added primitive code to compile the 'if' expression

This commit is contained in:
hyunghwan.chung 2017-01-18 17:17:05 +00:00
parent 4a4d40dea1
commit 40ba50fc53
7 changed files with 386 additions and 90 deletions

View File

@ -408,7 +408,14 @@ pooldic ErrorCode
(* migrate it into Error class *) (* migrate it into Error class *)
#NONE := error(0). #NONE := error(0).
#GENERIC := error(1). #GENERIC := error(1).
#NOENT := error(2). #NOIMPL := error(2).
#SYSERR := error(3).
#INTERN := error(4).
#SYSMEM := error(5).
#OOMEM := error(6).
#INVAL := error(7).
#NOENT := error(8).
(* add more items... *)
} }
class Error(Apex) class Error(Apex)

View File

@ -39,7 +39,7 @@ dcl obj.
class MyObject(Object) class MyObject(Object)
{ {
method(#class) main method(#class) mainxx
{ {
| d a ffi | | d a ffi |
@ -85,6 +85,7 @@ class MyObject(Object)
] on: Exception do: [:ex | ('Exception caught - ' & ex asString) dump ].*) ] on: Exception do: [:ex | ('Exception caught - ' & ex asString) dump ].*)
ffi := FFI new: '/lib64/libc.so.6'. ffi := FFI new: '/lib64/libc.so.6'.
(*
(ffi isError) (ffi isError)
ifTrue: [System logNl: 'cannot open libc.so' ] ifTrue: [System logNl: 'cannot open libc.so' ]
ifFalse: [ ifFalse: [
@ -92,6 +93,51 @@ class MyObject(Object)
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'fly away')) dump. (ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'fly away')) dump.
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'jump down')) dump. (ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'jump down')) dump.
ffi close. ffi close.
] ].
*)
if (ffi isError)
{
System logNl: 'cannot open libc.so'
}
else
{
(ffi call: #getpid signature: ')i' arguments: nil) dump.
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'fly away')) dump.
(ffi call: #printf signature: 's|iis)i' arguments: #(S'A=>%d B=>%d Hello, world %s\n' 1 2 'jump down')) dump.
ffi close.
}.
(('abcd' == 'abcd') ifTrue: [1] ifFalse: [2]) dump.
}
method(#class) main
{
|a k|
a :=
if ([System logNl: 'xxxx'. 'abcd' == 'bcde'. false] value)
{
System logNl: 'XXXXXXXXX'.
1111
}
elsif ('abcd' ~= 'abcd')
{
System logNl: 'second if'.
}
elsif ([k := 20. System logNl: 'k => ' & (k asString). k + 20. true] value)
{
System logNl: 'THIRID forever.............' & (k asString)
}
elsif (true = true)
{
System logNl: 'forever.............'
}
else
{
System logNl: 'NO MATCH'.
[true] value.
}.
a dump.
System logNl: 'DONE DONE DONE...'.
} }
} }

View File

