From 5c07a48c5a26ea5d7c5769e294b86a1666ab03a3 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 7 Feb 2017 17:40:34 +0000 Subject: [PATCH] wrote code to handle dictionary expression and association expression notation --- moo/kernel/Collect.moo | 91 ++++++++++++++++++++++------- moo/kernel/Mill.moo | 40 ++++++++++++- moo/kernel/generr.moo | 3 + moo/lib/comp.c | 126 ++++++++++++++++++++++++++++++++++++++++- moo/lib/decode.c | 9 +++ moo/lib/dic.c | 25 +++++--- moo/lib/err.c | 5 +- moo/lib/exec.c | 29 +++++++++- moo/lib/gc.c | 5 +- moo/lib/moo-prv.h | 5 ++ moo/lib/moo.h | 11 +++- 11 files changed, 313 insertions(+), 36 deletions(-) diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index a8d5f28..8bd8da9 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -146,6 +146,26 @@ class Set(Collection) ^self.tally } + method __make_expanded_bucket: bs + { + | newbuc newsz ass index | + + (* expand the bucket *) + newsz := bs + 128. (* TODO: keep this growth policy in sync with VM(dic.c) *) + newbuc := Array new: newsz. + 0 priorTo: bs do: [:i | + ass := self.bucket at: i. + (ass notNil) ifTrue: [ + index := (ass key hash) rem: newsz. + [(newbuc at: index) notNil] whileTrue: [index := (index + 1) rem: newsz]. + newbuc at: index put: ass + ] + ]. + + ^newbuc. + } + + method __find: key or_upsert: upsert with: value { | hv ass bs index ntally | @@ -164,28 +184,17 @@ class Set(Collection) index := (index + 1) rem: bs. ]. - upsert ifFalse: [^ErrorCode.NOENT]. + ##upsert ifFalse: [^ErrorCode.NOENT]. + if (upsert) {} else { ^ErrorCode.NOENT }. ntally := self.tally + 1. - (ntally >= bs) ifTrue: [ - | newbuc newsz | - (* expand the bucket *) - newsz := bs + 123. (* TODO: keep this growth policy in sync with VM(dic.c) *) - newbuc := Array new: newsz. - 0 priorTo: bs do: [:i | - ass := self.bucket at: i. - (ass notNil) ifTrue: [ - index := (ass key hash) rem: newsz. - [(newbuc at: index) notNil] whileTrue: [index := (index + 1) rem: newsz]. - newbuc at: index put: ass - ] - ]. - - self.bucket := newbuc. + if (ntally >= bs) + { + self.bucket := self __make_expanded_bucket: bs. bs := self.bucket size. index := hv rem: bs. [(self.bucket at: index) notNil] whileTrue: [index := (index + 1) rem: bs ]. - ]. + }. ass := Association key: key value: value. self.tally := ntally. @@ -194,6 +203,46 @@ class Set(Collection) ^ass } + (* __assocPut: is a special internal method used by VM to add an association + * to a dictionary with the dictionary/association expression notation. + * :{ :( 1, 20 ), :( #moo, 999) } *) + method __assocPut: assoc + { + | hv ass bs index ntally key | + + key := assoc key. + bs := self.bucket size. + hv := key hash. + index := hv rem: bs. + + [(ass := self.bucket at: index) notNil] + whileTrue: [ + (key = ass key) ifTrue: [ + (* found *) + self.bucket at: index put: assoc. + ##^assoc. + ^self. + ]. + index := (index + 1) rem: bs. + ]. + + (* not found *) + ntally := self.tally + 1. + if (ntally >= bs) + { + self.bucket := self __make_expanded_bucket: bs. + bs := self.bucket size. + index := hv rem: bs. + [(self.bucket at: index) notNil] whileTrue: [index := (index + 1) rem: bs ]. + }. + + self.tally := ntally. + self.bucket at: index put: assoc. + + ##^assoc. + ^self. + } + method at: key { | ass | @@ -210,15 +259,15 @@ class Set(Collection) ^ass value } - method associationAt: key + method associationAt: assoc { - ^self __find: key or_upsert: false with: nil. + ^self __find: (assoc key) or_upsert: false with: nil. } - method associationAt: key ifAbsent: error_block + method associationAt: assoc ifAbsent: error_block { | ass | - ass := self __find: key or_upsert: false with: nil. + ass := self __find: (assoc key) or_upsert: false with: nil. (ass isError) ifTrue: [^error_block value]. ^ass } diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index 489689e..6e03e9f 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -268,9 +268,15 @@ class MyObject(Object) ##Processor sleepFor: 20. } + + method(#class) main { + |a| + + a := 100. ## PROBLEM: the following double loop will exhaust the stack + (* while (true) { ##111 dump. @@ -282,7 +288,39 @@ class MyObject(Object) ##[:j :q | (j + q) dump] value: 10 value: 20. ##if (false) {} else { break }. }. + }.*) + + ##:() dump. ## missing association key + ##:(a+10,) dump. ## missing association value. + ##:(1,2,3) dump. ## ) expecte where , is + ##:(a+100,a*99) dump. + ##:(a+a+100,a*a*99) dump. + + a := :{ + :('aaa', 10), + :('bbb', 20), + :('bbb', 30), + :(#bbb, 40), + ##:(5, 99), + :('ccc', 890) }. + + (*a removeKey: 'bbb'. + a remove: :(#bbb).*) + + a keysAndValuesDo: [:k :v | + k dump. + v dump. + '------------' dump. + ]. + + (a associationAt: :(#aaa)) dump. } -## } + +(* +pooldic XXD { + #abc := #(1 2 3). + #def := #{ 1, 3, 4 }. ## syntax error - literal expected where #{ is +} +*) diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index cc936cd..ae4ca12 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -102,6 +102,9 @@ class MyObject(Object) 'break or continue not within a loop' 'break or continue within a block' 'while expected' + 'missing association key' + 'missing association value' + 'missing association' ). f := Stdio open: 'generr.out' for: 'w'. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index a32f48d..de96fd5 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -2020,6 +2020,7 @@ static int emit_single_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1 case BCODE_PUSH_INTLIT: case BCODE_PUSH_NEGINTLIT: case BCODE_PUSH_CHARLIT: + case BCODE_MAKE_DICTIONARY: case BCODE_MAKE_ARRAY: case BCODE_POP_INTO_ARRAY: bc = cmd; @@ -4059,13 +4060,128 @@ static int compile_array_expression (moo_t* moo) #else moo->c->mth.code.ptr[maip + 1] = index; #endif - } GET_TOKEN (moo); /* read a token after } */ return 0; } +static int compile_association_expression (moo_t* moo) +{ + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_ASSPAREN); + + GET_TOKEN (moo); /* read a token after #{ */ + if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + /* key is required */ + set_syntax_error (moo, MOO_SYNERR_NOASSKEY, TOKEN_LOC(moo), MOO_NULL); + return -1; + } + + if (emit_byte_instruction (moo, BCODE_MAKE_ASSOCIATION) <= -1) return -1; + + if (compile_method_expression (moo, 0) <= -1) return -1; + if (emit_byte_instruction (moo, BCODE_POP_INTO_ASSOCIATION_KEY) <= -1) return -1; + + if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + /* no comma, no value is specified. */ + goto done; + } + else if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) + { + set_syntax_error (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); /* read a token after the comma */ + if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + set_syntax_error (moo, MOO_SYNERR_NOASSVALUE, TOKEN_LOC(moo), MOO_NULL); + return -1; + } + + if (compile_method_expression (moo, 0) <= -1) return -1; + if (emit_byte_instruction (moo, BCODE_POP_INTO_ASSOCIATION_VALUE) <= -1) return -1; + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + +done: + GET_TOKEN (moo); + return 0; +} + +static int compile_dictionary_expression (moo_t* moo) +{ + moo_oow_t mdip; + + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DICBRACE); + + GET_TOKEN (moo); /* read a token after :{ */ + + mdip = moo->c->mth.code.len; + if (emit_single_param_instruction (moo, BCODE_MAKE_DICTIONARY, 0) <= -1) return -1; + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE) + { + moo_oow_t count; + + count = 0; + do + { + if (TOKEN_TYPE(moo) == MOO_IOTOK_ASSPAREN) + { + moo_oow_t si; + static moo_ooch_t msg[] = { '_', '_', 'a','s','s','o','c','P','u','t',':' }; + moo_oocs_t x; + + x.ptr = msg; + x.len = 11; + /* if the method returns self, i don't need DUP_STACKTOP and POP_STACKTOP + if (emit_byte_instruction (moo, BCODE_DUP_STACKTOP) <= -1 || + compile_association_expression(moo) <= -1 || + add_symbol_literal(moo, &x, 0, &si) <= -1 || + emit_double_param_instruction (moo, BCODE_SEND_MESSAGE_0, 1, si) <= -1 || + emit_byte_instruction (moo, BCODE_POP_STACKTOP) <= -1) return -1; */ + if (compile_association_expression(moo) <= -1 || + add_symbol_literal(moo, &x, 0, &si) <= -1 || + emit_double_param_instruction (moo, BCODE_SEND_MESSAGE_0, 1, si) <= -1) return -1; + count++; + } + else + { + set_syntax_error (moo, MOO_SYNERR_NOASSOC, TOKEN_LOC(moo), MOO_NULL); + return -1; + } + + if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break; + if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA) + { + GET_TOKEN(moo); + } + } + while (1); + + /* count is just a hint unlike in array */ + if (count > MAX_CODE_PARAM) count = MAX_CODE_PARAM; + + /* patch the MAKE_DICTIONARY instruction */ + #if (MOO_BCODE_LONG_PARAM_SIZE == 2) + moo->c->mth.code.ptr[mdip + 1] = count >> 8; + moo->c->mth.code.ptr[mdip + 2] = count & 0xFF; + #else + moo->c->mth.code.ptr[mdip + 1] = count; + #endif + } + + GET_TOKEN (moo); + return 0; +} + static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, const moo_ioloc_t* ident_loc, int ident_dotted, int* to_super) { /* @@ -4268,6 +4384,14 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons if (compile_array_expression(moo) <= -1) return -1; break; + case MOO_IOTOK_ASSPAREN: /* :( */ + if (compile_association_expression(moo) <= -1) return -1; + break; + + case MOO_IOTOK_DICBRACE: /* :{ */ + if (compile_dictionary_expression(moo) <= -1) return -1; + break; + case MOO_IOTOK_LBRACK: /* [ */ { int n; diff --git a/moo/lib/decode.c b/moo/lib/decode.c index fc2124b..8f7f0af 100644 --- a/moo/lib/decode.c +++ b/moo/lib/decode.c @@ -488,6 +488,15 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn) break; /* -------------------------------------------------------- */ + case BCODE_MAKE_DICTIONARY: + FETCH_PARAM_CODE_TO (moo, b1); + LOG_INST_1 (moo, "make_dictionary %zu", b1); + break; + + case BCODE_POP_INTO_DICTIONARY: + LOG_INST_0 (moo, "pop_into_dictionary"); + break; + case BCODE_MAKE_ASSOCIATION: LOG_INST_0 (moo, "make_association"); break; diff --git a/moo/lib/dic.c b/moo/lib/dic.c index 94791a3..0b78fa5 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -92,9 +92,10 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_set_t dic, moo_ moo_oop_association_t ass; moo_oow_t tmp_count = 0; - /* the system dictionary is not a generic dictionary. - * it accepts only a symbol as a key. */ - MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); + /* the builtin dictionary is not a generic dictionary. + * it accepts only a symbol or something similar as a key. */ + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol);*/ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(key)); MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer); MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array); @@ -107,9 +108,11 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_set_t dic, moo_ ass = (moo_oop_association_t)dic->bucket->slot[index]; MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol); + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); - if (MOO_OBJ_GET_SIZE(key) == MOO_OBJ_GET_SIZE(ass->key) && + if (MOO_OBJ_GET_CLASS(key) == MOO_OBJ_GET_CLASS(ass->key) && + MOO_OBJ_GET_SIZE(key) == MOO_OBJ_GET_SIZE(ass->key) && moo_equaloochars (key->slot, ((moo_oop_char_t)ass->key)->slot, MOO_OBJ_GET_SIZE(key))) { /* the value of MOO_NULL indicates no insertion or update. */ @@ -211,7 +214,8 @@ static moo_oop_association_t lookup (moo_t* moo, moo_oop_set_t dic, const moo_oo ass = (moo_oop_association_t)dic->bucket->slot[index]; MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol); + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); if (name->len == MOO_OBJ_GET_SIZE(ass->key) && moo_equaloochars(name->ptr, ((moo_oop_char_t)ass->key)->slot, name->len)) @@ -246,13 +250,15 @@ moo_oop_association_t moo_lookupsysdic (moo_t* moo, const moo_oocs_t* name) moo_oop_association_t moo_putatdic (moo_t* moo, moo_oop_set_t dic, moo_oop_t key, moo_oop_t value) { - MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol);*/ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(key)); return find_or_upsert (moo, dic, (moo_oop_char_t)key, value); } moo_oop_association_t moo_getatdic (moo_t* moo, moo_oop_set_t dic, moo_oop_t key) { - MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); */ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(key)); return find_or_upsert (moo, dic, (moo_oop_char_t)key, MOO_NULL); } @@ -282,7 +288,8 @@ int moo_deletedic (moo_t* moo, moo_oop_set_t dic, const moo_oocs_t* name) ass = (moo_oop_association_t)dic->bucket->slot[index]; MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol); + /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); if (name->len == MOO_OBJ_GET_SIZE(ass->key) && moo_equaloochars(name->ptr, ((moo_oop_char_t)ass->key)->slot, name->len)) diff --git a/moo/lib/err.c b/moo/lib/err.c index 539fe3f..0578d3f 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -128,6 +128,9 @@ static moo_ooch_t synerrstr_56[] = {'l','i','t','e','r','a','l',' ','e','x','p', static moo_ooch_t synerrstr_57[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; static moo_ooch_t synerrstr_58[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; static moo_ooch_t synerrstr_59[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_60[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','k','e','y','\0'}; +static moo_ooch_t synerrstr_61[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','v','a','l','u','e','\0'}; +static moo_ooch_t synerrstr_62[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -137,7 +140,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_32, synerrstr_33, synerrstr_34, synerrstr_35, synerrstr_36, synerrstr_37, synerrstr_38, synerrstr_39, synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47, synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, - synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59 + synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62 }; #endif /* END: GENERATED WITH generr.st */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 76348b6..099f208 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -3715,7 +3715,6 @@ int moo_execute (moo_t* moo) selector = (moo_oop_char_t)moo->active_method->slot[b2]; LOG_INST_3 (moo, "send_message%hs %zu @%zu", (((bcode >> 2) & 1)? "_to_super": ""), b1, b2); - if (send_message (moo, selector, ((bcode >> 2) & 1), b1) <= -1) goto oops; break; /* CMD_SEND_MESSAGE */ } @@ -3795,6 +3794,34 @@ int moo_execute (moo_t* moo) break; /* -------------------------------------------------------- */ + case BCODE_MAKE_DICTIONARY: + { + moo_oop_t t; + + FETCH_PARAM_CODE_TO (moo, b1); + LOG_INST_1 (moo, "make_dictionary %zu", b1); + + /* create an empty array */ + t = (moo_oop_t)moo_makedic (moo, moo->_dictionary, b1 + 10); /* TODO: find a better value than +10 for initial dictionary sizing */ + if (!t) goto oops; + + MOO_STACK_PUSH (moo, t); /* push the array created */ + break; + } + + case BCODE_POP_INTO_DICTIONARY: + { + moo_oop_t t1, t2; + + LOG_INST_0 (moo, "pop_into_dictionary"); + + t1 = MOO_STACK_GETTOP(moo); + MOO_STACK_POP (moo); + t2 = MOO_STACK_GETTOP(moo); + moo_putatdic (moo, (moo_oop_set_t)t2, ((moo_oop_association_t)t1)->key, ((moo_oop_association_t)t1)->value); /* TODO: 1. erorr check 2. reuse association as it it */ + break; + } + case BCODE_MAKE_ASSOCIATION: { moo_oop_t t; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 1c3db0e..10214f7 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -91,6 +91,7 @@ static kernel_class_info_t kernel_classes[] = { 5, { 'A','r','r','a','y' }, MOO_OFFSETOF(moo_t,_array) }, { 9, { 'B','y','t','e','A','r','r','a','y' }, MOO_OFFSETOF(moo_t,_byte_array) }, { 9, { 'S','y','m','b','o','l','S','e','t' }, MOO_OFFSETOF(moo_t,_symbol_set) }, + { 10, { 'D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _dictionary) }, { 16, { 'S','y','s','t','e','m','D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _system_dictionary) }, { 9, { 'N','a','m','e','s','p','a','c','e' }, MOO_OFFSETOF(moo_t, _namespace) }, @@ -176,6 +177,7 @@ static int ignite_1 (moo_t* moo) moo->_array = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_OOP)); moo->_byte_array = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_BYTE)); moo->_symbol_set = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); moo->_system_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); moo->_namespace = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); @@ -205,7 +207,8 @@ static int ignite_1 (moo_t* moo) !moo->_object || !moo->_string || !moo->_symbol || !moo->_array || - !moo->_byte_array || !moo->_symbol_set || !moo->_system_dictionary || + !moo->_byte_array || !moo->_symbol_set || + !moo->_dictionary || !moo->_system_dictionary || !moo->_namespace || !moo->_pool_dictionary || !moo->_method_dictionary || !moo->_method || !moo->_association || diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index f44b14c..b64e607 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -860,6 +860,11 @@ enum moo_bcode_t BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 ## */ BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 ## */ + /* UNUSED 237 */ + + BCODE_MAKE_DICTIONARY = 0xEE, /* 238 */ + BCODE_POP_INTO_DICTIONARY = 0xEF, /* 239 */ + BCODE_SEND_MESSAGE_X = 0xF0, /* 240 ## */ BCODE_MAKE_ASSOCIATION = 0xF1, /* 241 */ BCODE_POP_INTO_ASSOCIATION_KEY = 0xF2, /* 242 */ diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 92f62b8..b1ec868 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -360,6 +360,11 @@ typedef enum moo_obj_type_t moo_obj_type_t; /* [NOTE] this macro doesn't include the size of the trailer */ #define MOO_OBJ_BYTESOF(oop) ((MOO_OBJ_GET_SIZE(oop) + MOO_OBJ_GET_FLAGS_EXTRA(oop)) * MOO_OBJ_GET_FLAGS_UNIT(oop)) +#define MOO_OBJ_IS_CHAR_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_CHAR)) +#define MOO_OBJ_IS_BYTE_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_BYTE)) +#define MOO_OBJ_IS_HALFWORD_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_HALFWORD)) +#define MOO_OBJ_IS_WORD_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_WORD)) + /* [NOTE] this macro doesn't check the range of the actual value. * make sure that the value of each bit fields given falls within the * possible range of the defined bits */ @@ -900,6 +905,7 @@ struct moo_t moo_oop_t _array; /* Array */ moo_oop_t _byte_array; /* ByteArray */ moo_oop_t _symbol_set; /* SymbolSet */ + moo_oop_t _dictionary; moo_oop_t _system_dictionary; /* SystemDictionary */ moo_oop_t _namespace; /* Namespace */ @@ -1150,7 +1156,10 @@ enum moo_synerrnum_t MOO_SYNERR_LITERAL, /* literal expected */ MOO_SYNERR_NOTINLOOP, /* break or continue not within a loop */ MOO_SYNERR_INBLOCK, /* break or continue within a block */ - MOO_SYNERR_WHILE /* while expected */ + MOO_SYNERR_WHILE, /* while expected */ + MOO_SYNERR_NOASSKEY, /* missing association key */ + MOO_SYNERR_NOASSVALUE, /* missing association value */ + MOO_SYNERR_NOASSOC, /* missing association */ }; typedef enum moo_synerrnum_t moo_synerrnum_t;