diff --git a/lib/exec.c b/lib/exec.c index 39cdc14..93fff2a 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -3934,12 +3934,16 @@ static int execute (hcl_t* hcl) if (HCL_OBJ_GET_FLAGS_KERNEL(class_obj) == 1) { /* check if the new definition is compatible with kernel definition */ - hcl_ooi_t spec, selfspec; + hcl_ooi_t spec, selfspec, nivars_super, nivars_super_real; spec = HCL_OOP_TO_SMOOI(class_obj->spec); selfspec = HCL_OOP_TO_SMOOI(class_obj->selfspec); + nivars_super = HCL_OOP_TO_SMOOI(class_obj->nivars_super); + nivars_super_real = HCL_IS_NIL(hcl, superclass)? 0: HCL_OOP_TO_SMOOI(((hcl_oop_class_t)superclass)->nivars_super); +#if 0 hcl_logbfmt (hcl, HCL_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncvars=%d<<<\n", class_obj, class_obj->superclass, superclass, b2, b3, (int)HCL_CLASS_SPEC_NAMED_INSTVARS(spec), (int)HCL_CLASS_SELFSPEC_CLASSVARS(spec)); - if (class_obj->superclass != superclass || HCL_CLASS_SPEC_NAMED_INSTVARS(spec) != b2 || HCL_CLASS_SELFSPEC_CLASSVARS(selfspec) != b3) +#endif + if (class_obj->superclass != superclass || HCL_CLASS_SPEC_NAMED_INSTVARS(spec) != b2 || HCL_CLASS_SELFSPEC_CLASSVARS(selfspec) != b3 || nivars_super != nivars_super_real) { hcl_seterrbfmt (hcl, HCL_EPERM, "incompatible redefintion of %.*js", HCL_OBJ_GET_SIZE(class_name), HCL_OBJ_GET_CHAR_SLOT(class_name)); if (do_throw_with_internal_errmsg(hcl, fetched_instruction_pointer) >= 0) break; diff --git a/lib/gc.c b/lib/gc.c index de29f5c..6518eae 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -1468,6 +1468,7 @@ static int ignite_1 (hcl_t* hcl) HCL_OBJ_SET_CLASS (hcl->c_class, (hcl_oop_t)hcl->c_class); } + /* create class objects except Class */ for (i = 0; i < HCL_COUNTOF(kernel_classes); i++) { hcl_oop_class_t tmp; @@ -1496,6 +1497,20 @@ static int ignite_1 (hcl_t* hcl) *(hcl_oop_class_t*)((hcl_uint8_t*)hcl + kernel_classes[i].offset) = tmp; } + /* update the superclass field */ + for (i = 0; i < HCL_COUNTOF(kernel_classes); i++) + { + int skci; + skci = kernel_classes[i].superclass_kci; + if (skci >= 0) + { + hcl_oop_class_t* x, * y; + x = (hcl_oop_class_t*)((hcl_uint8_t*)hcl + kernel_classes[i].offset); + y = (hcl_oop_class_t*)((hcl_uint8_t*)hcl + kernel_classes[skci].offset); + (*x)->superclass = (hcl_oop_t)*y; + } + } + #if 0 /* an instance of a method class stores byte codes in the trailer space. * unlike other classes with trailer size set, the size of the trailer diff --git a/mod/core.c b/mod/core.c index 6048f3b..d7d31fd 100644 --- a/mod/core.c +++ b/mod/core.c @@ -48,16 +48,217 @@ static hcl_pfrc_t pf_core_get_class_name (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t return HCL_PF_SUCCESS; } +static hcl_pfrc_t pf_core_size (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + hcl_oop_oop_t src; + hcl_oop_t size; + + src = (hcl_oop_oop_t)HCL_STACK_GETARG(hcl, nargs, 0); + + if (!HCL_OOP_IS_POINTER(src)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "source not sizable - %O", src); + return HCL_PF_FAILURE; + } + + size = hcl_oowtoint(hcl, HCL_OBJ_GET_SIZE(src)); + if (!size) return HCL_PF_FAILURE; + + HCL_STACK_SETRET (hcl, nargs, size); + return HCL_PF_SUCCESS; +} + +static hcl_pfrc_t pf_core_slice (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + hcl_oop_t src, slice, a1, a2; + hcl_ooi_t size; + hcl_ooi_t pos; + hcl_ooi_t len; + hcl_ooi_t i; + + src = HCL_STACK_GETARG(hcl, nargs, 0); + a1 = HCL_STACK_GETARG(hcl, nargs, 1); + a2 = HCL_STACK_GETARG(hcl, nargs, 2); + + if (!HCL_OOP_IS_POINTER(src)) + { + unsliceable: + hcl_seterrbfmt (hcl, HCL_EINVAL, "source not sliceable - %O", src); + return HCL_PF_FAILURE; + } + + if (!HCL_OOP_IS_SMOOI(a1)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "position not numeric - %O", a1); + return HCL_PF_FAILURE; + } + if (!HCL_OOP_IS_SMOOI(a2)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "length not numeric - %O", a2); + return HCL_PF_FAILURE; + } + + size = HCL_OBJ_GET_SIZE(src); + pos = HCL_OOP_TO_SMOOI(a1); + len = HCL_OOP_TO_SMOOI(a2); + + if (pos < 0) pos = 0; + else if (pos >= size) pos = size; + if (len >= size - pos) len = size - pos; + +/* TODO: check if the object is an indexable object from the class spec... */ + /* use HCL_OBJ_GET_CLASS() instead of HCL_CLASSOF() as we know it's an object */ + slice = hcl_instantiate(hcl, (hcl_oop_class_t)HCL_OBJ_GET_CLASS(src), HCL_NULL, len); + if (HCL_UNLIKELY(!slice)) return HCL_PF_FAILURE; + +/* OR if add by the number of fixed fields??? */ + switch (HCL_OBJ_GET_FLAGS_TYPE(src)) + { + case HCL_OBJ_TYPE_OOP: + for (i = 0; i < len; i++) HCL_OBJ_GET_OOP_VAL(slice, i) = HCL_OBJ_GET_OOP_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_CHAR: + for (i = 0; i < len; i++) HCL_OBJ_GET_CHAR_VAL(slice, i) = HCL_OBJ_GET_CHAR_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_BYTE: + for (i = 0; i < len; i++) HCL_OBJ_GET_BYTE_VAL(slice, i) = HCL_OBJ_GET_BYTE_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_HALFWORD: + for (i = 0; i < len; i++) HCL_OBJ_GET_HALFWORD_VAL(slice, i) = HCL_OBJ_GET_HALFWORD_VAL(src, pos + i); + break; + + case HCL_OBJ_TYPE_WORD: + for (i = 0; i < len; i++) HCL_OBJ_GET_WORD_VAL(slice, i) = HCL_OBJ_GET_WORD_VAL(src, pos + i); + break; + + default: + goto unsliceable; + break; + } + + HCL_STACK_SETRET (hcl, nargs, slice); + return HCL_PF_SUCCESS; +} + +static hcl_pfrc_t pf_core_get (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + hcl_oop_t obj, val; + hcl_oop_t pos; + hcl_oow_t index; + + obj = HCL_STACK_GETARG(hcl, nargs, 0); + pos = HCL_STACK_GETARG(hcl, nargs, 1); + + if (!HCL_OOP_IS_POINTER(obj)) + { + unindexable: + hcl_seterrbfmt (hcl, HCL_EINVAL, "object not indexable - %O", obj); + return HCL_PF_FAILURE; + } + + if (!HCL_OOP_IS_SMOOI(pos)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "position not numeric - %O", pos); + return HCL_PF_FAILURE; + } + index = HCL_OOP_TO_SMOOI(pos); + if (index < 0 || index >= HCL_OBJ_GET_SIZE(obj)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "position(%O) out of range - 0 and %zu", pos, (hcl_oow_t)HCL_OBJ_GET_SIZE(obj) - 1); + return HCL_PF_FAILURE; + } + + switch (HCL_OBJ_GET_FLAGS_TYPE(obj)) + { + case HCL_OBJ_TYPE_OOP: + val = HCL_OBJ_GET_OOP_VAL(obj, index); + break; + + case HCL_OBJ_TYPE_CHAR: + { + hcl_ooch_t c; + c = HCL_OBJ_GET_CHAR_VAL(obj, index); + val = HCL_CHAR_TO_OOP(c); + break; + } + + case HCL_OBJ_TYPE_BYTE: + { + hcl_ooi_t b; + b = HCL_OBJ_GET_BYTE_VAL(obj, index); + val = HCL_SMOOI_TO_OOP(b); + break; + } + + case HCL_OBJ_TYPE_HALFWORD: + val = hcl_oowtoint(hcl, HCL_OBJ_GET_HALFWORD_VAL(obj, index)); + if (HCL_UNLIKELY(!val)) return HCL_PF_FAILURE; + break; + + case HCL_OBJ_TYPE_WORD: + val = hcl_oowtoint(hcl, HCL_OBJ_GET_WORD_VAL(obj, index)); + if (HCL_UNLIKELY(!val)) return HCL_PF_FAILURE; + break; + + default: + goto unindexable; + break; + } + + HCL_STACK_SETRET (hcl, nargs, val); + return HCL_PF_SUCCESS; +} + +#if 0 +static hcl_pfrc_t pf_core_put (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + hcl_oop_t obj; + hcl_oop_t pos, val; + hcl_oow_t index; + + obj = HCL_STACK_GETARG(hcl, nargs, 0); + pos = HCL_STACK_GETARG(hcl, nargs, 1); + val = HCL_STACK_GETARG(hcl, nargs, 2); + + if (!HCL_OOP_IS_POINTER(obj)) + { + unindexable: + hcl_seterrbfmt (hcl, HCL_EINVAL, "object not indexable - %O", obj); + return HCL_PF_FAILURE; + } + + if (!HCL_IS_ARRAY(hcl,obj)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "parameter not an array - %O", obj); + return HCL_PF_FAILURE; + } + if (!HCL_OOP_IS_SMOOI(pos)) + { + hcl_seterrbfmt (hcl, HCL_EINVAL, "position not numeric - %O", pos); + return HCL_PF_FAILURE; + } + index = HCL_OOP_TO_SMOOI(pos); + + obj->slot[index] = val; + HCL_STACK_SETRET (hcl, nargs, val); + return HCL_PF_SUCCESS; +} +#endif + static hcl_pfinfo_t pfinfos[] = { { { 'c','l','a','s','s','_','n','a','m','e','\0' }, { HCL_PFBASE_FUNC, pf_core_get_class_name, 1, 1 } }, -/* + { { 'g','e','t','\0' }, { HCL_PFBASE_FUNC, pf_core_get, 2, 2 } }, { { 'l','e','n','g','t','h','\0' }, { HCL_PFBASE_FUNC, pf_core_size, 1, 1 } }, +/* { { 'n','e','w','\0' }, { HCL_PFBASE_FUNC, pf_core_new, 1, 1 } }, { { 'p','u','t','\0' }, { HCL_PFBASE_FUNC, pf_core_put, 3, 3 } }, +*/ { { 's','i','z','e','\0' }, { HCL_PFBASE_FUNC, pf_core_size, 1, 1 } }, { { 's','l','i','c','e','\0' }, { HCL_PFBASE_FUNC, pf_core_slice, 3, 3 } } -*/ }; /* ------------------------------------------------------------------------ */ diff --git a/src/kernel.hcl b/src/kernel.hcl index d2c9fa6..cc9dcb8 100644 --- a/src/kernel.hcl +++ b/src/kernel.hcl @@ -10,21 +10,25 @@ class Collection :: Object { class IndexedCollection :: Collection { } -class FixedSizedCollection :: Collection { +class FixedSizedCollection :: IndexedCollection { } class Array :: FixedSizedCollection { } -class String :: Array { +class String :: FixedSizedCollection { } fun Collection:length() { - return (arr.length self) + return (core.length self) } fun Collection:slice(index count) { - return (arr.slice self index count) + return (core.slice self index count) +} + +fun Collection:at(index) { + return (core.get self index) } fun Class:name() { @@ -50,3 +54,5 @@ fun Class:name() { printf "string length %d\n" ("aaaa":length) +printf "substring [%s]\n" ("abcdefghijklmn":slice 5 6) +printf "substring [%c]\n" ("abcdefghijklmn":at 14)