|
|
|
@@ -108,11 +108,12 @@ static void refdown_globals (hawk_rtx_t* rtx, int pop);
|
|
|
|
|
static int run_pblocks (hawk_rtx_t* rtx);
|
|
|
|
|
static int run_pblock_chain (hawk_rtx_t* rtx, hawk_chain_t* cha);
|
|
|
|
|
static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno);
|
|
|
|
|
static int run_null_block_for_blockless_pattern (hawk_rtx_t* rtx);
|
|
|
|
|
static int run_block (hawk_rtx_t* rtx, hawk_nde_blk_t* nde);
|
|
|
|
|
static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde);
|
|
|
|
|
static int run_if (hawk_rtx_t* rtx, hawk_nde_if_t* nde);
|
|
|
|
|
static int run_switch (hawk_rtx_t* rtx, hawk_nde_switch_t* nde);
|
|
|
|
|
static int run_while (hawk_rtx_t* rtx, hawk_nde_while_t* nde);
|
|
|
|
|
static int run_while (hawk_rtx_t* rtx, int state, hawk_nde_while_t* nde);
|
|
|
|
|
static int run_for (hawk_rtx_t* rtx, hawk_nde_for_t* nde);
|
|
|
|
|
static int run_forin (hawk_rtx_t* rtx, hawk_nde_forin_t* nde);
|
|
|
|
|
static int run_break (hawk_rtx_t* rtx, hawk_nde_break_t* nde);
|
|
|
|
@@ -690,7 +691,6 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t
|
|
|
|
|
if (ecb->gblset) ecb->gblset(rtx, idx, val, ecb->ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2498,6 +2498,7 @@ static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno)
|
|
|
|
|
if (!ptn)
|
|
|
|
|
{
|
|
|
|
|
/* just execute the block */
|
|
|
|
|
HAWK_ASSERT(blk != HAWK_NULL); /* not possible to have no statement block */
|
|
|
|
|
rtx->active_block = blk;
|
|
|
|
|
if (run_block(rtx, blk) <= -1) return -1;
|
|
|
|
|
}
|
|
|
|
@@ -2515,8 +2516,10 @@ static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno)
|
|
|
|
|
|
|
|
|
|
if (hawk_rtx_valtobool(rtx, v1))
|
|
|
|
|
{
|
|
|
|
|
rtx->active_block = blk;
|
|
|
|
|
if (run_block(rtx, blk) <= -1)
|
|
|
|
|
int n;
|
|
|
|
|
rtx->active_block = blk; /* this may be null for a blockless pattern */
|
|
|
|
|
n = blk? run_block(rtx, blk): run_null_block_for_blockless_pattern(rtx);
|
|
|
|
|
if (n <= -1)
|
|
|
|
|
{
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, v1);
|
|
|
|
|
return -1;
|
|
|
|
@@ -2561,37 +2564,35 @@ static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static HAWK_INLINE int run_null_block_for_blockless_pattern (hawk_rtx_t* rtx)
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
/* blockless pattern - execute print $0*/
|
|
|
|
|
hawk_rtx_refupval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
|
|
|
|
|
n = hawk_rtx_writeiostr(rtx, HAWK_OUT_CONSOLE, HAWK_T(""), HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line));
|
|
|
|
|
if (n <= -1) goto oops;
|
|
|
|
|
|
|
|
|
|
n = hawk_rtx_writeiostr(rtx, HAWK_OUT_CONSOLE, HAWK_T(""), rtx->gbl.ors.ptr, rtx->gbl.ors.len);
|
|
|
|
|
if (n <= -1) goto oops;
|
|
|
|
|
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
oops:
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
/* ADJERR_LOC(rtx, &nde->loc); - can't adjust error location as nde is null */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static HAWK_INLINE int run_block0 (hawk_rtx_t* rtx, hawk_nde_blk_t* nde)
|
|
|
|
|
{
|
|
|
|
|
hawk_nde_t* p;
|
|
|
|
|
/*hawk_oow_t saved_stack_top;*/
|
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
|
|
if (nde == HAWK_NULL)
|
|
|
|
|
{
|
|
|
|
|
/* blockless pattern - execute print $0*/
|
|
|
|
|
hawk_rtx_refupval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
|
|
|
|
|
n = hawk_rtx_writeiostr(rtx, HAWK_OUT_CONSOLE, HAWK_T(""), HAWK_OOECS_PTR(&rtx->inrec.line), HAWK_OOECS_LEN(&rtx->inrec.line));
|
|
|
|
|
if (n <= -1)
|
|
|
|
|
{
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
/* ADJERR_LOC(rtx, &nde->loc); - can't adjust error location as nde is null */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = hawk_rtx_writeiostr(rtx, HAWK_OUT_CONSOLE, HAWK_T(""), rtx->gbl.ors.ptr, rtx->gbl.ors.len);
|
|
|
|
|
if (n <= -1)
|
|
|
|
|
{
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
/* ADJERR_LOC(rtx, &nde->loc); - can't adjust error location as nde is null */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, rtx->inrec.d0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HAWK_ASSERT(nde != HAWK_NULL);
|
|
|
|
|
HAWK_ASSERT(nde->type == HAWK_NDE_BLK);
|
|
|
|
|
/*saved_stack_top = rtx->stack_top;*/
|
|
|
|
|
|
|
|
|
@@ -2928,7 +2929,34 @@ static HAWK_INLINE int run_pending_signal_handlers (hawk_rtx_t* rtx)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|
|
|
|
static int push_exec_stack (hawk_rtx_t* rtx, int state, hawk_nde_t* nde)
|
|
|
|
|
{
|
|
|
|
|
if (rtx->exec_stack_size >= rtx->exec_stack_limit)
|
|
|
|
|
{
|
|
|
|
|
hawk_oow_t new_limit;
|
|
|
|
|
hawk_exec_stack_t* tmp;
|
|
|
|
|
new_limit = rtx->exec_stack_limit + 1;
|
|
|
|
|
new_limit = HAWK_ALIGN_POW2(new_limit, 64); /* TODO: change align factor */
|
|
|
|
|
tmp = hawk_rtx_reallocmem(rtx, rtx->exec_stack, HAWK_SIZEOF(*tmp) * new_limit);
|
|
|
|
|
if (HAWK_UNLIKELY(!tmp)) return -1;
|
|
|
|
|
rtx->exec_stack = tmp;
|
|
|
|
|
rtx->exec_stack_limit = new_limit;
|
|
|
|
|
}
|
|
|
|
|
rtx->exec_stack[rtx->exec_stack_size].state = state;
|
|
|
|
|
rtx->exec_stack[rtx->exec_stack_size].nde = nde;
|
|
|
|
|
rtx->exec_stack_size++;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: return the item pointer? */
|
|
|
|
|
static hawk_exec_stack_t* pop_exec_stack (hawk_rtx_t* rtx, hawk_exec_stack_t* es)
|
|
|
|
|
{
|
|
|
|
|
if (rtx->exec_stack_size <= 0) return HAWK_NULL;
|
|
|
|
|
*es = rtx->exec_stack[--rtx->exec_stack_size];
|
|
|
|
|
return es;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_statement0 (hawk_rtx_t* rtx, int state, hawk_nde_t* nde)
|
|
|
|
|
{
|
|
|
|
|
int xret;
|
|
|
|
|
hawk_val_t* tmp;
|
|
|
|
@@ -2965,7 +2993,7 @@ static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|
|
|
|
|
|
|
|
|
case HAWK_NDE_WHILE:
|
|
|
|
|
case HAWK_NDE_DOWHILE:
|
|
|
|
|
xret = run_while(rtx, (hawk_nde_while_t*)nde);
|
|
|
|
|
xret = run_while(rtx, state, (hawk_nde_while_t*)nde);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case HAWK_NDE_FOR:
|
|
|
|
@@ -3035,6 +3063,36 @@ static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|
|
|
|
return xret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|
|
|
|
{
|
|
|
|
|
int xret;
|
|
|
|
|
hawk_oow_t base;
|
|
|
|
|
hawk_exec_stack_t es;
|
|
|
|
|
|
|
|
|
|
HAWK_ASSERT(nde != HAWK_NULL);
|
|
|
|
|
// TODO: maybe the caller of this function can push nde to exec stack and call it without the parameter
|
|
|
|
|
base = rtx->exec_stack_size;
|
|
|
|
|
|
|
|
|
|
if (push_exec_stack(rtx, 0, nde) <= -1) return -1;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (!pop_exec_stack(rtx, &es)) break;
|
|
|
|
|
|
|
|
|
|
xret = run_statement0(rtx, es.state, es.nde);
|
|
|
|
|
if (xret <= -1)
|
|
|
|
|
{
|
|
|
|
|
/*while (rtx->exec_stack_size > base) pop_exec_stack(rtx);*/
|
|
|
|
|
rtx->exec_stack_size = base; /* restore the stack */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rtx->exec_stack_size == base) break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_if (hawk_rtx_t* rtx, hawk_nde_if_t* nde)
|
|
|
|
|
{
|
|
|
|
|
hawk_val_t* test;
|
|
|
|
@@ -3051,11 +3109,13 @@ static int run_if (hawk_rtx_t* rtx, hawk_nde_if_t* nde)
|
|
|
|
|
hawk_rtx_refupval_inline(rtx, test);
|
|
|
|
|
if (hawk_rtx_valtobool(rtx, test))
|
|
|
|
|
{
|
|
|
|
|
n = run_statement(rtx, nde->then_part);
|
|
|
|
|
//n = run_statement(rtx, nde->then_part);
|
|
|
|
|
n = push_exec_stack(rtx, 0, nde->then_part);
|
|
|
|
|
}
|
|
|
|
|
else if (nde->else_part)
|
|
|
|
|
{
|
|
|
|
|
n = run_statement(rtx, nde->else_part);
|
|
|
|
|
//n = run_statement(rtx, nde->else_part);
|
|
|
|
|
n = push_exec_stack(rtx, 0, nde->else_part);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, test); /* TODO: is this correct?*/
|
|
|
|
@@ -3130,7 +3190,6 @@ static int run_switch (hawk_rtx_t* rtx, hawk_nde_switch_t* nde)
|
|
|
|
|
action = action->next;
|
|
|
|
|
}
|
|
|
|
|
while(action);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -3177,40 +3236,32 @@ done:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_while (hawk_rtx_t* rtx, hawk_nde_while_t* nde)
|
|
|
|
|
static int run_while (hawk_rtx_t* rtx, int state, hawk_nde_while_t* nde)
|
|
|
|
|
{
|
|
|
|
|
hawk_val_t* test;
|
|
|
|
|
|
|
|
|
|
if (nde->type == HAWK_NDE_WHILE)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
/* no chained expressions are allowed for the test
|
|
|
|
|
* expression of the while statement */
|
|
|
|
|
HAWK_ASSERT(nde->test->next == HAWK_NULL);
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
int verdict;
|
|
|
|
|
|
|
|
|
|
ON_STATEMENT(rtx, nde->test);
|
|
|
|
|
|
|
|
|
|
test = eval_expression(rtx, nde->test);
|
|
|
|
|
if (HAWK_UNLIKELY(!test)) return -1;
|
|
|
|
|
|
|
|
|
|
hawk_rtx_refupval_inline(rtx, test);
|
|
|
|
|
verdict = hawk_rtx_valtobool(rtx, test);
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, test);
|
|
|
|
|
|
|
|
|
|
if (hawk_rtx_valtobool(rtx, test))
|
|
|
|
|
{
|
|
|
|
|
if (run_statement(rtx,nde->body) <= -1)
|
|
|
|
|
{
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, test);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, test);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, test);
|
|
|
|
|
if (!verdict) break;
|
|
|
|
|
if (run_statement(rtx, nde->body) <= -1) return -1;
|
|
|
|
|
|
|
|
|
|
if (rtx->exit_level == EXIT_BREAK)
|
|
|
|
|
{
|
|
|
|
@@ -3223,6 +3274,53 @@ static int run_while (hawk_rtx_t* rtx, hawk_nde_while_t* nde)
|
|
|
|
|
}
|
|
|
|
|
else if (rtx->exit_level != EXIT_NONE) break;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
/* no chained expressions are allowed for the test
|
|
|
|
|
* expression of the while statement */
|
|
|
|
|
HAWK_ASSERT(nde->test->next == HAWK_NULL);
|
|
|
|
|
|
|
|
|
|
ON_STATEMENT(rtx, nde->test);
|
|
|
|
|
|
|
|
|
|
if (state >= 1)
|
|
|
|
|
{
|
|
|
|
|
int verdict;
|
|
|
|
|
hawk_val_t* v;
|
|
|
|
|
|
|
|
|
|
if (state == 2)
|
|
|
|
|
{
|
|
|
|
|
if (rtx->exit_level == EXIT_BREAK)
|
|
|
|
|
{
|
|
|
|
|
rtx->exit_level = EXIT_NONE;
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
else if (rtx->exit_level == EXIT_CONTINUE)
|
|
|
|
|
{
|
|
|
|
|
rtx->exit_level = EXIT_NONE;
|
|
|
|
|
}
|
|
|
|
|
else if (rtx->exit_level != EXIT_ONE)
|
|
|
|
|
{
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v = pop_eval_stack(rtx); /* result of the test */
|
|
|
|
|
hawk_rtx_refupval_inline(rtx, v);
|
|
|
|
|
verdict = hawk_rtx_valtobool(rtx, v);
|
|
|
|
|
hawk_rtx_refdownval_inline(rtx, v);
|
|
|
|
|
|
|
|
|
|
if (verdict)
|
|
|
|
|
{
|
|
|
|
|
if (push_exec_stack(rtx, 2, (hawk_nde_t*)nde) <= -1 ||
|
|
|
|
|
push_exec_stack(rtx, 0, nde->body) <= -1) return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (push_exec_stack(rtx, 1, (hawk_nde_t*)nde) <= -1) return -1;
|
|
|
|
|
if (push_exec_stack(rtx, 0, nde->test) <= -1) return -1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else if (nde->type == HAWK_NDE_DOWHILE)
|
|
|
|
|
{
|
|
|
|
|