implemented simple optimization in compiling an if expression
This commit is contained in:
parent
22013650bb
commit
07d8d0ea83
@ -176,7 +176,11 @@ class MyObject(Object)
|
||||
a := a + 100000000000000.
|
||||
}.*)
|
||||
|
||||
(*
|
||||
|
||||
a := if(false) { 10 } elsif (false) { 20 } elsif (false) { 30} else { 40}.
|
||||
##a := if(false) { 999 } else { 888 }.
|
||||
a dump.
|
||||
|
||||
a := 5.
|
||||
a := while (true)
|
||||
{
|
||||
@ -187,12 +191,12 @@ class MyObject(Object)
|
||||
}.
|
||||
a dump.
|
||||
}.
|
||||
a dump.*)
|
||||
a dump.
|
||||
a := 5.
|
||||
do {
|
||||
a := do {
|
||||
('in loop.....' & a asString) dump.
|
||||
if (a > 5) { break }.
|
||||
##if (a > 5) { break }.
|
||||
a := a + 1.
|
||||
} while(a < 10).
|
||||
} while (false).
|
||||
|
107
moo/lib/comp.c
107
moo/lib/comp.c
@ -4530,63 +4530,94 @@ 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;
|
||||
moo_oow_pool_chunk_t* jumptoend_chunk;
|
||||
moo_oow_t i, j;
|
||||
|
||||
moo_oow_t jumptonext;
|
||||
moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock;
|
||||
int falseblock;
|
||||
moo_ioloc_t if_loc, brace_loc;
|
||||
|
||||
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF);
|
||||
if_loc = *TOKEN_LOC(moo);
|
||||
|
||||
init_oow_pool (moo, &jumptoend);
|
||||
jumptonext = INVALID_IP;
|
||||
endoftrueblock = INVALID_IP;
|
||||
|
||||
/* TODO: simple optimization to check if the conditional is true or false */
|
||||
GET_TOKEN (moo); /* get ( */
|
||||
if (compile_conditional (moo) <= -1) goto oops;
|
||||
|
||||
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) goto oops;
|
||||
|
||||
GET_TOKEN (moo); /* get { */
|
||||
brace_loc = *TOKEN_LOC(moo);
|
||||
if (compile_braced_block (moo) <= -1) goto oops;
|
||||
|
||||
/* emit code to jump to the end */
|
||||
/*jumptoend[jumptoend_count++] = moo->c->mth.code.len;*/
|
||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops;
|
||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||
|
||||
GET_TOKEN (moo);
|
||||
while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF)
|
||||
do
|
||||
{
|
||||
if (patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||
int falseblock = 0;
|
||||
|
||||
GET_TOKEN (moo); /* get ( */
|
||||
if (compile_conditional(moo) <= -1) goto oops;
|
||||
precondpos = moo->c->mth.code.len;
|
||||
|
||||
/* 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) goto oops;
|
||||
if (jumptonext != INVALID_IP &&
|
||||
patch_long_forward_jump_instruction (moo, jumptonext, precondpos, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||
|
||||
if (compile_conditional(moo) <= -1) goto oops;
|
||||
postcondpos = moo->c->mth.code.len;
|
||||
|
||||
if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE)
|
||||
{
|
||||
/* do not generate jump */
|
||||
jumptonext = INVALID_IP;
|
||||
falseblock = 0;
|
||||
|
||||
/* eliminate PUSH_TRUE as well */
|
||||
moo->c->mth.code.len = precondpos;
|
||||
postcondpos = precondpos;
|
||||
}
|
||||
else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
|
||||
{
|
||||
jumptonext = INVALID_IP;
|
||||
/* mark that the conditional is false. instructions will get eliminated below */
|
||||
falseblock = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remember position of the jump_forward_if_false instruction to be generated */
|
||||
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) goto oops;
|
||||
}
|
||||
|
||||
GET_TOKEN (moo); /* get { */
|
||||
brace_loc = *TOKEN_LOC(moo);
|
||||
if (compile_braced_block(moo) <= -1) goto oops;
|
||||
|
||||
/* emit code to jump to the end */
|
||||
/*jumptoend[jumptoend_count++] = moo->c->mth.code.len;*/
|
||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops;
|
||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||
if (jumptonext == INVALID_IP)
|
||||
{
|
||||
if (falseblock)
|
||||
{
|
||||
moo->c->mth.code.len = precondpos;
|
||||
postcondpos = precondpos;
|
||||
}
|
||||
else if (endoftrueblock == INVALID_IP)
|
||||
{
|
||||
/* update the end position of the first true block */
|
||||
endoftrueblock = moo->c->mth.code.len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (endoftrueblock == INVALID_IP)
|
||||
{
|
||||
/* emit an instruction to jump to the end */
|
||||
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1) goto oops;
|
||||
if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
GET_TOKEN (moo); /* get the next token after } */
|
||||
}
|
||||
} while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF);
|
||||
|
||||
if (patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||
if (jumptonext != INVALID_IP &&
|
||||
patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
|
||||
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
|
||||
{
|
||||
@ -4596,10 +4627,16 @@ static int compile_if_expression (moo_t* moo)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* emit code to push nil if no 'else' part exists */
|
||||
/* emit an instruction to push nil if no 'else' part exists */
|
||||
if (emit_byte_instruction (moo, BCODE_PUSH_NIL) <= -1) goto oops;
|
||||
}
|
||||
|
||||
if (endoftrueblock != INVALID_IP)
|
||||
{
|
||||
/* eliminate all instructions after the end of the first true block found */
|
||||
moo->c->mth.code.len = endoftrueblock;
|
||||
}
|
||||
|
||||
/* patch instructions that jumps to the end of if expression */
|
||||
for (jumptoend_chunk = jumptoend.head, i = 0; jumptoend_chunk; jumptoend_chunk = jumptoend_chunk->next)
|
||||
{
|
||||
@ -4819,7 +4856,7 @@ skip_emitting_jump_backward:
|
||||
|
||||
/* update jump instructions emitted for break */
|
||||
if (update_loop_jumps (moo, &loop->break_ip_pool, moo->c->mth.code.len) <= -1) return -1;
|
||||
free_loop (moo, loop);
|
||||
free_loop (moo, loop); /* destroy the unlinked loop information */
|
||||
loop = MOO_NULL;
|
||||
loop_pushed = 0;
|
||||
|
||||
|
@ -3518,7 +3518,8 @@ int moo_execute (moo_t* moo)
|
||||
case BCODE_JUMP_BACKWARD_IF_TRUE_X:
|
||||
FETCH_PARAM_CODE_TO (moo, b1);
|
||||
LOG_INST_1 (moo, "jump_backward_if_true %zu", b1);
|
||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= b1;
|
||||
/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= b1;*/
|
||||
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= b1;
|
||||
MOO_STACK_POP (moo);
|
||||
break;
|
||||
|
||||
@ -3527,7 +3528,8 @@ int moo_execute (moo_t* moo)
|
||||
case BCODE_JUMP_BACKWARD_IF_TRUE_2:
|
||||
case BCODE_JUMP_BACKWARD_IF_TRUE_3:
|
||||
LOG_INST_1 (moo, "jump_backward_if_true %zu", (moo_oow_t)(bcode & 0x3));
|
||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= (bcode & 0x3); /* low 2 bits */
|
||||
/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= (bcode & 0x3);*/ /* low 2 bits */
|
||||
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= (bcode & 0x3);
|
||||
MOO_STACK_POP (moo);
|
||||
break;
|
||||
|
||||
@ -3560,7 +3562,8 @@ int moo_execute (moo_t* moo)
|
||||
case BCODE_JUMP2_BACKWARD_IF_TRUE:
|
||||
FETCH_PARAM_CODE_TO (moo, b1);
|
||||
LOG_INST_1 (moo, "jump2_backward_if_true %zu", b1);
|
||||
if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= MAX_CODE_JUMP + b1;
|
||||
/* if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip -= MAX_CODE_JUMP + b1; */
|
||||
if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip -= MAX_CODE_JUMP + b1;
|
||||
MOO_STACK_POP (moo);
|
||||
break;
|
||||
/* -------------------------------------------------------- */
|
||||
|
@ -96,7 +96,7 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t
|
||||
moo->option.dfl_sysdic_size = MOO_DFL_SYSDIC_SIZE;
|
||||
moo->option.dfl_procstk_size = MOO_DFL_PROCSTK_SIZE;
|
||||
|
||||
/* TODO: intoduct a permanent heap */
|
||||
/* TODO: introduce a permanent heap */
|
||||
/*moo->permheap = moo_makeheap (moo, what is the best size???);
|
||||
if (!moo->permheap) goto oops; */
|
||||
moo->curheap = moo_makeheap (moo, heapsz);
|
||||
|
Loading…
Reference in New Issue
Block a user