# 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
local ionum=
ionum=false
IFS="${RS}"
for t in ${array}; do
if ${ionum}; then
case "${t%${US}*}" in
T_WORD|T_CMDNAME|T_FNAME)
printf ' '
;;
esac
ionum=false
fi
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).
;;
T_IO_NUMBER)
ionum=true
;;
*)
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}"
}