84 lines
2.6 KiB
Bash
Executable File
84 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
stack_init_name_unit() {
|
|
eval "stacklast_${1}="
|
|
}
|
|
|
|
stack_push_name_hex_unit() {
|
|
# args: $1 must be an [a-z]+ name
|
|
# $2 must be a hexadecimal string
|
|
# input: stacklast_$1
|
|
# output: stacklast_$1 stack_$1_${!stacklast_$1}
|
|
# clobbers: stacklast
|
|
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
|
|
eval stacklast='${'stacklast_${1}'}'
|
|
stacklast=$((${stacklast}+1))
|
|
echo stack_${1}_${stacklast}='"'${2}'"'
|
|
eval stack_${1}_${stacklast}='"'${2}'"'
|
|
eval stacklast_${1}=${stacklast}
|
|
}
|
|
|
|
stack_len_name_int() {
|
|
# args: $1 must be an [a-z]+ name
|
|
# input: stacklast_$1
|
|
# output: stdout=${!stacklast_$1}
|
|
# clobbers: nothing
|
|
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
|
|
eval 'printf %s ${'stacklast_${1}'}'
|
|
}
|
|
|
|
stack_pop_name_result_unit() {
|
|
# args: $1 must be an [a-z]+ name
|
|
# input: stacklast_$1
|
|
# output: stacklast_$1 stack_$1_${!stacklast_$1}
|
|
# clobbers: stacklast
|
|
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
|
|
eval stacklast='${'stacklast_${1}'}'
|
|
eval $2'="${'stack_${1}_${stacklast}'}"'
|
|
stacklast=$((${stacklast}-1))
|
|
eval stacklast_${1}=${stacklast}
|
|
}
|
|
|
|
stack_peek_name_hex() {
|
|
# args: $1 must be an [a-z]+ name
|
|
# input: stacklast_$1 stack_$1_${!stacklast_$1}
|
|
# output: stdout
|
|
# clobbers: stacklast
|
|
# warning: does no attempt to escape ", \, $, space and so on in any of the inputs or outputs.
|
|
eval stacklast='${'stacklast_${1}'}'
|
|
eval 'printf %s "${'stack_${1}_${stacklast}'}"'
|
|
}
|
|
|
|
stack_init_name_unit parse_stack
|
|
stack_push_name_hex_unit parse ''
|
|
|
|
printf '(+ 1 ( + 22 345 ))' | \
|
|
od -v -A n -t x1 | sed -e 's/^ //' | tr ' ' \\n | (while read c; do
|
|
case "$c" in
|
|
# Open paren
|
|
28) if test "x$(stack_peek_name_hex parse)" = 'x'; then
|
|
stack_pop_name_result_unit parse current
|
|
fi
|
|
stack_push_name_hex_unit parse 28
|
|
stack_push_name_hex_unit parse '';;
|
|
# Close paren
|
|
29) if test "x$(stack_peek_name_hex parse)" = 'x'; then
|
|
stack_pop_name_result_unit parse current
|
|
fi
|
|
stack_push_name_hex_unit parse 29;;
|
|
# Space
|
|
20) if test "x$(stack_peek_name_hex parse)" != 'x'; then
|
|
stack_push_name_hex_unit parse ''
|
|
fi;;
|
|
# identifier character
|
|
*) stack_pop_name_result_unit parse current
|
|
stack_push_name_hex_unit parse "$current$c";;
|
|
esac
|
|
done
|
|
|
|
while test "x$(stack_len_name_int parse)" != 'x0'; do
|
|
stack_pop_name_result_unit parse tmp
|
|
echo "$tmp 0a"
|
|
done | tac | xxd -ps -r
|
|
)
|