implemented if ... then (no else, yet!)
This commit is contained in:
parent
f25131f77c
commit
28748660b3
118
f.sh
118
f.sh
|
@ -1,118 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
alias :=_newword
|
|
||||||
alias ']=_execbody'
|
|
||||||
alias xshift='shift 2>/dev/null || printf "Stack underflow\n"'
|
|
||||||
|
|
||||||
_stack="" # top is
|
|
||||||
_builtin_dictionary="swap dup rot over drop add sub div mod mul put" # + - / * .
|
|
||||||
|
|
||||||
_newword() {
|
|
||||||
name="$1"
|
|
||||||
shift
|
|
||||||
eval "${name}_definition=\"$*\""
|
|
||||||
}
|
|
||||||
|
|
||||||
_execword() {
|
|
||||||
eval "def=\"\$$1_definition\""
|
|
||||||
eval "def=\"\$$1_definition\""
|
|
||||||
[ "$def" ] || {
|
|
||||||
printf '%s\n' "Error: no word $1"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_execbody $def
|
|
||||||
}
|
|
||||||
|
|
||||||
_execbody() {
|
|
||||||
for word in "$@"; do
|
|
||||||
[ "$_debug" ] && {
|
|
||||||
printf 'word %s\nstack %s\n' "$word" "$_stack"
|
|
||||||
read
|
|
||||||
}
|
|
||||||
case "$_builtin_dictionary" in
|
|
||||||
*"$word"*) "_$word" $_stack ;;
|
|
||||||
*) case "$word" in
|
|
||||||
*[0-9]*) _stack="$word $_stack" ;;
|
|
||||||
*) _execword "$word" ;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
_swap() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
_stack="$2 $1 $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_dup() {
|
|
||||||
_stack="$1 $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_rot() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
thr="$3"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$3 $1 $2 $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_over() {
|
|
||||||
_stack="$2 $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_drop() {
|
|
||||||
xshift
|
|
||||||
_stack="$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_add() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$(( one + two )) $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_sub() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$(( two - one )) $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_div() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$(( two / one )) $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_mod() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$(( two % one )) $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_mul() {
|
|
||||||
one="$1"
|
|
||||||
two="$2"
|
|
||||||
xshift
|
|
||||||
xshift
|
|
||||||
_stack="$(( one * two )) $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
_put() {
|
|
||||||
one="$1"
|
|
||||||
xshift
|
|
||||||
printf '%s \n' "$one"
|
|
||||||
_stack="$*"
|
|
||||||
}
|
|
232
for.sh
Executable file
232
for.sh
Executable file
|
@ -0,0 +1,232 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Weird shell stack based forth "lookalike"
|
||||||
|
# recursion can be done by repeating the
|
||||||
|
# word. Words cannot have multiple defs
|
||||||
|
# in a dictionary.
|
||||||
|
# todo:
|
||||||
|
# implement conditionals in _execword :^)
|
||||||
|
|
||||||
|
ignore() :
|
||||||
|
alias :=_newword
|
||||||
|
alias ']=_execbody'
|
||||||
|
|
||||||
|
_stack="" # top is
|
||||||
|
_builtin_dictionary="swap dup rot over drop add sub div mod mul put not or and xor eq lt gt ne" # + - / * .
|
||||||
|
|
||||||
|
_newword() {
|
||||||
|
name="$1"
|
||||||
|
shift
|
||||||
|
[ "$_debug" ] && {
|
||||||
|
printf '_newword %s: %s\n' "$name" "$*"
|
||||||
|
read
|
||||||
|
}
|
||||||
|
eval "${name}_definition=\"$*\""
|
||||||
|
}
|
||||||
|
|
||||||
|
_execword() {
|
||||||
|
[ "$_debug" ] && {
|
||||||
|
printf '_execword %s\n' "$1"
|
||||||
|
read
|
||||||
|
}
|
||||||
|
eval "def=\"\$$1_definition\""
|
||||||
|
[ "$def" ] || {
|
||||||
|
printf '%s\n' "Error: no word $1"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_execbody $def
|
||||||
|
}
|
||||||
|
|
||||||
|
_execbody() {
|
||||||
|
while [ "$1" ]; do
|
||||||
|
word="$1"
|
||||||
|
|
||||||
|
[ "$_debug" ] && {
|
||||||
|
printf 'word %s\nstack %s\n' "$word" "$_stack"
|
||||||
|
read
|
||||||
|
}
|
||||||
|
case "$_builtin_dictionary" in
|
||||||
|
*"$word"*) "_$word" $_stack ;;
|
||||||
|
*) case "$word" in
|
||||||
|
then) ignore ;;
|
||||||
|
if)
|
||||||
|
[ "${_stack%% *}" = 0 ] && {
|
||||||
|
[ "$_debug" ] && {
|
||||||
|
printf 'failed if, jumping ahead\n'
|
||||||
|
read
|
||||||
|
}
|
||||||
|
_ifcnt=1
|
||||||
|
_thencnt=0
|
||||||
|
while [ "$_ifcnt" != "$_thencnt" ]; do
|
||||||
|
[ "$_debug" ] && {
|
||||||
|
printf '$1 %s\n' "$1"
|
||||||
|
printf '$* %s\n' "$*"
|
||||||
|
printf 'ifcnt: %s thencnt: %s\n' "$_ifcnt" "$_thencnt"
|
||||||
|
read
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
case "$1" in
|
||||||
|
if) ignore $(( _ifcnt += 1 )) ;;
|
||||||
|
then) ignore $(( _thencnt += 1 )) ;;
|
||||||
|
"") printf 'Unmatched if\n'; return ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
_drop $_stack
|
||||||
|
shift
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
*[0-9]*) _stack="$word $_stack" ;;
|
||||||
|
*) _execword "$word" ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$two $one $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dup() {
|
||||||
|
_stack="$1 $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_rot() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
thr="$3"
|
||||||
|
shift 3
|
||||||
|
_stack="$thr $one $two $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_over() {
|
||||||
|
_stack="$2 $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_drop() {
|
||||||
|
shift
|
||||||
|
_stack="$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_add() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( one + two )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_sub() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( two - one )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_div() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( two / one )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_mod() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( two % one )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_mul() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( one * two )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_put() {
|
||||||
|
one="$1"
|
||||||
|
shift
|
||||||
|
printf '%s \n' "$one"
|
||||||
|
_stack="$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_not() {
|
||||||
|
one="$1"
|
||||||
|
shift
|
||||||
|
_stack="$(( ~ one )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_or() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( one | two )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_and() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( one & two )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_xor() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
_stack="$(( one ^ two )) $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
_eq() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
if [ "$one" -eq "$two" ]; then
|
||||||
|
_stack="$(( ~ 0 )) $*"
|
||||||
|
else
|
||||||
|
_stack="$(( 0 )) $*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_lt() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
if [ "$two" -lt "$one" ]; then
|
||||||
|
_stack="$(( ~ 0 )) $*"
|
||||||
|
else
|
||||||
|
_stack="$(( 0 )) $*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_gt() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
if [ "$two" -gt "$one" ]; then
|
||||||
|
_stack="$(( ~ 0 )) $*"
|
||||||
|
else
|
||||||
|
_stack="$(( 0 )) $*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_ne() {
|
||||||
|
one="$1"
|
||||||
|
two="$2"
|
||||||
|
shift 2
|
||||||
|
if [ "$two" -ne "$one" ]; then
|
||||||
|
_stack="$(( ~ 0 )) $*"
|
||||||
|
else
|
||||||
|
_stack="$(( 0 )) $*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# definitions in forsh
|
||||||
|
: true not false ;
|
||||||
|
: false 0 ;
|
Loading…
Reference in New Issue
Block a user