#!/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 "${@}"