wrote code to handle dictionary expression and association expression notation

This commit is contained in:
hyunghwan.chung 2017-02-07 17:40:34 +00:00
parent 62eb6db83d
commit 5c07a48c5a
11 changed files with 313 additions and 36 deletions

View File

@ -146,6 +146,26 @@ class Set(Collection)
^self.tally ^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 method __find: key or_upsert: upsert with: value
{ {
| hv ass bs index ntally | | hv ass bs index ntally |
@ -164,28 +184,17 @@ class Set(Collection)
index := (index + 1) rem: bs. index := (index + 1) rem: bs.
]. ].
upsert ifFalse: [^ErrorCode.NOENT]. ##upsert ifFalse: [^ErrorCode.NOENT].
if (upsert) {} else { ^ErrorCode.NOENT }.
ntally := self.tally + 1. ntally := self.tally + 1.
(ntally >= bs) ifTrue: [ if (ntally >= bs)
| newbuc newsz | {
(* expand the bucket *) self.bucket := self __make_expanded_bucket: bs.
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.
bs := self.bucket size. bs := self.bucket size.
index := hv rem: bs. index := hv rem: bs.
[(self.bucket at: index) notNil] whileTrue: [index := (index + 1) rem: bs ]. [(self.bucket at: index) notNil] whileTrue: [index := (index + 1) rem: bs ].
]. }.
ass := Association key: key value: value. ass := Association key: key value: value.
self.tally := ntally. self.tally := ntally.
@ -194,6 +203,46 @@ class Set(Collection)
^ass ^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 method at: key
{ {
| ass | | ass |
@ -210,15 +259,15 @@ class Set(Collection)
^ass value ^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 |
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 isError) ifTrue: [^error_block value].
^ass ^ass
} }

View File

@ -268,9 +268,15 @@ class MyObject(Object)
##Processor sleepFor: 20. ##Processor sleepFor: 20.
} }
method(#class) main method(#class) main
{ {
|a|
a := 100.
## PROBLEM: the following double loop will exhaust the stack ## PROBLEM: the following double loop will exhaust the stack
(*
while (true) while (true)
{ {
##111 dump. ##111 dump.
@ -282,7 +288,39 @@ class MyObject(Object)
##[:j :q | (j + q) dump] value: 10 value: 20. ##[:j :q | (j + q) dump] value: 10 value: 20.
##if (false) {} else { break }. ##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
}
*)

View File

@ -102,6 +102,9 @@ class MyObject(Object)
'break or continue not within a loop' 'break or continue not within a loop'
'break or continue within a block' 'break or continue within a block'
'while expected' 'while expected'
'missing association key'
'missing association value'
'missing association'
). ).
f := Stdio open: 'generr.out' for: 'w'. f := Stdio open: 'generr.out' for: 'w'.

View File

@ -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_INTLIT:
case BCODE_PUSH_NEGINTLIT: case BCODE_PUSH_NEGINTLIT:
case BCODE_PUSH_CHARLIT: case BCODE_PUSH_CHARLIT:
case BCODE_MAKE_DICTIONARY:
case BCODE_MAKE_ARRAY: case BCODE_MAKE_ARRAY:
case BCODE_POP_INTO_ARRAY: case BCODE_POP_INTO_ARRAY:
bc = cmd; bc = cmd;
@ -4059,13 +4060,128 @@ static int compile_array_expression (moo_t* moo)
#else #else
moo->c->mth.code.ptr[maip + 1] = index; moo->c->mth.code.ptr[maip + 1] = index;
#endif #endif
} }
GET_TOKEN (moo); /* read a token after } */ GET_TOKEN (moo); /* read a token after } */
return 0; 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) 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; if (compile_array_expression(moo) <= -1) return -1;
break; 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: /* [ */ case MOO_IOTOK_LBRACK: /* [ */
{ {
int n; int n;

View File

@ -488,6 +488,15 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
break; 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: case BCODE_MAKE_ASSOCIATION:
LOG_INST_0 (moo, "make_association"); LOG_INST_0 (moo, "make_association");
break; break;

View File

@ -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_oop_association_t ass;
moo_oow_t tmp_count = 0; moo_oow_t tmp_count = 0;
/* the system dictionary is not a generic dictionary. /* the builtin dictionary is not a generic dictionary.
* it accepts only a symbol as a key. */ * it accepts only a symbol or something similar as a 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));
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer); MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer);
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array); 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]; 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) == 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))) 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. */ /* 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]; 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) == 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) && if (name->len == MOO_OBJ_GET_SIZE(ass->key) &&
moo_equaloochars(name->ptr, ((moo_oop_char_t)ass->key)->slot, name->len)) 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_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); 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_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); 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]; 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) == 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) && if (name->len == MOO_OBJ_GET_SIZE(ass->key) &&
moo_equaloochars(name->ptr, ((moo_oop_char_t)ass->key)->slot, name->len)) moo_equaloochars(name->ptr, ((moo_oop_char_t)ass->key)->slot, name->len))

View File

@ -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_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_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_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[] = static moo_ooch_t* synerrstr[] =
{ {
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, 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_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_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_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 #endif
/* END: GENERATED WITH generr.st */ /* END: GENERATED WITH generr.st */

