summaryrefslogtreecommitdiffstats
path: root/research
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2016-02-23 14:00:21 (EST)
committer P. J. McDermott <pj@pehjota.net>2016-02-23 14:00:21 (EST)
commit23c04846378d7861a1afa6edeaa94f6d151bbb53 (patch)
tree099c67cb2061a7e08642532ccff892af9cac1b1c /research
parentad07bf77f733d8d4c823c63fc2c423f57d063258 (diff)
downloadeggshell-23c04846378d7861a1afa6edeaa94f6d151bbb53.zip
eggshell-23c04846378d7861a1afa6edeaa94f6d151bbb53.tar.gz
eggshell-23c04846378d7861a1afa6edeaa94f6d151bbb53.tar.bz2
Old runtime library research scripts: Now you see them...
Modification dates: research1.sh: 2016-02-13 14:44:30 -0500 research2.sh: 2016-02-13 19:25:25 -0500 research3.sh: 2016-02-14 17:56:33 -0500 research4.sh: 2016-02-23 01:26:54 -0500
Diffstat (limited to 'research')
-rw-r--r--research/research1.sh36
-rw-r--r--research/research2.sh111
-rw-r--r--research/research3.sh157
-rw-r--r--research/research4.sh323
4 files changed, 627 insertions, 0 deletions
diff --git a/research/research1.sh b/research/research1.sh
new file mode 100644
index 0000000..748bb31
--- /dev/null
+++ b/research/research1.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+tu0(){
+
+local local_var='local_var'
+global_var='global_var'
+
+foo()
+{
+ printf 'foo()\n'
+ printf 'local_var: %s\n' "${local_var}"
+ printf 'global_var: %s\n' "${global_var}"
+}
+
+}
+tu0
+
+tu1(){
+
+bar()
+{
+ printf 'bar()\n'
+ printf 'local_var: %s\n' "${local_var}"
+ printf 'global_var: %s\n' "${global_var}"
+}
+
+}
+tu1
+
+main()
+{
+ foo
+ bar
+}
+
+main "${@}"
diff --git a/research/research2.sh b/research/research2.sh
new file mode 100644
index 0000000..9908495
--- /dev/null
+++ b/research/research2.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+################################################################################
+# shld
+################################################################################
+__last_tu=''
+
+static()
+{
+ local arg=
+ local var=
+ local val=
+ local exp=
+
+ for arg in "${@}"; do
+ case "${arg}" in
+ *=*)
+ var="${arg%%=*}"
+ val="$(printf "${arg#*=}" | \
+ sed "s|'|'\\\\''|g")"
+ ;;
+ *)
+ var="${arg}"
+ val=''
+ ;;
+ esac
+ # Sanitize variable name.
+ case "${var}" in
+ [!A-Za-z_]* | *[!0-9A-Za-z_]*)
+ printf 'Syntax error: %s %s\n' \
+ 'illegal static variable name:' \
+ "${var}" >&2
+ ;;
+ esac
+ # Set up static variable assignments to be evaluated on scope
+ # change.
+ exp="__${__tu}_static_var_vals="
+ exp="${exp}\"\${__${__tu}_static_var_vals} ${var}='${val}'\""
+ eval "${exp}"
+ # Set up list of static variables to be cleaned up on scope
+ # change.
+ exp="__${__tu}_static_vars=\"\${__${__tu}_static_vars} ${var}\""
+ eval "${exp}"
+ # Set up static variables for current scope.
+ eval "${var}='${val}'"
+ done
+
+ # Clean up static variables from previous scope.
+ if ! [ "x${__last_tu}" = 'x' ]; then
+ eval "unset \${__${__last_tu}_static_vars}"
+ fi
+ __last_tu="${__tu}"
+}
+
+__set_up_static_vars()
+{
+ local tu="${1}"
+
+ # Clean up static variables from previous scope.
+ if ! [ "x${__last_tu}" = 'x' ]; then
+ eval "unset \${__${__last_tu}_static_vars}"
+ fi
+ __last_tu="${tu}"
+
+ # Set up static variables for specified scope.
+ eval "$(eval printf '%s' "\"$(eval printf '%s' \
+ "'\${__${tu}_static_var_vals}'")\"")"
+}
+
+################################################################################
+# TU 0
+################################################################################
+__tu='tu0'
+__tu0_locals=''
+
+static static_var0='tu0 static_var0'
+
+tu0_fn0()
+{ __set_up_static_vars 'tu0'
+ echo "tu0"
+ echo "\tstatic_var0: $static_var0"
+ echo "\tstatic_var1: $static_var1"
+}
+
+################################################################################
+# TU 1
+################################################################################
+__tu='tu1'
+__tu1_locals=''
+
+static static_var0='tu1 static_var0'
+static static_var1='tu1 static_var1'
+
+tu1_fn0()
+{ __set_up_static_vars 'tu1'
+ echo "tu1"
+ echo "\tstatic_var0: $static_var0"
+ echo "\tstatic_var1: $static_var1"
+}
+
+################################################################################
+# TU 2
+################################################################################
+main()
+{
+ tu0_fn0
+ tu1_fn0
+ tu0_fn0
+}
+
+main "${@}"
diff --git a/research/research3.sh b/research/research3.sh
new file mode 100644
index 0000000..ad994fa
--- /dev/null
+++ b/research/research3.sh
@@ -0,0 +1,157 @@
+#!/bin/sh
+
+################################################################################
+# shld
+################################################################################
+__last_tu=''
+
+static()
+{
+ local arg=
+ local var=
+ local val=
+ local exp=
+
+ for arg in "${@}"; do
+ case "${arg}" in
+ *=*)
+ var="${arg%%=*}"
+ val="$(printf "${arg#*=}" | \
+ sed "s|'|'\\\\''|g")"
+ ;;
+ *)
+ var="${arg}"
+ val=''
+ ;;
+ esac
+ # Sanitize variable name.
+ case "${var}" in
+ [!A-Za-z_]* | *[!0-9A-Za-z_]*)
+ printf 'Syntax error: %s %s\n' \
+ 'illegal static variable name:' \
+ "${var}" >&2
+ ;;
+ esac
+ # Set up static variable assignments to be evaluated on scope
+ # change.
+ exp="__${__tu}_static_var_vals="
+ exp="${exp}\"\${__${__tu}_static_var_vals} ${var}='${val}'\""
+ eval "${exp}"
+ # Set up list of static variables to be cleaned up on scope
+ # change.
+ exp="__${__tu}_static_vars=\"\${__${__tu}_static_vars} ${var}\""
+ eval "${exp}"
+ # Set up static variables for current scope.
+ eval "${var}='${val}'"
+ done
+
+ # Clean up static variables from previous scope.
+ if ! [ "x${__last_tu}" = 'x' ]; then
+ eval "unset \${__${__last_tu}_static_vars}"
+ fi
+ __last_tu="${__tu}"
+}
+
+__set_up_static_vars()
+{
+ local tu="${1}"
+
+ # Clean up static variables and functions from previous scope.
+ if ! [ "x${__last_tu}" = 'x' ]; then
+ eval "unset \${__${__last_tu}_static_vars}"
+ for fn in $(eval printf '%s' \
+ "\"\${__${__last_tu}_static_fns}\""); do
+ unset -f "${fn%:*}"
+ done
+ fi
+ __last_tu="${tu}"
+
+ # Set up static variables and functions for specified scope.
+ eval "$(eval printf '%s' "\"$(eval printf '%s' \
+ "'\${__${tu}_static_var_vals}'")\"")"
+ for fn in $(eval printf '%s' "\"\${__${tu}_static_fns}\""); do
+ eval "${fn%:*}() { ${fn#*:}; }"
+ done
+}
+
+################################################################################
+# TU 0
+################################################################################
+__tu='tu0'
+__tu0_static_vars=''
+__tu0_static_fns=''
+
+entry0()
+{ __set_up_static_vars 'tu0'
+ echo "tu0 entry0()"
+ foo
+}
+
+call0()
+{
+ ${1}
+}
+
+# shpp will convert:
+# static foo()
+# into:
+__tu0_static_fns="${__tu0_static_fns} foo:__tu0_fn0"
+static foo=__tu0_fn0
+__tu0_fn0()
+{ __set_up_static_vars 'tu0'
+ echo "tu0 foo()"
+ bar
+}
+
+# bar()
+__tu0_static_fns="${__tu0_static_fns} bar:__tu0_fn1"
+static bar=__tu0_fn1
+__tu0_fn1()
+{ __set_up_static_vars 'tu0'
+ echo "tu0 bar()"
+}
+
+################################################################################
+# TU 1
+################################################################################
+__tu='tu1'
+__tu1_static_vars=''
+__tu1_static_fns=''
+
+entry1()
+{ __set_up_static_vars 'tu1'
+ echo "tu1 entry1()"
+ foo
+}
+
+# foo()
+__tu1_static_fns="${__tu1_static_fns} foo:__tu1_fn0"
+static foo=__tu1_fn0
+__tu1_fn0()
+{ __set_up_static_vars 'tu1'
+ echo "tu1 foo()"
+ call0 ${baz}
+}
+
+# baz()
+__tu1_static_fns="${__tu1_static_fns} baz:__tu1_fn1"
+static baz=__tu1_fn1
+__tu1_fn1()
+{ __set_up_static_vars 'tu1'
+ echo "tu1 baz()"
+}
+
+################################################################################
+# TU 2
+################################################################################
+__tu='tu2'
+__tu2_static_vars=''
+__tu2_static_fns=''
+
+main()
+{ __set_up_static_vars 'tu2'
+ entry0
+ entry1
+}
+
+main "${@}"
diff --git a/research/research4.sh b/research/research4.sh
new file mode 100644
index 0000000..9ef3bf0
--- /dev/null
+++ b/research/research4.sh
@@ -0,0 +1,323 @@
+set -eu
+__ESC="$(printf '\033.')"; __ESC="${__ESC%.}"
+ __RS="$(printf '\036.')"; __RS="${__RS%.}"
+ __US="$(printf '\037.')"; __US="${__US%.}"
+__fn_stack=
+__fn_frame=
+__fn_name=
+__fn_tu=
+__fn_vars=
+__fn_var_vals=
+__fn=
+__prev_tu=
+__prev_vars=
+__var=
+__val=
+
+__fn_stack_push()
+{
+ __fn_stack="${__fn_stack}${__RS}${__fn_frame}"
+}
+
+__fn_stack_peek()
+{
+ __fn_frame="${__fn_stack##*${__RS}}"
+}
+
+__fn_stack_pop()
+{
+ __fn_stack_peek
+ __fn_stack="${__fn_stack%${__RS}*}"
+}
+
+__fn_frame_encode()
+{
+ # RS and US in frame variable values must be encoded.
+ __fn_var_vals="$(printf '%s' "${__fn_var_vals}" | sed "
+ s|${__ESC}|${__ESC}0|g;
+ s|${__RS}|${__ESC}1|g; s|${__US}|${__ESC}2|g;
+ ")"
+ __fn_frame="${__fn_name}${__US}${__fn_tu}"
+ __fn_frame="${__fn_frame}${__US}${__fn_vars}${__US}${__fn_var_vals}"
+}
+
+__fn_frame_decode()
+{
+ __fn_name="${__fn_frame%%${__US}*}"
+ __fn_frame="${__fn_frame#*${__US}}"
+ __fn_tu="${__fn_frame%%${__US}*}"
+ __fn_frame="${__fn_frame#*${__US}}"
+ __fn_vars="${__fn_frame%%${__US}*}"
+ __fn_var_vals="${__fn_frame#*${__US}}"
+ __fn_var_vals="$(printf '%s' "${__fn_var_vals}" | sed "
+ s|${__ESC}0|${__ESC}|g;
+ s|${__ESC}1|${__RS}|g; s|${__ESC}2|${__US}|g;
+ ")"
+}
+
+__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_stack_pop
+ __fn_vars="${__prev_vars}"
+ __fn_update_vars
+ __fn_frame_encode
+ __fn_stack_push
+
+ # New state.
+ __fn_name="${2}"
+ __fn_tu="${1}"
+ __fn_vars=
+ __fn_var_vals=
+ __fn_frame_encode
+ __fn_stack_push
+
+ # Switch.
+ __fn_ctxsw
+}
+
+__fn_end()
+{
+ # Old state.
+ __fn_stack_pop
+ __fn_frame_decode
+ __prev_tu="${__fn_tu}"
+ __prev_vars="${__fn_vars}"
+
+ # New state.
+ __fn_stack_peek
+ __fn_frame_decode
+
+ # 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()
+{
+ IFS="${__RS}"
+ for __fn_frame in ${__fn_stack#${__RS}}; do
+ printf '%s\n' "${__fn_frame%%${__US}*}"
+ 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