@ -81,6 +81,8 @@ static struct voca_t
{ 10, { '#','c','l','a','s','s','i','n','s','t' } }, { 10, { '#','c','l','a','s','s','i','n','s','t' } },
{ 3, { 'd','c','l' } }, { 3, { 'd','c','l' } },
{ 7, { 'd','e','c','l','a','r','e' } }, { 7, { 'd','e','c','l','a','r','e' } },
{ 4, { 'e','l','s','e' } },
{ 5, { 'e','l','s','i','f' } },
{ 6, { 'e','n','s','u','r','e', } }, { 6, { 'e','n','s','u','r','e', } },
{ 5, { 'e','r','r','o','r' } }, { 5, { 'e','r','r','o','r' } },
{ 9, { 'e','x','c','e','p','t','i','o','n' } }, { 9, { 'e','x','c','e','p','t','i','o','n' } },
@ -120,6 +122,8 @@ enum voca_id_t
VOCA_CLASSINST_S, VOCA_CLASSINST_S,
VOCA_DCL, VOCA_DCL,
VOCA_DECLARE, VOCA_DECLARE,
VOCA_ELSE,
VOCA_ELSIF,
VOCA_ENSURE, VOCA_ENSURE,
VOCA_ERROR, VOCA_ERROR,
VOCA_EXCEPTION, VOCA_EXCEPTION,
@ -986,6 +990,14 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_IF); SET_TOKEN_TYPE (moo, MOO_IOTOK_IF);
} }
else if (is_token_word(moo, VOCA_ELSE))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSE);
}
else if (is_token_word(moo, VOCA_ELSIF))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSIF);
}
} }
return 0; return 0;
@ -1867,8 +1879,8 @@ static int emit_single_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1
case BCODE_POP_INTO_OBJECT_0: case BCODE_POP_INTO_OBJECT_0:
case BCODE_JUMP_FORWARD_0: case BCODE_JUMP_FORWARD_0:
case BCODE_JUMP_BACKWARD_0: case BCODE_JUMP_BACKWARD_0:
case BCODE_JUMP_IF_TRUE_0: case BCODE_JUMP_FORWARD_IF_FALSE_0:
case BCODE_JUMP_IF_FALSE_0: case BCODE_JUMP_BACKWARD_IF_FALSE_0:
if (param_1 < 4) if (param_1 < 4)
{ {
/* low 2 bits to hold the parameter */ /* low 2 bits to hold the parameter */
@ -3257,12 +3269,49 @@ static int store_tmpr_count_for_block (moo_t* moo, moo_oow_t tmpr_count)
return 0; return 0;
} }
static int patch_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oob_t jump2_inst, moo_ioloc_t* errloc)
{
moo_oow_t code_size;
moo_oow_t jump_offset;
/* MOO_BCODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */
code_size = moo->c->mth.code.len - jip - (MOO_BCODE_LONG_PARAM_SIZE + 1);
if (code_size > MAX_CODE_JUMP * 2)
{
/* TODO: accept the location and pass it to set_syntax_error.
* change error code or get it as a parameter */
set_syntax_error (moo, MOO_SYNERR_BLKFLOOD, errloc, MOO_NULL);
return -1;
}
if (code_size > MAX_CODE_JUMP)
{
/* switch to JUMP2 instruction to allow a bigger jump offset.
* up to twice MAX_CODE_JUMP only */
moo->c->mth.code.ptr[jip] = jump2_inst;
jump_offset = code_size - MAX_CODE_JUMP;
}
else
{
jump_offset = code_size;
}
#if (MOO_BCODE_LONG_PARAM_SIZE == 2)
moo->c->mth.code.ptr[jip + 1] = jump_offset >> 8;
moo->c->mth.code.ptr[jip + 2] = jump_offset & 0xFF;
#else
moo->c->mth.code.ptr[jip + 1] = jump_offset;
#endif
return 0;
}
static int compile_block_expression (moo_t* moo) static int compile_block_expression (moo_t* moo)
{ {
moo_oow_t jump_inst_pos; moo_oow_t jump_inst_pos;
moo_oow_t saved_tmpr_count, saved_tmprs_len; moo_oow_t saved_tmpr_count, saved_tmprs_len;
moo_oow_t block_arg_count, block_tmpr_count; moo_oow_t block_arg_count, block_tmpr_count;
moo_oow_t block_code_size;
moo_ioloc_t block_loc, colon_loc, tmpr_loc; moo_ioloc_t block_loc, colon_loc, tmpr_loc;
/* /*
@ -3273,7 +3322,7 @@ static int compile_block_expression (moo_t* moo)
/* this function expects [ not to be consumed away */ /* this function expects [ not to be consumed away */
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_LBRACK); MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_LBRACK);
block_loc = moo->c->tok.loc; block_loc = *TOKEN_LOC(moo);
GET_TOKEN (moo); GET_TOKEN (moo);
saved_tmprs_len = moo->c->mth.tmprs.len; saved_tmprs_len = moo->c->mth.tmprs.len;
@ -3397,6 +3446,8 @@ static int compile_block_expression (moo_t* moo)
if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK) <= -1) return -1; if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
if (patch_jump_instruction (moo, jump_inst_pos, BCODE_JUMP2_FORWARD, &block_loc) <= -1) return -1;
#if 0
/* MOO_BCODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ /* MOO_BCODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */
block_code_size = moo->c->mth.code.len - jump_inst_pos - (MOO_BCODE_LONG_PARAM_SIZE + 1); block_code_size = moo->c->mth.code.len - jump_inst_pos - (MOO_BCODE_LONG_PARAM_SIZE + 1);
if (block_code_size > MAX_CODE_JUMP * 2) if (block_code_size > MAX_CODE_JUMP * 2)
@ -3427,6 +3478,7 @@ static int compile_block_expression (moo_t* moo)
moo->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset; moo->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset;
#endif #endif
} }
#endif
/* restore the temporary count */ /* restore the temporary count */
moo->c->mth.tmprs.len = saved_tmprs_len; moo->c->mth.tmprs.len = saved_tmprs_len;
@ -4224,12 +4276,147 @@ static int compile_basic_expression (moo_t* moo, const moo_oocs_t* ident, const
return 0; return 0;
} }
static int compile_braced_block (moo_t* moo)
{
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)
{
set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo);
while (TOKEN_TYPE(moo) != MOO_IOTOK_EOF)
{
if (compile_block_statement(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
{
GET_TOKEN (moo);
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP) <= -1) return -1;
}
else
{
set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
}
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
{
set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
return 0;
}
static int compile_conditional (moo_t* moo)
{
if (TOKEN_TYPE(moo) != MOO_IOTOK_LPAREN)
{
set_syntax_error (moo, MOO_SYNERR_LPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo);
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));
return -1;
}
return 0;
}
static int compile_if_expression (moo_t* moo)
{
moo_oow_t jumptoend[100];
moo_oow_t jumptoend_count = 0;
moo_oow_t i;
moo_oow_t jumptonext;
moo_ioloc_t if_loc, brace_loc;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF);
if_loc = *TOKEN_LOC(moo);
/* TODO: simple optimization to check if the conditional is true or false */
GET_TOKEN (moo); /* get ( */
if (compile_conditional (moo) <= -1) return -1;
/* insert dummy instructions before replacing them with a jump instruction */
jumptonext = moo->c->mth.code.len;
/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to
* produce the long jump instruction (BCODE_JUMP_FORWARD_X) */
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) return -1;
GET_TOKEN (moo); /* get { */
brace_loc = *TOKEN_LOC(moo);
if (compile_braced_block (moo) <= -1) return -1;
/* emit code to jump to the end */
jumptoend[jumptoend_count++] = moo->c->mth.code.len;
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1;
GET_TOKEN (moo);
while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF)
{
if (patch_jump_instruction (moo, jumptonext, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) return -1;
GET_TOKEN (moo);
if (compile_conditional(moo) <= -1) return -1;
/* emit code to jump to the next elsif or else */
jumptonext = moo->c->mth.code.len;
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) return -1;
GET_TOKEN (moo); /* get { */
brace_loc = *TOKEN_LOC(moo);
if (compile_braced_block(moo) <= -1) return -1;
/* emit code to jump to the end */
jumptoend[jumptoend_count++] = moo->c->mth.code.len;
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1;
GET_TOKEN (moo);
}
if (patch_jump_instruction (moo, jumptonext, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) return -1;
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
{
GET_TOKEN (moo);
if (compile_braced_block (moo) <= -1) return -1;
GET_TOKEN (moo);
}
else
{
/* emit code to push nil if no 'else' part exists */
if (emit_byte_instruction (moo, BCODE_PUSH_NIL) <= -1) return -1;
}
/* patch instructions that jumps to the end of if expression */
for (i = 0; i < jumptoend_count; i++)
{
/* pass if_loc to every call to patch_jump_instruction().
* it's harmless because if the first call doesn't flood, the subseqent
* call will never flood either. */
if (patch_jump_instruction (moo, jumptoend[i], BCODE_JUMP2_FORWARD_IF_FALSE, &if_loc) <= -1) return -1;
}
return 0;
}
static int compile_method_expression (moo_t* moo, int pop) 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
* method-assignment-expression := identifier ":=" method-expression * method-assignment-expression := identifier ":=" method-expression
* if-expression := if ( ) { } else { }. * if-expression := if ( ) { } elsif { } else { }
*/ */
moo_oocs_t assignee; moo_oocs_t assignee;
@ -4241,7 +4428,7 @@ static int compile_method_expression (moo_t* moo, int pop)
if (TOKEN_TYPE(moo) == MOO_IOTOK_IF) if (TOKEN_TYPE(moo) == MOO_IOTOK_IF)
{ {
/* TODO: ... */ if (compile_if_expression (moo) <= -1) return -1;
} }
else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT || else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT ||
TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
@ -4396,7 +4583,10 @@ static int compile_method_statement (moo_t* moo)
* that the stack top will eventually be popped off. the compiler * that the stack top will eventually be popped off. the compiler
* can optimize some instruction sequencese. for example, two * can optimize some instruction sequencese. for example, two
* consecutive store and pop intructions can be transformed to * consecutive store and pop intructions can be transformed to
* a more specialized single pop-and-store instruction. */ * a more specialized single pop-and-store instruction.
* the compile_method_expression() function emits POP_INTO_XXX
* instructions if the second parameter is 1 whenever possible and
* STORE_INTO_XXX if it's 0.*/
n = compile_method_expression(moo, 1); n = compile_method_expression(moo, 1);
if (n <= -1) return -1; if (n <= -1) return -1;

