summaryrefslogtreecommitdiffstats
path: root/research
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2016-02-24 03:14:25 (EST)
committer P. J. McDermott <pj@pehjota.net>2016-02-24 03:15:39 (EST)
commit125adb4bcd29df7b74d5e5aa34c527c2f68826c6 (patch)
tree576973c9099e8508d00bd85db951ba12b0139778 /research
parent7add577ea68819fb7f64e16187d2543c1cf5518b (diff)
downloadeggshell-125adb4bcd29df7b74d5e5aa34c527c2f68826c6.zip
eggshell-125adb4bcd29df7b74d5e5aa34c527c2f68826c6.tar.gz
eggshell-125adb4bcd29df7b74d5e5aa34c527c2f68826c6.tar.bz2
research: New stack management test script
Diffstat (limited to 'research')
-rw-r--r--research/research5.sh308
1 files changed, 308 insertions, 0 deletions
diff --git a/research/research5.sh b/research/research5.sh
new file mode 100644
index 0000000..49d8548
--- /dev/null
+++ b/research/research5.sh
@@ -0,0 +1,308 @@
+set -e
+__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=
+
+__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 "unset \${__${__prev_tu}_static_vars}"
+ for __fn in $(eval printf '%s' \
+ "\"\${__${__prev_tu}_static_fns}\""); do
+ unset -f "${__fn%:*}"
+ done
+ ;; esac
+ case "${__fn_tu}" in
+ ${__prev_tu});;
+ ?*)
+ # Set static variables and function for the current TU.
+ eval "$(eval printf '%s' "\"$(eval printf '%s' \
+ "'\${__${__fn_tu}_static_var_vals}'")\"")"
+ for __fn in $(eval printf '%s' \
+ "\"\${__${__fn_tu}_static_fns}\""); do
+ eval "${__fn%:*}() { ${__fn#*:}; }"
+ done
+ ;; esac
+ unset ${__prev_vars}
+ eval "${__fn_var_vals}"
+}
+
+__fn_update_vars()
+{
+ 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()
+{
+ # 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()
+{
+ # 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.
+ 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()
+{
+ 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
+ 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
+}
+
+EOF(){ :; }
+
+#: <<'EOF'
+################################################################################
+# Stack trace test
+################################################################################
+__tu=tu0
+__tu0_static_vars=
+__tu0_static_var_vals=
+__tu0_static_fns=
+
+a(){ __fn_start tu0 a; b; __fn_end; }
+b(){ __fn_start tu0 b; c; __fn_end; }
+c(){ __fn_start tu0 c; printf 'Stack trace:\n';
+ printf ' * %s()\n' $(__stack_trace); __fn_end; }
+a
+
+__tu_end
+EOF
+
+#: <<'EOF'
+################################################################################
+# TU 0
+################################################################################
+__tu=tu0
+__tu0_static_vars=
+__tu0_static_var_vals=
+__tu0_static_fns=
+
+static v=1
+
+foo()
+{
+ __fn_start tu0 foo
+
+ echo "v (should be 1): $v"
+
+ __fn_end
+}
+
+__tu_end
+
+################################################################################
+# TU 1
+################################################################################
+__tu=tu1
+__tu1_static_vars=
+__tu1_static_var_vals=
+__tu1_static_fns=
+
+bar()
+{
+ __fn_start tu1 bar
+
+ echo "v (should not be 1): $v"
+ foo
+ echo "v (should not be 1): $v"
+
+ __fn_end
+}
+
+__tu_end
+
+bar
+EOF
+
+#: <<'EOF'
+################################################################################
+# TU 0
+################################################################################
+__tu=tu0
+__tu0_static_vars=
+__tu0_static_var_vals=
+__tu0_static_fns=
+
+a()
+{
+ __fn_start tu0 a
+ __local v=1
+ echo "v (should be 1): $v"
+ b
+ echo "v (should be 1): $v"
+ __fn_end
+}
+
+b()
+{
+ __fn_start tu0 b
+ echo "v (should be empty): $v"
+ __fn_end
+}
+
+__tu_end
+
+a
+EOF
+
+: <<'EOF'
+################################################################################
+# TU 0
+################################################################################
+__tu=tu0
+__tu0_static_vars=
+__tu0_static_var_vals=
+__tu0_static_fns=
+
+a()
+{
+ __fn_start tu0 a
+ static v=1
+ __fn_end
+}
+
+__tu_end
+
+a
+EOF