Simple lexer for micro-scheme
This commit is contained in:
parent
a51a05f606
commit
5f1a136992
83
micro-scheme/micro-scheme.sh
Executable file
83
micro-scheme/micro-scheme.sh
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/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
|
||||
)
|
Loading…
Reference in New Issue
Block a user