diff options
Diffstat (limited to 'eshtrans')
-rw-r--r-- | eshtrans/backend/codegen.esh | 43 | ||||
-rw-r--r-- | eshtrans/backend/main.esh | 2 |
2 files changed, 38 insertions, 7 deletions
diff --git a/eshtrans/backend/codegen.esh b/eshtrans/backend/codegen.esh index 42b714a..9e95956 100644 --- a/eshtrans/backend/codegen.esh +++ b/eshtrans/backend/codegen.esh @@ -18,14 +18,20 @@ # along with the Eggshell Compiler. If not, see # <http://www.gnu.org/licenses/>. +sbufi= +sbufc= sc= tu_id= static_fn_n= sgetc() { - sc="$(dd bs=1 count=1 2>/dev/null; printf '.')" - sc="${sc%.}" + if [ ${sbufi} -ge ${sbufc} ]; then + sc='' + else + eval "sc=\${sbufv_${sbufi}}" + sbufi=$((${sbufi} + 1)) + fi } add_static_fn() @@ -160,9 +166,10 @@ codegen_sub() # We need to recurse through this stack to get to all the tokens. # Each element in the stack (an array of tokens) gets run through the codegen to # become text that is inserted into the array below. -sh_parse_stack() +parse_stack() { local array= + local res= array='' while :; do @@ -179,9 +186,9 @@ sh_parse_stack() 'C') # Command substitution sgetc # STX - array="${array}$(\ - sh_parse_stack)." - array="${array%.}" + res="$(parse_stack)" + sbufi="${res%% *}" + array="${array}${res#* }" ;; esac ;; @@ -195,9 +202,33 @@ sh_parse_stack() ;; esac done + printf '%d ' ${sbufi} codegen_sub "${array}" } +sh_parse_stack() +{ + local buf="${1}" + shift 1 + local res= + + eval "$(printf '%s' "${buf}" | awk -v FS='' -v j=0 \ + -v squote="'" -v esc_squote="'\\\\''" ' + { + for (i = 1; i <= NF; ++i) { + sub(squote, esc_squote, $i); + printf("sbufv_%d='\''%s'\''\n", j++, $i); + }; + printf("sbufv_%d='\''\n'\''\n", j++); + } + ')" + sbufi=0 + sbufc=${#buf} + res="$(parse_stack; printf '.')" + res="${res%.}" + printf '%s' "${res#* }" +} + sh_set_tu_id() { local toks="${1}" diff --git a/eshtrans/backend/main.esh b/eshtrans/backend/main.esh index 60bc622..12aeff7 100644 --- a/eshtrans/backend/main.esh +++ b/eshtrans/backend/main.esh @@ -25,7 +25,7 @@ sh_codegen() sh_set_tu_id "${toks}" sh_start_tu - if ! printf '%s' "${toks}" | sh_parse_stack; then + if ! sh_parse_stack "${toks}"; then return 1 fi sh_end_tu |