# Shell command language code generator # # Copyright (C) 2016 Patrick "P. J." McDermott # # This file is part of the Eggshell Compiler. # # The Eggshell Compiler is free software: you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # # The Eggshell Compiler is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with the Eggshell Compiler. If not, see # . sc= sgetc() { sc="$(dd bs=1 count=1 2>/dev/null; printf '.')" sc="${sc%.}" } codegen_sub() { local array="${1}" shift 1 IFS="${RS}" for t in ${array}; do toktext "${t}" case "${t%${US}*}" in T_NEWLINE|T_LPAREN) # Indenting lines can mess up here-documents. # Adding a space after "(" can mess up function # definitions (on zsh at least, while other # shells accept the space). ;; *) printf ' ' ;; esac done unset IFS } # The token stack is encoded in a string in the following grammar: # Terminal symbols: # TOKEN # Production rules: # stack = tokens [ '' type '' stack '' [ tokens ] ] ; # tokens = TOKEN { '' TOKEN } ; # type = 'C' ; # 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() { local array= array='' while :; do sgetc case "${sc}" in '') # EOF break ;; "${SOH}") # New stack element sgetc case "${sc}" in 'C') # Command substitution sgetc # STX array="${array}$(\ sh_parse_stack)." array="${array%.}" ;; esac ;; "${ETX}") # End of stack element break ;; *) # Token character array="${array}${sc}" ;; esac done codegen_sub "${array}" }