wrote code to handle dictionary expression and association expression notation
This commit is contained in:
parent
62eb6db83d
commit
5c07a48c5a
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
*)
|
||||||
|
@ -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'.
|
||||||
|
126
moo/lib/comp.c
126
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_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;
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
@ -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 ||
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user