summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2023-07-22 16:38:33 +0100
committerdakkar <dakkar@thenautilus.net>2023-07-22 16:38:33 +0100
commit02eec4498027352e87826929d015f5b47bad93f8 (patch)
treef59e8d639aabdd6899cb3d570d57468d7e85833a
parentmove constructor to global base class (diff)
downloadbash-object-system-02eec4498027352e87826929d015f5b47bad93f8.tar.gz
bash-object-system-02eec4498027352e87826929d015f5b47bad93f8.tar.bz2
bash-object-system-02eec4498027352e87826929d015f5b47bad93f8.zip
metaclass instances
-rw-r--r--bos-base.sh7
-rw-r--r--bos-dispatch.sh6
-rw-r--r--bos-meta-class.sh16
-rw-r--r--bos-meta.sh17
-rw-r--r--bos-sugar.sh41
-rw-r--r--meta-stuff.rst.txt24
-rw-r--r--t/testlib.sh3
7 files changed, 74 insertions, 40 deletions
diff --git a/bos-base.sh b/bos-base.sh
index d964177..3e97b78 100644
--- a/bos-base.sh
+++ b/bos-base.sh
@@ -3,11 +3,12 @@
function bos/base/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_into_metaclass_instance; bos-meta/metaclass-instance-for-class-into new_into_metaclass_instance "$class"
local new_object
- $metaclass_object create-object-into new_object "$class" "$@"
+ $new_into_metaclass_instance create-object-into new_object "$class" "$@"
new_into_result="$new_object"
+
+ return 0
}
diff --git a/bos-dispatch.sh b/bos-dispatch.sh
index 8306378..d6bc463 100644
--- a/bos-dispatch.sh
+++ b/bos-dispatch.sh
@@ -33,10 +33,8 @@ function bos-dispatch/invoke() {
return $?
fi
- local metaclass_ref
- bos-namespaces/store-scalar-for-into metaclass_ref meta "$class"
- local -n metaclass_object="$metaclass_ref"
+ local metaclass_instance; bos-meta/metaclass-instance-for-class-into metaclass_instance "$class"
- $metaclass_object invoke "$class" "$self_id" "$method" "$@"
+ $metaclass_instance invoke "$class" "$self_id" "$method" "$@"
return $?
}
diff --git a/bos-meta-class.sh b/bos-meta-class.sh
index 9bfdd0a..1fedb45 100644
--- a/bos-meta-class.sh
+++ b/bos-meta-class.sh
@@ -1,9 +1,5 @@
#!bash
-# this encoding must match bos-namespaces/encode-into
-bos_5fbos_2fmeta_2fclass_5fmeta="bos-dipatch/invoke bos/meta/class 0"
-declare -a bos_5fbos_2fmeta_2fclass_5fmro=( "bos/meta/class" )
-
# these are instance methods of the base metaclass
function bos/meta/class/isa-for-into() {
@@ -152,3 +148,15 @@ function bos/meta/class/create-object-into() {
return 0
}
+
+function bos/meta/class() {
+ bos-dispatch/invoke bos/meta/class 0 "$@"
+}
+
+declare bos_meta_class_meta_class_instance
+bos/meta/class/create-object-into bos_meta_class_meta_class_instance bos/meta/class
+bos-meta/set-metaclass-instance-for bos/meta/class "$bos_meta_class_meta_class_instance"
+
+$bos_meta_class_meta_class_instance make-mro-for bos/meta/class
+
+unset bos_meta_class_meta_class_instance
diff --git a/bos-meta.sh b/bos-meta.sh
new file mode 100644
index 0000000..6932095
--- /dev/null
+++ b/bos-meta.sh
@@ -0,0 +1,17 @@
+#!bash
+
+declare -A bos_meta_metaclass_instance_for_class
+
+function bos-meta/set-metaclass-instance-for() {
+ bos_meta_metaclass_instance_for_class["$1"]="$2"
+
+ return 0
+}
+
+function bos-meta/metaclass-instance-for-class-into() {
+ local -n bos_meta_metaclass_instance_result="$1"
+
+ bos_meta_metaclass_instance_result="${bos_meta_metaclass_instance_for_class[$2]}"
+
+ return 0
+}
diff --git a/bos-sugar.sh b/bos-sugar.sh
index 8f3a810..152f5d8 100644
--- a/bos-sugar.sh
+++ b/bos-sugar.sh
@@ -31,31 +31,34 @@ function bos-sugar/declare-block() {
# ----
-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/meta/class 0'
+function bos-sugar/declare-helpers() {
+ function extends() {
+ local fq_class; bos-namespaces/current-namespace-into fq_class
+ local metaclass_instance; bos-meta/metaclass-instance-for-class-into metaclass_instance "$fq_class"
+ $metaclass_instance set-superclasses-for "$fq_class" "$@"
+ }
+}
+
+function bos-sugar/remove-helpers() {
+ unset extends
}
function bos-sugar/class-open() {
- if [[ "${#*}" -ne 1 ]]; then
- >&2 echo "'class \$class_name; do …; done', not 'class $*'"
+ if [[ "${#*}" -lt 1 || "${#*}" -gt 2 ]]; then
+ >&2 echo "'class \$class_name [\$metaclass]; do …; done', not 'class $*'"
return 1
fi
+ local class="$1"
+ local metaclass="${2:-bos/meta/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" "$@"
- }
+ bos-sugar/declare-helpers
- local class="$1"
bos-namespaces/namespace-open "$1"
local fq_class; bos-namespaces/current-namespace-into fq_class
- bos-sugar/set-metaclass-for "$fq_class"
+ local class_open_metaclass_instance; $metaclass new-into class_open_metaclass_instance
+
+ bos-meta/set-metaclass-instance-for "$fq_class" "$class_open_metaclass_instance"
return 0
}
@@ -64,16 +67,18 @@ 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"
bos-namespaces/namespace-close
- $metaclass_object make-mro-for "$fq_class"
+ local class_close_metaclass_instance; bos-meta/metaclass-instance-for-class-into class_close_metaclass_instance "$fq_class"
+
+ $class_close_metaclass_instance make-mro-for "$fq_class"
# TODO this should probably be done by the metaclass?
eval "function $fq_class { bos-dispatch/invoke \"$fq_class\" 0 \"\$@\"; }"
+ bos-sugar/remove-helpers
+
return 0
}
diff --git a/meta-stuff.rst.txt b/meta-stuff.rst.txt
index 46fabf5..ea5a074 100644
--- a/meta-stuff.rst.txt
+++ b/meta-stuff.rst.txt
@@ -10,10 +10,15 @@ done bits
* ``bos/mop/base`` + ``bos/mop/inheritance`` become ``bos/meta/class``
-next bits…
+ * store class→metaclass association somewhere (global dictionary,
+ probably)
-* formalise that ``bos-dispatch/invoke $class 0 $method $args`` is a
- class method invocation
+ - when creating a class, create a metaclass instance and store it
+ - the store must be pre-populated with metaclass instances for:
+
+ + ``bos/meta/class`` → ``bos-dispatch/invoke bos/meta/class 1``
+
+next bits…
* add ``bos/meta/attribute``
@@ -32,13 +37,12 @@ next bits…
- ``add-attribute``
- add class, mro, as attributes to the metaclass
-* store class→metaclass association somewhere (global dictionary,
- probably)
+* pre-populated metaclass instances for:
- - when creating a class, create a metaclass instance and store it
- - the store must be pre-populated with metaclass instances for:
+ - ``bos/meta/class`` → ``bos-dispatch/invoke bos/meta/class 1``
+ - ``bos/meta/attribute`` → ``bos-dispatch/invoke bos/meta/class 2``
- + ``bos/meta/class`` → ``bos-dispatch/invoke bos/meta/class 1``
- + ``bos/meta/attribute`` → ``bos-dispatch/invoke bos/meta/class 2``
+ and those instances' attributes must be manually stored
- and those instances' attributes must be manually stored
+* formalise that ``bos-dispatch/invoke $class 0 $method $args`` is a
+ class method invocation
diff --git a/t/testlib.sh b/t/testlib.sh
index af5eed2..edbd973 100644
--- a/t/testlib.sh
+++ b/t/testlib.sh
@@ -2,11 +2,12 @@
PS4='[${#FUNCNAME[*]}] ${BASH_SOURCE[0]}:${LINENO} (${FUNCNAME[0]}) +'
+. bos-dispatch.sh
. bos-namespaces.sh
. bos-object-id.sh
. bos-base.sh
+. bos-meta.sh
. bos-meta-class.sh
-. bos-dispatch.sh
. bos-sugar.sh
. minitap.sh