summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2023-07-22 14:07:56 +0100
committerdakkar <dakkar@thenautilus.net>2023-07-22 14:07:56 +0100
commit709cf92de411b7a57c7298f8d970901930c4ce0f (patch)
tree1c88dd977cc60698c8fc22d7eab0c80a2b294764
parent`*-into` always takes the destination as `$1` (diff)
downloadbash-object-system-709cf92de411b7a57c7298f8d970901930c4ce0f.tar.gz
bash-object-system-709cf92de411b7a57c7298f8d970901930c4ce0f.tar.bz2
bash-object-system-709cf92de411b7a57c7298f8d970901930c4ce0f.zip
fix block&namespace nesting
-rw-r--r--bos-namespaces.sh29
-rw-r--r--bos-sugar.sh91
-rw-r--r--t/namespace.t17
3 files changed, 104 insertions, 33 deletions
diff --git a/bos-namespaces.sh b/bos-namespaces.sh
index 0cb794a..02f3df2 100644
--- a/bos-namespaces.sh
+++ b/bos-namespaces.sh
@@ -38,9 +38,25 @@ function bos-namespaces/store-dict-for-into() {
result="$name"
}
+declare -a bos_namespace_stack
+
+function bos-namespaces/current-namespace-into() {
+ local -n bos_namespace_current_namespace_result="$1"
+ local IFS=/
+ bos_namespace_current_namespace_result="${bos_namespace_stack[*]}"
+}
+
+function bos-namespaces/push() {
+ bos_namespace_stack+=( "$1" )
+}
+
+function bos-namespaces/pop() {
+ unset "bos_namespace_stack[-1]"
+}
+
# save all currently-visible functions in an associative array
-function bos-namespaces/start() {
- local namespace="$1";shift
+function bos-namespaces/save-funcs() {
+ local namespace; bos-namespaces/current-namespace-into namespace
local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
local -n saved_funcs="$ns_store"
local _ funcname
@@ -56,12 +72,17 @@ function bos-namespaces/start() {
# ones that differ
function bos-namespaces/list-new-funcs-into() {
local -n result="$1"
- local namespace="$2"
+ local namespace; bos-namespaces/current-namespace-into namespace
local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
local -n saved_funcs="$ns_store"
local _ funcname new_function
while read -r _ _ funcname; do
+ # if a function already belong to this namespace, it's not new
+ if [[ "$funcname" == "$namespace"/* ]]; then
+ continue
+ fi
+
new_function="$(declare -pf "$funcname")"
if [[ "$new_function" != "${saved_funcs["$funcname"]}" ]]; then
result+=( "${funcname}" )
@@ -74,7 +95,7 @@ function bos-namespaces/list-new-funcs-into() {
# rename a bunch of functions by prepending a prefix; restore the
# saved function of the same name, if it exists
function bos-namespaces/qualify-funcs() {
- local namespace="$1";shift
+ local namespace; bos-namespaces/current-namespace-into namespace
local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
local -n saved_funcs="$ns_store"
local _ funcname new_function
diff --git a/bos-sugar.sh b/bos-sugar.sh
index 2da789a..1322b36 100644
--- a/bos-sugar.sh
+++ b/bos-sugar.sh
@@ -1,47 +1,58 @@
#!bash
-declare -a bos_sugar_block_toggle
+declare -a bos_sugar_block_stack
-function bos-sugar/block() {
+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
- local depth="${#FUNCNAME[*]}"
- if [[ -z "${bos_sugar_block_toggle[$depth]}" ]]; then
- bos_sugar_block_toggle=( ["$depth"]=1 )
- "$on_open" "$@"
+
+ if [[ "${bos_sugar_block_stack[-1]}" == 0 ]]; then
+ bos_sugar_block_stack[-1]=1
+ "$on_open" "$@" && return 0
else
- unset "bos_sugar_block_toggle[$depth]"
- "$on_close" "$@"
+ unset "bos_sugar_block_toggle[-1]"
+ "$on_close" "$@" && return 1
fi
}
-declare -a bos_sugar_class_stack
+function bos-sugar/declare-block() {
+ local block_name="$1"
+ local open_func="$2"
+ local close_func="$3"
-function bos-sugar/current-class-into() {
- local -n bos_sugar_current_class_result="$1"
- local IFS=/
- bos_sugar_current_class_result="${bos_sugar_class_stack[*]}"
+ 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-current-class() {
- local class; bos-sugar/current-class-into class
+# ----
+
+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 [[ "${#*}" -gt 1 ]]; then
+ if [[ "${#*}" -ne 1 ]]; then
>&2 echo "'class \$class_name; do …; done', not 'class $*'"
return 1
fi
+
local class="$1"
- bos_sugar_class_stack+=( "$class" )
- bos-sugar/set-metaclass-for-current-class
- local fq_class; bos-sugar/current-class-into fq_class
+ 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-sugar/current-class-into fq_class
+ 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" "$@"
@@ -49,7 +60,7 @@ function bos-sugar/class-open() {
eval "function $fq_class { bos-dispatch/invoke \"$fq_class\" 0 \"\$@\"; }"
- bos-namespaces/start "$fq_class"
+ bos-namespaces/save-funcs
# this will get renamed into the class
function new-into() {
@@ -68,22 +79,44 @@ function bos-sugar/class-open() {
}
function bos-sugar/class-close() {
- local class="$1"
+ local class="$1";
- local fq_class; bos-sugar/current-class-into fq_class
+ 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 "$fq_class"
- bos-namespaces/qualify-funcs "$fq_class" "${methods_list[@]}"
+ 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"
- unset "bos_sugar_class_stack[-1]"
+ 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 1
+ 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
}
-shopt -s expand_aliases
+bos-sugar/declare-block namespace bos-sugar/namespace-open bos-sugar/namespace-close
-alias class='while bos-sugar/block bos-sugar/class-open bos-sugar/class-close'
diff --git a/t/namespace.t b/t/namespace.t
new file mode 100644
index 0000000..e367720
--- /dev/null
+++ b/t/namespace.t
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+. t/testlib.sh
+
+namespace One; do
+ function test() { echo One/test; }
+
+ class Two; do
+ function test() { echo One/Two/test; }
+ done
+
+done
+
+is "$(One/test)" One/test 'function should be moved to namespace'
+is "$(One/Two/test)" One/Two/test 'class should be moved to namespace'
+
+done-testing