View File

@ -247,7 +247,6 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
case BCODE_JUMP_BACKWARD_X: case BCODE_JUMP_BACKWARD_X:
FETCH_PARAM_CODE_TO (moo, b1); FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump_backward %zu", b1); LOG_INST_1 (moo, "jump_backward %zu", b1);
moo->ip += b1;
break; break;
case BCODE_JUMP_BACKWARD_0: case BCODE_JUMP_BACKWARD_0:
@ -257,19 +256,29 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
LOG_INST_1 (moo, "jump_backward %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */ LOG_INST_1 (moo, "jump_backward %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
break; break;
case BCODE_JUMP_IF_TRUE_X: case BCODE_JUMP_FORWARD_IF_FALSE_X:
case BCODE_JUMP_IF_FALSE_X: FETCH_PARAM_CODE_TO (moo, b1);
case BCODE_JUMP_IF_TRUE_0: LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
case BCODE_JUMP_IF_TRUE_1: break;
case BCODE_JUMP_IF_TRUE_2:
case BCODE_JUMP_IF_TRUE_3: case BCODE_JUMP_FORWARD_IF_FALSE_0:
case BCODE_JUMP_IF_FALSE_0: case BCODE_JUMP_FORWARD_IF_FALSE_1:
case BCODE_JUMP_IF_FALSE_1: case BCODE_JUMP_FORWARD_IF_FALSE_2:
case BCODE_JUMP_IF_FALSE_2: case BCODE_JUMP_FORWARD_IF_FALSE_3:
case BCODE_JUMP_IF_FALSE_3: LOG_INST_1 (moo, "jump_forward_if_false %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
LOG_INST_0 (moo, "<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>>"); break;
moo->errnum = MOO_ENOIMPL;
return -1; case BCODE_JUMP_BACKWARD_IF_FALSE_X:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump_backward_if_false %zu", b1);
break;
case BCODE_JUMP_BACKWARD_IF_FALSE_0:
case BCODE_JUMP_BACKWARD_IF_FALSE_1:
case BCODE_JUMP_BACKWARD_IF_FALSE_2:
case BCODE_JUMP_BACKWARD_IF_FALSE_3:
LOG_INST_1 (moo, "jump_backward_if_false %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
break;
case BCODE_JUMP2_FORWARD: case BCODE_JUMP2_FORWARD:
FETCH_PARAM_CODE_TO (moo, b1); FETCH_PARAM_CODE_TO (moo, b1);
@ -281,6 +290,15 @@ return -1;
LOG_INST_1 (moo, "jump2_backward %zu", b1); LOG_INST_1 (moo, "jump2_backward %zu", b1);
break; break;
case BCODE_JUMP2_FORWARD_IF_FALSE:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump2_forward_if_false %zu", b1);
break;
case BCODE_JUMP2_BACKWARD_IF_FALSE:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump2_backward_if_false %zu", b1);
break;
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
case BCODE_PUSH_CTXTEMPVAR_X: case BCODE_PUSH_CTXTEMPVAR_X:

View File

@ -3460,7 +3460,7 @@ int moo_execute (moo_t* moo)
case BCODE_JUMP_BACKWARD_X: case BCODE_JUMP_BACKWARD_X:
FETCH_PARAM_CODE_TO (moo, b1); FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump_backward %zu", b1); LOG_INST_1 (moo, "jump_backward %zu", b1);
moo->ip += b1; moo->ip -= b1;
break; break;
case BCODE_JUMP_BACKWARD_0: case BCODE_JUMP_BACKWARD_0:
@ -3471,19 +3471,37 @@ int moo_execute (moo_t* moo)
moo->ip -= (bcode & 0x3); /* low 2 bits */ moo->ip -= (bcode & 0x3); /* low 2 bits */
break; break;
case BCODE_JUMP_IF_TRUE_X: case BCODE_JUMP_FORWARD_IF_FALSE_X:
case BCODE_JUMP_IF_FALSE_X: FETCH_PARAM_CODE_TO (moo, b1);
case BCODE_JUMP_IF_TRUE_0: LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
case BCODE_JUMP_IF_TRUE_1: if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += b1;
case BCODE_JUMP_IF_TRUE_2: MOO_STACK_POP (moo);
case BCODE_JUMP_IF_TRUE_3: break;
case BCODE_JUMP_IF_FALSE_0:
case BCODE_JUMP_IF_FALSE_1: case BCODE_JUMP_FORWARD_IF_FALSE_0:
case BCODE_JUMP_IF_FALSE_2: case BCODE_JUMP_FORWARD_IF_FALSE_1:
case BCODE_JUMP_IF_FALSE_3: case BCODE_JUMP_FORWARD_IF_FALSE_2:
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_FATAL, "<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>>\n"); case BCODE_JUMP_FORWARD_IF_FALSE_3:
moo->errnum = MOO_ENOIMPL; LOG_INST_1 (moo, "jump_forward_if_false %zu", (moo_oow_t)(bcode & 0x3));
return -1; if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += (bcode & 0x3); /* low 2 bits */
MOO_STACK_POP (moo);
break;
case BCODE_JUMP_BACKWARD_IF_FALSE_X:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump_backward_if_false %zu", b1);
if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip -= b1;
MOO_STACK_POP (moo);
break;
case BCODE_JUMP_BACKWARD_IF_FALSE_0:
case BCODE_JUMP_BACKWARD_IF_FALSE_1:
case BCODE_JUMP_BACKWARD_IF_FALSE_2:
case BCODE_JUMP_BACKWARD_IF_FALSE_3:
LOG_INST_1 (moo, "jump_backward_if_false %zu", (moo_oow_t)(bcode & 0x3));
if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip -= (bcode & 0x3); /* low 2 bits */
MOO_STACK_POP (moo);
break;
case BCODE_JUMP2_FORWARD: case BCODE_JUMP2_FORWARD:
FETCH_PARAM_CODE_TO (moo, b1); FETCH_PARAM_CODE_TO (moo, b1);
@ -3497,6 +3515,20 @@ return -1;
moo->ip -= MAX_CODE_JUMP + b1; moo->ip -= MAX_CODE_JUMP + b1;
break; break;
case BCODE_JUMP2_FORWARD_IF_FALSE:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump2_forward_if_false %zu", b1);
if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += MAX_CODE_JUMP + b1;
MOO_STACK_POP (moo);
break;
case BCODE_JUMP2_BACKWARD_IF_FALSE:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "jump2_backward_if_false %zu", b1);
if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip -= MAX_CODE_JUMP + b1;
MOO_STACK_POP (moo);
break;
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
case BCODE_PUSH_CTXTEMPVAR_X: case BCODE_PUSH_CTXTEMPVAR_X:

View File

@ -309,7 +309,6 @@ struct moo_iotok_t
MOO_IOTOK_FALSE, MOO_IOTOK_FALSE,
MOO_IOTOK_THIS_CONTEXT, MOO_IOTOK_THIS_CONTEXT,
MOO_IOTOK_THIS_PROCESS, MOO_IOTOK_THIS_PROCESS,
MOO_IOTOK_IF,
MOO_IOTOK_IDENT, MOO_IOTOK_IDENT,
MOO_IOTOK_IDENT_DOTTED, MOO_IOTOK_IDENT_DOTTED,
MOO_IOTOK_BINSEL, MOO_IOTOK_BINSEL,
@ -327,7 +326,11 @@ struct moo_iotok_t
MOO_IOTOK_BAPAREN, /* #[ */ MOO_IOTOK_BAPAREN, /* #[ */
MOO_IOTOK_PERIOD, MOO_IOTOK_PERIOD,
MOO_IOTOK_COMMA, MOO_IOTOK_COMMA,
MOO_IOTOK_SEMICOLON MOO_IOTOK_SEMICOLON,
MOO_IOTOK_IF,
MOO_IOTOK_ELSE,
MOO_IOTOK_ELSIF
} type; } type;
moo_oocs_t name; moo_oocs_t name;
@ -575,8 +578,8 @@ SHORT INSTRUCTION CODE LONG INSTRUCTION C
68-71 0100 01XX JUMP_FORWARD 196 1100 0100 XXXXXXXX JUMP_FORWARD_X 68-71 0100 01XX JUMP_FORWARD 196 1100 0100 XXXXXXXX JUMP_FORWARD_X
72-75 0100 10XX JUMP_BACKWARD 200 1100 1000 XXXXXXXX JUMP_BACKWARD_X 72-75 0100 10XX JUMP_BACKWARD 200 1100 1000 XXXXXXXX JUMP_BACKWARD_X
76-79 0100 11XX JUMP_IF_TRUE 204 1100 1100 XXXXXXXX JUMP_IF_TRUE_X 76-79 0100 11XX JUMP_BACKWARD_IF_FALSE 204 1100 1100 XXXXXXXX JUMP_BACKWARD_IF_FALSE_X
80-83 0101 00XX JUMP_IF_FALSE 208 1101 0000 XXXXXXXX JUMP_IF_FALSE_X 80-83 0101 00XX JUMP_FORWARD_IF_FALSE 208 1101 0000 XXXXXXXX JUMP_FORWARD_IF_FALSE_X
84-87 0101 01XX UNUSED 84-87 0101 01XX UNUSED
@ -704,15 +707,15 @@ enum moo_bcode_t
BCODE_JUMP_BACKWARD_2 = 0x4A, BCODE_JUMP_BACKWARD_2 = 0x4A,
BCODE_JUMP_BACKWARD_3 = 0x4B, BCODE_JUMP_BACKWARD_3 = 0x4B,
BCODE_JUMP_IF_TRUE_0 = 0x4C, BCODE_JUMP_FORWARD_IF_FALSE_0 = 0x4C, /* 76 */
BCODE_JUMP_IF_TRUE_1 = 0x4D, BCODE_JUMP_FORWARD_IF_FALSE_1 = 0x4D, /* 77 */
BCODE_JUMP_IF_TRUE_2 = 0x4E, BCODE_JUMP_FORWARD_IF_FALSE_2 = 0x4E, /* 78 */
BCODE_JUMP_IF_TRUE_3 = 0x4F, BCODE_JUMP_FORWARD_IF_FALSE_3 = 0x4F, /* 79 */
BCODE_JUMP_IF_FALSE_0 = 0x50, /* 80 */ BCODE_JUMP_BACKWARD_IF_FALSE_0 = 0x50, /* 80 */
BCODE_JUMP_IF_FALSE_1 = 0x51, /* 81 */ BCODE_JUMP_BACKWARD_IF_FALSE_1 = 0x51, /* 81 */
BCODE_JUMP_IF_FALSE_2 = 0x52, /* 82 */ BCODE_JUMP_BACKWARD_IF_FALSE_2 = 0x52, /* 82 */
BCODE_JUMP_IF_FALSE_3 = 0x53, /* 83 */ BCODE_JUMP_BACKWARD_IF_FALSE_3 = 0x53, /* 83 */
BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */ BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */
BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */ BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */
@ -756,41 +759,7 @@ enum moo_bcode_t
/* UNUSED 0x78 - 0x7F */ /* UNUSED 0x78 - 0x7F */
BCODE_STORE_INTO_INSTVAR_X = 0x80, /* 128 */ BCODE_STORE_INTO_INSTVAR_X = 0x80, /* 128 ## */
BCODE_POP_INTO_INSTVAR_X = 0x88, /* 136 */
BCODE_PUSH_INSTVAR_X = 0x90, /* 144 */
BCODE_PUSH_TEMPVAR_X = 0x98, /* 152 */
BCODE_STORE_INTO_TEMPVAR_X = 0xA0, /* 160 */
BCODE_POP_INTO_TEMPVAR_X = 0xA8, /* 168 */
BCODE_PUSH_LITERAL_X = 0xB0, /* 176 */
BCODE_STORE_INTO_OBJECT_X = 0xB8, /* 184 */
BCODE_POP_INTO_OBJECT_X = 0xBC, /* 188 */
BCODE_PUSH_OBJECT_X = 0xC0, /* 192 */
BCODE_JUMP_FORWARD_X = 0xC4, /* 196 */
BCODE_JUMP_BACKWARD_X = 0xC8, /* 200 */
BCODE_JUMP_IF_TRUE_X = 0xCC, /* 204 */
BCODE_JUMP_IF_FALSE_X = 0xD0, /* 208 */
BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */
BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 */
BCODE_PUSH_CTXTEMPVAR_X = 0xE0, /* 224 */
BCODE_PUSH_OBJVAR_X = 0xE4, /* 228 */
BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 */
BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 */
BCODE_SEND_MESSAGE_X = 0xF0, /* 240 */
BCODE_SEND_MESSAGE_TO_SUPER_X = 0xF4, /* 244 */
/* -------------------------------------- */
BCODE_JUMP2_FORWARD = 0xC5, /* 197 */
BCODE_JUMP2_BACKWARD = 0xC9, /* 201 */
BCODE_PUSH_RECEIVER = 0x81, /* 129 */ BCODE_PUSH_RECEIVER = 0x81, /* 129 */
BCODE_PUSH_NIL = 0x82, /* 130 */ BCODE_PUSH_NIL = 0x82, /* 130 */
@ -799,16 +768,50 @@ enum moo_bcode_t
BCODE_PUSH_CONTEXT = 0x85, /* 133 */ BCODE_PUSH_CONTEXT = 0x85, /* 133 */
BCODE_PUSH_PROCESS = 0x86, /* 134 */ BCODE_PUSH_PROCESS = 0x86, /* 134 */
BCODE_PUSH_NEGONE = 0x87, /* 135 */ BCODE_PUSH_NEGONE = 0x87, /* 135 */
BCODE_POP_INTO_INSTVAR_X = 0x88, /* 136 ## */
BCODE_PUSH_ZERO = 0x89, /* 137 */ BCODE_PUSH_ZERO = 0x89, /* 137 */
BCODE_PUSH_ONE = 0x8A, /* 138 */ BCODE_PUSH_ONE = 0x8A, /* 138 */
BCODE_PUSH_TWO = 0x8B, /* 139 */ BCODE_PUSH_TWO = 0x8B, /* 139 */
BCODE_PUSH_INSTVAR_X = 0x90, /* 144 ## */
BCODE_PUSH_TEMPVAR_X = 0x98, /* 152 ## */
BCODE_STORE_INTO_TEMPVAR_X = 0xA0, /* 160 ## */
BCODE_POP_INTO_TEMPVAR_X = 0xA8, /* 168 ## */
BCODE_PUSH_LITERAL_X = 0xB0, /* 176 ## */
/* UNUSED - 0xB1 */ /* UNUSED - 0xB1 */
BCODE_PUSH_INTLIT = 0xB2, /* 178 */ BCODE_PUSH_INTLIT = 0xB2, /* 178 */
BCODE_PUSH_NEGINTLIT = 0xB3, /* 179 */ BCODE_PUSH_NEGINTLIT = 0xB3, /* 179 */
BCODE_PUSH_CHARLIT = 0xB4, /* 180 */ BCODE_PUSH_CHARLIT = 0xB4, /* 180 */
/* UNUSED 0xE8 - 0xF7 */ BCODE_STORE_INTO_OBJECT_X = 0xB8, /* 184 ## */
BCODE_POP_INTO_OBJECT_X = 0xBC, /* 188 ## */
BCODE_PUSH_OBJECT_X = 0xC0, /* 192 ## */
BCODE_JUMP_FORWARD_X = 0xC4, /* 196 ## */
BCODE_JUMP2_FORWARD = 0xC5, /* 197 */
BCODE_JUMP_BACKWARD_X = 0xC8, /* 200 ## */
BCODE_JUMP2_BACKWARD = 0xC9, /* 201 */
BCODE_JUMP_FORWARD_IF_FALSE_X = 0xCC, /* 204 ## */
BCODE_JUMP2_FORWARD_IF_FALSE = 0xCD, /* 205 */
BCODE_JUMP_BACKWARD_IF_FALSE_X = 0xD0, /* 208 ## */
BCODE_JUMP2_BACKWARD_IF_FALSE = 0xD1, /* 209 */
BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 ## */
BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 ## */
BCODE_PUSH_CTXTEMPVAR_X = 0xE0, /* 224 ## */
BCODE_PUSH_OBJVAR_X = 0xE4, /* 228 ## */
BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 ## */
BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 ## */
BCODE_SEND_MESSAGE_X = 0xF0, /* 240 ## */
BCODE_SEND_MESSAGE_TO_SUPER_X = 0xF4, /* 244 ## */
/* -------------------------------------- */
BCODE_DUP_STACKTOP = 0xF8, BCODE_DUP_STACKTOP = 0xF8,
BCODE_POP_STACKTOP = 0xF9, BCODE_POP_STACKTOP = 0xF9,