started the first step to implement array expression support enclosed in #{ }.

added 2 new byte codes - MAKE_ARRAY, POP_INTO_ARRAY for implementation
This commit is contained in:
hyunghwan.chung 2017-02-05 13:54:52 +00:00
parent 98b6dd1118
commit eb83c8d83a
9 changed files with 212 additions and 40 deletions

View File

@ -192,14 +192,15 @@ class MyObject(Object)
a dump.
}.
a dump.
a := 5.
do {
a := do {
('in loop.....' & a asString) dump.
##if (a > 5) { break }.
a := a + 1.
} while(a < 10).
} while (false).
do {
a := do {
('in loop.....' & a asString) dump.
##if (a > 5) { break }.
a := a + 1.
} while(a < 10).
} while (false).
a dump.
## these should be elimited by the compiler.
@ -213,6 +214,24 @@ class MyObject(Object)
nil.
## end of elimination.
a :=999.
a := #{
1,
2,
a,
4,
1 + 1,
2 + 2
}.
a do: [ :v | v dump].
(*
## how to handle return inside 'if' like the following???
## what happens to the stack?
a := if ((k := 20) == 10) {99} else { 100}.
k dump.
a dump.
*)
'---------- END ------------' dump.
##Processor sleepFor: 20.
}

View File

@ -90,6 +90,7 @@ class MyObject(Object)
'too many block temporaries'
'too many block arguments'
'too large block'
'too large array expression'
'wrong primitive function number'
'wrong primitive function identifier'
'wrong module name'

View File