View File

@ -3715,7 +3715,6 @@ int moo_execute (moo_t* moo)
selector = (moo_oop_char_t)moo->active_method->slot[b2]; 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); 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; if (send_message (moo, selector, ((bcode >> 2) & 1), b1) <= -1) goto oops;
break; /* CMD_SEND_MESSAGE */ break; /* CMD_SEND_MESSAGE */
} }
@ -3795,6 +3794,34 @@ int moo_execute (moo_t* moo)
break; 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: case BCODE_MAKE_ASSOCIATION:
{ {
moo_oop_t t; moo_oop_t t;

View File

@ -91,6 +91,7 @@ static kernel_class_info_t kernel_classes[] =
{ 5, { 'A','r','r','a','y' }, MOO_OFFSETOF(moo_t,_array) }, { 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, { '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) }, { 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) }, { 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) }, { 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->_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->_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->_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->_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)); 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->_object || !moo->_string ||
!moo->_symbol || !moo->_array || !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->_namespace || !moo->_pool_dictionary ||
!moo->_method_dictionary || !moo->_method || !moo->_association || !moo->_method_dictionary || !moo->_method || !moo->_association ||

View File

@ -860,6 +860,11 @@ enum moo_bcode_t
BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 ## */ BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 ## */
BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 ## */ 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_SEND_MESSAGE_X = 0xF0, /* 240 ## */
BCODE_MAKE_ASSOCIATION = 0xF1, /* 241 */ BCODE_MAKE_ASSOCIATION = 0xF1, /* 241 */
BCODE_POP_INTO_ASSOCIATION_KEY = 0xF2, /* 242 */ BCODE_POP_INTO_ASSOCIATION_KEY = 0xF2, /* 242 */

View File

@ -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 */ /* [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_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. /* [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 * make sure that the value of each bit fields given falls within the
* possible range of the defined bits */ * possible range of the defined bits */
@ -900,6 +905,7 @@ struct moo_t
moo_oop_t _array; /* Array */ moo_oop_t _array; /* Array */
moo_oop_t _byte_array; /* ByteArray */ moo_oop_t _byte_array; /* ByteArray */
moo_oop_t _symbol_set; /* SymbolSet */ moo_oop_t _symbol_set; /* SymbolSet */
moo_oop_t _dictionary;
moo_oop_t _system_dictionary; /* SystemDictionary */ moo_oop_t _system_dictionary; /* SystemDictionary */
moo_oop_t _namespace; /* Namespace */ moo_oop_t _namespace; /* Namespace */
@ -1150,7 +1156,10 @@ enum moo_synerrnum_t
MOO_SYNERR_LITERAL, /* literal expected */ MOO_SYNERR_LITERAL, /* literal expected */
MOO_SYNERR_NOTINLOOP, /* break or continue not within a loop */ MOO_SYNERR_NOTINLOOP, /* break or continue not within a loop */
MOO_SYNERR_INBLOCK, /* break or continue within a block */ 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; typedef enum moo_synerrnum_t moo_synerrnum_t;