summaryrefslogtreecommitdiffstats
path: root/research/research3.sh
diff options
context:
space:
mode:
Diffstat (limited to 'research/research3.sh')
-rw-r--r--research/research3.sh157
1 files changed, 157 insertions, 0 deletions
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 "${@}"