summaryrefslogtreecommitdiffstats
path: root/eshtrans
diff options
context:
space:
mode:
Diffstat (limited to 'eshtrans')
-rw-r--r--eshtrans/Makefile6
-rw-r--r--eshtrans/eshrt/eshrtbegin.esh250
-rw-r--r--eshtrans/eshrt/eshrtend.esh27
3 files changed, 281 insertions, 2 deletions
diff --git a/eshtrans/Makefile b/eshtrans/Makefile
index c924c92..2d3d626 100644
--- a/eshtrans/Makefile
+++ b/eshtrans/Makefile
@@ -15,6 +15,8 @@ WITH_PROF = n
PROF_y = ../libeshprof/hooks.esh
PROF = $(PROF_$(WITH_PROF))
+ESHRT = eshrt/eshrtbegin.sh2 eshrt/eshrtend.sh2
+
bootstrap: stage3
stage1:
@printf 'Stage 1:\n'
@@ -41,9 +43,9 @@ eshtrans.stage1: $(OBJECTS1)
cat $(OBJECTS1) >$@
printf 'main "$${@}"\n' >>$@
chmod a+x $@
-eshtrans.stage2: eshtrans.stage1 $(OBJECTS2) $(PROF)
+eshtrans.stage2: eshtrans.stage1 $(OBJECTS2) $(PROF) $(ESHRT)
../eshld/eshld -o $@ $(OBJECTS2) $(PROF)
-eshtrans.stage3: eshtrans.stage2 $(OBJECTS3) $(PROF)
+eshtrans.stage3: eshtrans.stage2 $(OBJECTS3) $(PROF) $(ESHRT)
../eshld/eshld -o $@ $(OBJECTS3) $(PROF)
$(OBJECTS1) $(OBJECTS2) $(OBJECTS3):
diff --git a/eshtrans/eshrt/eshrtbegin.esh b/eshtrans/eshrt/eshrtbegin.esh
new file mode 100644
index 0000000..9f7e59e
--- /dev/null
+++ b/eshtrans/eshrt/eshrtbegin.esh
@@ -0,0 +1,250 @@
+# Eggshell runtime library
+#
+# 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
+# <http://www.gnu.org/licenses/>.
+
+use nostack
+
+__ESC="$(printf '\033.')"; __ESC="${__ESC%.}"
+ __RS="$(printf '\036.')"; __RS="${__RS%.}"
+ __US="$(printf '\037.')"; __US="${__US%.}"
+__sp=0
+__fn_name=''
+__fn_tu=''
+__fn_vars=''
+__fn_var_vals=''
+__fn=''
+__prev_tu=''
+__prev_vars=''
+__var=''
+__val=''
+__fn_frame=0
+__fn_begin_hooks=''
+__fn_end_hooks=''
+__init_funcs=''
+
+__sp_inc()
+{
+ __sp=$((${__sp} + 1))
+}
+
+__sp_dec()
+{
+ __sp=$((${__sp} - 1))
+}
+
+__frame_set()
+{
+ eval "__frame_${__sp}_name=\${__fn_name}"
+ eval "__frame_${__sp}_tu=\${__fn_tu}"
+ eval "__frame_${__sp}_vars=\${__fn_vars}"
+ eval "__frame_${__sp}_var_vals=\${__fn_var_vals}"
+}
+
+__frame_get()
+{
+ eval "__fn_name=\${__frame_${__sp}_name}"
+ eval "__fn_tu=\${__frame_${__sp}_tu}"
+ eval "__fn_vars=\${__frame_${__sp}_vars}"
+ eval "__fn_var_vals=\${__frame_${__sp}_var_vals}"
+}
+
+__fn_ctxsw()
+{
+ unset IFS
+ case "${__prev_tu}" in
+ ${__fn_tu});;
+ ?*)
+ # Unset static variables and functions from previous TU.
+ eval "__val=\${__${__prev_tu}_static_vars}"
+ case "${__val}" in ?*)
+ eval "unset \${__${__prev_tu}_static_vars}"
+ ;; esac
+ eval "__val=\${__${__prev_tu}_static_fns}"
+ for __fn in ${__val}; do
+ unset -f "${__fn%:*}"
+ done
+ ;; esac
+ case "${__fn_tu}" in
+ ${__prev_tu});;
+ ?*)
+ # Set static variables and function for the current TU.
+ eval "__val=\${__${__fn_tu}_static_var_vals}"
+ eval "${__val}"
+ eval "__val=\${__${__fn_tu}_static_fns}"
+ for __fn in ${__val}; do
+ eval "${__fn%:*}() { ${__fn#*:}; }"
+ done
+ ;; esac
+ case "${__prev_vars}" in ?*)
+ unset ${__prev_vars}
+ ;; esac
+ eval "${__fn_var_vals}"
+}
+
+__fn_update_vars()
+{
+ unset IFS
+ for __var in ${__fn_vars}; do
+ __val="$(eval "printf '%s' \"\${${__var}}\"" | \
+ sed "s|'|'\\\\''|g;")"
+ __fn_var_vals="${__fn_var_vals} ${__var}='${__val}'"
+ done
+}
+
+__fn_start()
+{
+ # Hooks.
+ unset IFS
+ for __fn in ${__fn_begin_hooks}; do
+ ${__fn} ${2}
+ done
+
+ # Old state.
+ __prev_tu="${__fn_tu}"
+ __prev_vars="${__fn_vars}"
+
+ # Update local vars in stack.
+ __fn_update_vars
+ __frame_set
+
+ # Set stack pointer.
+ __sp_inc
+
+ # New state.
+ __fn_name="${2}"
+ __fn_tu="${1}"
+ __fn_vars=
+ __fn_var_vals=
+ __frame_set
+
+ # Switch.
+ __fn_ctxsw
+}
+
+__fn_end()
+{
+ # Hooks.
+ unset IFS
+ for __fn in ${__fn_end_hooks}; do
+ ${__fn} ${__fn_name}
+ done
+
+ # Old state.
+ __prev_tu="${__fn_tu}"
+ __prev_vars="${__fn_vars}"
+
+ # Set stack pointer.
+ __sp_dec
+
+ # New state.
+ __frame_get
+
+ # Switch.
+ __fn_ctxsw
+}
+
+__tu_end()
+{
+ # Save TU static vars.
+ unset IFS
+ for __var in $(eval "printf '%s' \"\${__${__tu}_static_vars}\""); do
+ __val="$(eval "printf '%s' \"\${${__var}}\"" | \
+ sed "s|'|'\\\\''|g")"
+ eval "__${__tu}_static_var_vals=\"\${__${__tu}_static_var_vals}\
+ ${__var}='\${__val}'\""
+ unset ${__var}
+ done
+
+ __tu=''
+}
+
+__stack_trace()
+{
+ __fn_frame=0
+ while [ ${__fn_frame} -le ${__sp} ]; do
+ eval "printf '%s\n' \"\${__frame_${__fn_frame}_name}\""
+ __fn_frame=$((${__fn_frame} + 1))
+ done
+}
+
+__local()
+{
+ unset IFS
+ for __var in "${@}"; do
+ case "${__var}" in
+ *=*)
+ __val="${__var#*=}"
+ __var="${__var%%=*}"
+ ;;
+ *)
+ __val=''
+ ;;
+ esac
+ case "${__var}" in [!A-Za-z_]* | *[!0-9A-Za-z_]*)
+ printf 'Syntax error: %s %s\n' \
+ 'illegal static variable name:' "${__var}" >&2
+ exit 1
+ ;; esac
+ eval "${__var}=\${__val}"
+ __fn_vars="${__fn_vars} ${__var}"
+ done
+}
+
+__static()
+{
+ case "${__tu}" in '')
+ printf 'Error: Cannot declare static variables in functions' >&2
+ exit 1
+ ;; esac
+ unset IFS
+ for __var in "${@}"; do
+ case "${__var}" in
+ *=*)
+ __val="${__var#*=}"
+ __var="${__var%%=*}"
+ ;;
+ *)
+ __val=''
+ ;;
+ esac
+ case "${__var}" in [!A-Za-z_]* | *[!0-9A-Za-z_]*)
+ printf 'Syntax error: %s %s\n' \
+ 'illegal static variable name:' "${__var}" >&2
+ exit 1
+ ;; esac
+ eval "${__var}=\${__val}"
+ eval "__${__tu}_static_vars=\"\${__${__tu}_static_vars} \
+ ${__var}\""
+ done
+}
+
+__fn_begin_hook()
+{
+ __fn_begin_hooks="${__fn_begin_hooks} ${1}"
+}
+
+__fn_end_hook()
+{
+ __fn_end_hooks="${__fn_end_hooks} ${1}"
+}
+
+__init()
+{
+ __init_funcs="${__init_funcs} ${1}"
+}
diff --git a/eshtrans/eshrt/eshrtend.esh b/eshtrans/eshrt/eshrtend.esh
new file mode 100644
index 0000000..34cb7e1
--- /dev/null
+++ b/eshtrans/eshrt/eshrtend.esh
@@ -0,0 +1,27 @@
+# Eggshell runtime library
+#
+# 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
+# <http://www.gnu.org/licenses/>.
+
+use nostack
+
+unset IFS
+for __func in ${__init_funcs}; do
+ ${__func}
+done
+${__entry} "${@}"