From 23c04846378d7861a1afa6edeaa94f6d151bbb53 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Tue, 23 Feb 2016 14:00:21 -0500 Subject: 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 --- 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 -- cgit v0.9.1