declare -a bos_sugar_block_stack
function bos-sugar/push() {
bos_sugar_block_stack+=( 0 )
}
function bos-sugar/block-and-pop() {
local on_open="$1"; shift
local on_close="$1"; shift
if [[ "${bos_sugar_block_stack[-1]}" == 0 ]]; then
bos_sugar_block_stack[-1]=1
"$on_open" "$@" && return 0
else
unset "bos_sugar_block_toggle[-1]"
"$on_close" "$@" && return 1
fi
}
function bos-sugar/declare-block() {
local block_name="$1"
local open_func="$2"
local close_func="$3"
shopt -s expand_aliases
eval "alias $1='bos-sugar/push; while bos-sugar/block-and-pop $open_func $close_func'"
}
function bos-sugar/set-metaclass-for() {
local class="$1"
local metaclass_ref; bos-namespaces/store-scalar-for-into metaclass_ref meta "$class"
local -n metaclass_object="$metaclass_ref"
metaclass_object='bos-dispatch/invoke bos/mop/inheritance 0'
}
function bos-sugar/class-open() {
if [[ "${#*}" -ne 1 ]]; then
>&2 echo "'class \$class_name; do …; done', not 'class $*'"
return 1
fi
local class="$1"
bos-namespaces/push "$class"
local fq_class; bos-namespaces/current-namespace-into fq_class
bos-sugar/set-metaclass-for "$fq_class"
function extends() {
local fq_class; bos-namespaces/current-namespace-into fq_class
local metaclass_ref; bos-namespaces/store-scalar-for-into metaclass_ref meta "$fq_class"
local -n metaclass_object="$metaclass_ref"
$metaclass_object set-superclasses-for "$fq_class" "$@"
}
eval "function $fq_class { bos-dispatch/invoke \"$fq_class\" 0 \"\$@\"; }"
bos-namespaces/save-funcs
# this will get renamed into the class
function new-into() {
local class _; bos-object/unpack-self-into class _ "$self"
local -n new_into_result="$1"; shift
local metaclass_ref; bos-namespaces/store-scalar-for-into metaclass_ref meta "$class"
local -n metaclass_object="$metaclass_ref"
local new_object
$metaclass_object create-object-into new_object "$class"
new_into_result="$new_object"
}
return 0
}
function bos-sugar/class-close() {
local class="$1";
local fq_class; bos-namespaces/current-namespace-into fq_class
local metaclass_ref; bos-namespaces/store-scalar-for-into metaclass_ref meta "$fq_class"
local -n metaclass_object="$metaclass_ref"
local -a methods_list; bos-namespaces/list-new-funcs-into methods_list
bos-namespaces/qualify-funcs "${methods_list[@]}"
$metaclass_object make-mro-for "$fq_class"
bos-namespaces/pop
return 0
}
bos-sugar/declare-block class bos-sugar/class-open bos-sugar/class-close
function bos-sugar/namespace-open() {
if [[ "${#*}" -ne 1 ]]; then
>&2 echo "'namespace \$namespace_name; do …; done', not 'namespace $*'"
return 1
fi
bos-namespaces/push "$1"
bos-namespaces/save-funcs
return 0
}
function bos-sugar/namespace-close() {
local -a methods_list; bos-namespaces/list-new-funcs-into methods_list
bos-namespaces/qualify-funcs "${methods_list[@]}"
bos-namespaces/pop
return 0
}
bos-sugar/declare-block namespace bos-sugar/namespace-open bos-sugar/namespace-close