diff --git a/moo/README.md b/moo/README.md index 3d13f47..74eef5e 100644 --- a/moo/README.md +++ b/moo/README.md @@ -62,6 +62,27 @@ class MyClass(Object) } ``` +Class attributes + +The word class can be followed by attribute list enclosed in parenthesis. e.g.) class(#limited,#immutable) + +* #limited - not instantiable with new. +* #immutable - instantiated object to be read-only. +* #final - disallow subclasses. +* #byte, #character, #halfword, #word, #liword, #pointer - + specify the type of a non-pointer object. a non-pointer type can have an additional size + enclosed in parenthesis. e.g.) #character(2) + a non-pointer object is not allowed to have named instanced variables. + a non-pointer object is always variable indexed. +* #pointer - specify a pointer variable indexed object. an instantiate object can have extra + object pointers in additon to named instance variables. + +``` +class(#word(2)) X(Object) { } +X new -> create an object with 2 words. +X new: 4 -> create an object with 6 words. +``` + ### Flow Control ``` k := if (i < 20) { 30 } else { 40 }. diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index b081acf..e647ca3 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -381,7 +381,7 @@ TODO: how to pass all variadic arguments to another variadic methods??? } -class SmallPointer(Object) +class(#limited) SmallPointer(Object) { method(#primitive) asString. @@ -409,6 +409,6 @@ class SmallPointer(Object) method(#primitive) free. } -class LargePointer(Object) +class(#limited,#immutable,#word(1)) LargePointer(Object) { } diff --git a/moo/lib/comp.c b/moo/lib/comp.c index de73c45..5e83199 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -844,6 +844,7 @@ static moo_oop_t string_to_smptr (moo_t* moo, moo_oocs_t* str, moo_ioloc_t* loc) { moo_oow_t num = 0; const moo_ooch_t* ptr, * end; + moo_oop_t ret; ptr = str->ptr, end = str->ptr + str->len; @@ -873,6 +874,7 @@ static moo_oop_t string_to_smptr (moo_t* moo, moo_oocs_t* str, moo_ioloc_t* loc) ptr++; } +#if 0 if (!MOO_IN_SMPTR_RANGE(num)) { moo_setsynerr (moo, MOO_SYNERR_SMPTRLITINVAL, loc, str); @@ -880,6 +882,14 @@ static moo_oop_t string_to_smptr (moo_t* moo, moo_oocs_t* str, moo_ioloc_t* loc) } return MOO_SMPTR_TO_OOP(num); +#else + /* TODO: change the function name from string_to_smptr() to string_to_ptr() if this part of code is permanently accepted */ + if (MOO_IN_SMPTR_RANGE(num)) return MOO_SMPTR_TO_OOP(num); + ret = moo_instantiate(moo, moo->_large_pointer, MOO_NULL, 0); + if (!ret) return MOO_NULL; + MOO_OBJ_SET_WORD_VAL(ret, 0, num); + return ret; +#endif } /* --------------------------------------------------------------------- diff --git a/moo/lib/exec.c b/moo/lib/exec.c index d827768..6ea1949 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -4085,8 +4085,9 @@ static moo_pfrc_t pf_error_as_string (moo_t* moo, moo_mod_t* mod, moo_ooi_t narg ec = MOO_OOP_TO_ERROR(rcv); MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(ec)); -/* TODO: error string will be mostly the same.. do i really have to call makestring every time? */ - s = moo_errnum_to_errstr (ec); +/* TODO: error string will be mostly the same.. do i really have to call makestring every time? + * cache the error string object created? */ + s = moo_errnum_to_errstr(ec); ss = moo_makestring (moo, s, moo_count_oocstr(s)); if (!ss) return MOO_PF_FAILURE; diff --git a/moo/lib/fmt.c b/moo/lib/fmt.c index d82b11c..fc927a4 100644 --- a/moo/lib/fmt.c +++ b/moo/lib/fmt.c @@ -1436,7 +1436,7 @@ int moo_fmt_object_ (moo_fmtout_t* fmtout, moo_oop_t oop) for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) { - ch = MOO_OBJ_GET_CHAR_SLOT(oop)[i]; + ch = MOO_OBJ_GET_CHAR_VAL(oop, i); if ((ch >= '\0' && ch < ' ') || ch == '\\' || ch == '\"') { escape = 1; @@ -1451,7 +1451,7 @@ int moo_fmt_object_ (moo_fmtout_t* fmtout, moo_oop_t oop) if (moo_bfmt_out(fmtout, ((c == moo->_symbol)? "#\"": "\"")) <= -1) return -1; for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) { - ch = MOO_OBJ_GET_CHAR_SLOT(oop)[i]; + ch = MOO_OBJ_GET_CHAR_VAL(oop, i); if (ch >= '\0' && ch < ' ') { switch (ch) diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 6d75762..fda379f 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -387,13 +387,22 @@ static kernel_class_info_t kernel_classes[] = { 12, { 'S','m','a','l','l','P','o','i','n','t','e','r' }, - 0, + MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, 0, 0, MOO_OBJ_TYPE_OOP, MOO_OFFSETOF(moo_t, _small_pointer) }, + { 12, + { 'L','a','r','g','e','P','o','i','n','t','e','r' }, + MOO_CLASS_SELFSPEC_FLAG_LIMITED, + 0, + 1, /* #word(1) */ + MOO_CLASS_SPEC_FLAG_IMMUTABLE | MOO_CLASS_SPEC_FLAG_INDEXED, + MOO_OBJ_TYPE_WORD, + MOO_OFFSETOF(moo_t, _large_pointer) }, + { 6, { 'S','y','s','t','e','m' }, 0, diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 00a7538..33690f1 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1562,6 +1562,7 @@ struct moo_t moo_oop_class_t _fixed_point_decimal; /* FixedPointDecimal */ moo_oop_class_t _small_pointer; + moo_oop_class_t _large_pointer; moo_oop_class_t _system; /* ============================================================= * END KERNEL CLASSES