@ -40,6 +40,8 @@
#define NAMESPACE_SIZE 128 /* TODO: choose the right size */
#define POOL_DICTIONARY_SIZE_ALIGN 128
#define INVALID_IP MOO_TYPE_MAX(moo_oow_t)
enum class_mod_t
{
CLASS_INDEXED = (1 << 0)
@ -957,7 +959,10 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
if (moo->c->in_array && is_leadidentchar(c))
{
/* when reading an array literal, read as many characters as
* would compose a normal keyword symbol literal */
* would compose a normal keyword symbol literal.
* for example, in #(a #b:c: x:y:) x:y: is not preceded
* by #. in an array literal, it should still be treated as
* a symbol. */
do
{
ADD_TOKEN_CHAR (moo, c);
@ -1564,9 +1569,9 @@ retry:
return -1;
case '(':
/* #( */
/* #( - array literal */
ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_ARPAREN);
SET_TOKEN_TYPE (moo, MOO_IOTOK_APAREN);
break;
case '[':
@ -1575,6 +1580,12 @@ retry:
SET_TOKEN_TYPE (moo, MOO_IOTOK_BAPAREN);
break;
case '{':
/* #{ - array expression */
ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_ABRACE);
break;
case '\'':
/* quoted symbol literal */
GET_CHAR (moo);
@ -1999,10 +2010,13 @@ 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_ARRAY:
case BCODE_POP_INTO_ARRAY:
bc = cmd;
goto write_long;
}
MOO_DEBUG1 (moo, "Invalid single param instruction opcode %d\n", (int)cmd);
moo->errnum = MOO_EINVAL;
return -1;
@ -2059,6 +2073,7 @@ static int emit_double_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1
goto write_long;
}
MOO_DEBUG1 (moo, "Invalid double param instruction opcode %d\n", (int)cmd);
moo->errnum = MOO_EINVAL;
return -1;
@ -3798,6 +3813,7 @@ static int __read_array_literal (moo_t* moo, moo_oop_t* xlit)
lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1);
break;
/*
case MOO_IOTOK_IDENT:
case MOO_IOTOK_IDENT_DOTTED:
case MOO_IOTOK_BINSEL:
@ -3806,8 +3822,38 @@ static int __read_array_literal (moo_t* moo, moo_oop_t* xlit)
case MOO_IOTOK_SUPER:
case MOO_IOTOK_THIS_CONTEXT:
case MOO_IOTOK_THIS_PROCESS:
case MOO_IOTOK_DO:
case MOO_IOTOK_WHILE:
case MOO_IOTOK_BREAK:
case MOO_IOTOK_CONTINUE:
case MOO_IOTOK_IF:
case MOO_IOTOK_ELSE:
case MOO_IOTOK_ELSIF:
lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo));
break;
*/
/*
a := #(1 2 3 self 5)
a := #(1 2 3 #(1 2 3) self)
a := #(1, 2, 3, self, 5) <---- is array constant? is array non constant?
if array constant contains a comma, produce MAKE_ARRAY
if array literal contains no comma, it's just a literal array.
what to do with a single element array? no problem if the element is still a literal.
should i allow expression or something like that here???
#(( abc ))
#(1, 2)
*
make array 10.
push 10
put array at 1.
push 20
put array at 2
if index is too large, switch to at:put? (or don't care as it's too large???).
*/
case MOO_IOTOK_NIL:
lit = moo->_nil;
@ -3821,16 +3867,16 @@ static int __read_array_literal (moo_t* moo, moo_oop_t* xlit)
lit = moo->_false;
break;
case MOO_IOTOK_ERROR:
case MOO_IOTOK_ERROR: /* error */
lit = MOO_ERROR_TO_OOP(MOO_EGENERIC);
break;
case MOO_IOTOK_ERRLIT:
case MOO_IOTOK_ERRLIT: /* error(X) */
lit = string_to_error (moo, TOKEN_NAME(moo));
break;
case MOO_IOTOK_ARPAREN: /* #( */
case MOO_IOTOK_LPAREN: /* ( */
case MOO_IOTOK_APAREN: /* #( */
/*case MOO_IOTOK_LPAREN:*/ /* ( */
saved_arlit_count = moo->c->mth.arlit_count;
/* TODO: get rid of recursion?? */
GET_TOKEN (moo);
@ -3839,7 +3885,7 @@ static int __read_array_literal (moo_t* moo, moo_oop_t* xlit)
break;
case MOO_IOTOK_BAPAREN: /* #[ */
case MOO_IOTOK_LBRACK: /* [ */
/*case MOO_IOTOK_LBRACK:*/ /* [ */
GET_TOKEN (moo);
if (__read_byte_array_literal (moo, &lit) <= -1) return -1;
break;
@ -3928,6 +3974,63 @@ static int compile_array_literal (moo_t* moo)
return 0;
}
static int compile_array_expression (moo_t* moo)
{
moo_oow_t maip;
moo_ioloc_t aeloc;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_ABRACE);
maip = moo->c->mth.code.len;
if (emit_single_param_instruction(moo, BCODE_MAKE_ARRAY, 0) <= -1) return -1;
aeloc = *TOKEN_LOC(moo);
GET_TOKEN (moo); /* read a token after #{ */
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
{
moo_oow_t index;
index = 0;
do
{
/* TODO: check if index exceeds the index that the BCODE_POP_INTO_ARRAY and BCODE_MAKE_ARRAY can support */
if (compile_method_expression (moo, 0) <= -1) return -1;
if (emit_single_param_instruction (moo, BCODE_POP_INTO_ARRAY, index) <= -1) return -1;
index++;
if (index > MAX_CODE_PARAM)
{
set_syntax_error (moo, MOO_SYNERR_ARREXPFLOOD, &aeloc, MOO_NULL);
return -1;
}
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
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);
}
while (1);
/* TODO: devise a double_param MAKE_ARRAY to increase the number of elementes supported... */
/* patch the MAKE_ARRAY instruction */
#if (MOO_BCODE_LONG_PARAM_SIZE == 2)
moo->c->mth.code.ptr[maip + 1] = index >> 8;
moo->c->mth.code.ptr[maip + 2] = index & 0xFF;
#else
moo->c->mth.code.ptr[maip + 1] = index;
#endif
}
GET_TOKEN (moo); /* read a token after } */
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)
{
/*
@ -4121,12 +4224,14 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
if (compile_byte_array_literal(moo) <= -1) return -1;
break;
case MOO_IOTOK_ARPAREN: /* #( */
case MOO_IOTOK_APAREN: /* #( */
/*GET_TOKEN (moo);*/
if (compile_array_literal(moo) <= -1) return -1;
break;
/* TODO: dynamic array, non constant array #<> or #{} or what is a better bracket? */
case MOO_IOTOK_ABRACE: /* #{ */
if (compile_array_expression(moo) <= -1) return -1;
break;
case MOO_IOTOK_LBRACK: /* [ */
{
@ -4520,7 +4625,11 @@ static int compile_conditional (moo_t* moo)
}
GET_TOKEN (moo);
/* a weird expression like this is also allowed for the call to compile_method_expression()
* if (if (a == 10) { ^20 }) { ^40 }. */
if (compile_method_expression(moo, 0) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
{
set_syntax_error (moo, MOO_SYNERR_LPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo));
@ -4530,8 +4639,6 @@ static int compile_conditional (moo_t* moo)
return 0;
}
#define INVALID_IP MOO_TYPE_MAX(moo_oow_t)
static int compile_if_expression (moo_t* moo)
{
moo_oow_pool_t jumptoend;
@ -4876,9 +4983,11 @@ oops:
static int compile_method_expression (moo_t* moo, int pop)
{
/*
* method-expression := method-assignment-expression | basic-expression | if-expression
* method-expression := method-assignment-expression | basic-expression | if-expression | while-expression | do-while-expression
* method-assignment-expression := identifier ":=" method-expression
* if-expression := if ( ) { } elsif { } else { }
* while-expression := while () {}
* do-while-expression := do { } while ()
*/
moo_oocs_t assignee;
@ -6144,11 +6253,11 @@ static int __compile_pooldic_definition (moo_t* moo)
if (!lit) return -1;
goto add_literal;
case MOO_IOTOK_BAPAREN: /* #[ - byte array parenthesis */
case MOO_IOTOK_BAPAREN: /* #[ - byte array literal parenthesis */
if (read_byte_array_literal(moo, &lit) <= -1) return -1;
goto add_literal;
case MOO_IOTOK_ARPAREN: /* #( - array parenthesis */
case MOO_IOTOK_APAREN: /* #( - array literal parenthesis */
if (read_array_literal(moo, &lit) <= -1) return -1;
goto add_literal;

View File

@ -488,6 +488,16 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
break;
/* -------------------------------------------------------- */
case BCODE_MAKE_ARRAY:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "make_array %zu", b1);
break;
case BCODE_POP_INTO_ARRAY:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "pop_into_array %zu", b1);
break;
case BCODE_DUP_STACKTOP:
LOG_INST_0 (moo, "dup_stacktop");
break;

View File

@ -116,17 +116,18 @@ static moo_ooch_t synerrstr_44[] = {'t','o','o',' ','m','a','n','y',' ','a','r',
static moo_ooch_t synerrstr_45[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_46[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_47[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_48[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_49[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_50[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_51[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_52[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_53[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_54[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_55[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_56[] = {'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',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_58[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_48[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
static moo_ooch_t synerrstr_49[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_50[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_51[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_52[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_53[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_54[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_55[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_56[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\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_59[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t* synerrstr[] =
{
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
@ -136,7 +137,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_56, synerrstr_57, synerrstr_58, synerrstr_59
};
#endif
/* END: GENERATED WITH generr.st */

View File

@ -3795,6 +3795,35 @@ int moo_execute (moo_t* moo)
break;
/* -------------------------------------------------------- */
case BCODE_MAKE_ARRAY:
{
moo_oop_t t;
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "make_array %zu", b1);
/* create an empty array */
t = moo_instantiate (moo, moo->_array, MOO_NULL, b1);
if (!t) goto oops;
MOO_STACK_PUSH (moo, t); /* push the array created */
break;
}
case BCODE_POP_INTO_ARRAY:
{
moo_oop_t t1, t2;
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "pop_into_array %zu", b1);
t1 = MOO_STACK_GETTOP(moo);
MOO_STACK_POP (moo);
t2 = MOO_STACK_GETTOP(moo);
((moo_oop_oop_t)t2)->slot[b1] = t1;
break;
}
case BCODE_DUP_STACKTOP:
{
moo_oop_t t;
@ -3951,7 +3980,7 @@ int moo_execute (moo_t* moo)
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_ERROR, "Error - cannot return from dead context\n");
moo->errnum = MOO_EINTERN; /* TODO: can i make this error catchable at the moo level? */
return -1;
goto oops;
non_local_return_ok:
/*MOO_DEBUG2 (moo, "NON_LOCAL RETURN OK TO... %p %p\n", moo->active_context->origin, moo->active_context->origin->sender);*/
@ -3988,7 +4017,7 @@ int moo_execute (moo_t* moo)
MOO_STACK_PUSH (moo, (moo_oop_t)unwind_stop);
MOO_STACK_PUSH (moo, (moo_oop_t)return_value);
if (send_private_message (moo, fbm, 16, 0, 2) <= -1) return -1;
if (send_private_message (moo, fbm, 16, 0, 2) <= -1) goto oops;
}
else
{
@ -4081,7 +4110,7 @@ int moo_execute (moo_t* moo)
* this base block context is created with no stack for
* this reason */
blkctx = (moo_oop_context_t)moo_instantiate (moo, moo->_block_context, MOO_NULL, 0);
if (!blkctx) return -1;
if (!blkctx) goto oops;
/* the long forward jump instruction has the format of
* 11000100 KKKKKKKK or 11000100 KKKKKKKK KKKKKKKK
@ -4138,7 +4167,7 @@ int moo_execute (moo_t* moo)
* this base block context is created with no
* stack for this reason. */
blkctx = (moo_oop_context_t)moo_instantiate (moo, moo->_block_context, MOO_NULL, 0);
if (!blkctx) return -1;
if (!blkctx) goto oops;
/* get the receiver to the block copy message after block context instantiation
* not to get affected by potential GC */

View File

@ -159,7 +159,6 @@ static MOO_INLINE moo_ooi_t open_input (moo_t* moo, moo_ioarg_t* arg)
xtn_t* xtn = moo_getxtn(moo);
bb_t* bb = MOO_NULL;
/* TOOD: support predefined include directory as well */
if (arg->includer)
{

View File

@ -323,8 +323,9 @@ struct moo_iotok_t
MOO_IOTOK_RBRACK,
MOO_IOTOK_LPAREN,
MOO_IOTOK_RPAREN,
MOO_IOTOK_ARPAREN, /* #( */
MOO_IOTOK_APAREN, /* #( */
MOO_IOTOK_BAPAREN, /* #[ */
MOO_IOTOK_ABRACE, /* #{ */
MOO_IOTOK_PERIOD,
MOO_IOTOK_COMMA,
MOO_IOTOK_SEMICOLON,
@ -862,6 +863,8 @@ enum moo_bcode_t
/* -------------------------------------- */
BCODE_MAKE_ARRAY = 0xF5, /* 245 */
BCODE_POP_INTO_ARRAY = 0xF6, /* 246 */
BCODE_DUP_STACKTOP = 0xF7,
BCODE_POP_STACKTOP = 0xF8,
BCODE_RETURN_STACKTOP = 0xF9, /* ^something */

View File

@ -1139,6 +1139,7 @@ enum moo_synerrnum_t
MOO_SYNERR_BLKTMPRFLOOD, /* too many block temporaries */
MOO_SYNERR_BLKARGFLOOD, /* too many block arguments */
MOO_SYNERR_BLKFLOOD, /* too large block */
MOO_SYNERR_ARREXPFLOOD, /* too large array expression */
MOO_SYNERR_PFNUM, /* wrong primitive number */
MOO_SYNERR_PFID, /* wrong primitive identifier */
MOO_SYNERR_MODNAME, /* wrong module name */