diff options
-rw-r--r-- | bos-base.sh | 7 | ||||
-rw-r--r-- | bos-dispatch.sh | 6 | ||||
-rw-r--r-- | bos-meta-class.sh | 16 | ||||
-rw-r--r-- | bos-meta.sh | 17 | ||||
-rw-r--r-- | bos-sugar.sh | 41 | ||||
-rw-r--r-- | meta-stuff.rst.txt | 24 | ||||
-rw-r--r-- | t/testlib.sh | 3 |
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 |