Compare commits
2
Commits
main
...
f3dc3052a7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3dc3052a7 | ||
|
|
ece6c0e286 |
@@ -437,6 +437,15 @@ struct hawk_var_xinfo_t
|
||||
hawk_loc_t loc;
|
||||
};
|
||||
|
||||
/* item to to in the exec stack */
|
||||
struct hawk_exec_stack_t
|
||||
{
|
||||
int state;
|
||||
hawk_nde_t* nde;
|
||||
};
|
||||
|
||||
typedef struct hawk_exec_stack_t hawk_exec_stack_t;
|
||||
|
||||
struct hawk_rtx_t
|
||||
{
|
||||
HAWK_RTX_HDR;
|
||||
@@ -451,6 +460,11 @@ struct hawk_rtx_t
|
||||
hawk_oow_t stack_base;
|
||||
hawk_oow_t stack_limit;
|
||||
|
||||
/* stack for executing statements */
|
||||
hawk_exec_stack_t* exec_stack;
|
||||
hawk_oow_t exec_stack_size;
|
||||
hawk_oow_t exec_stack_limit;
|
||||
|
||||
int exit_level;
|
||||
int init_called;
|
||||
|
||||
|
||||
@@ -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,41 +3236,33 @@ 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
verdict = hawk_rtx_valtobool(rtx, test);
|
||||
hawk_rtx_refdownval_inline(rtx, test);
|
||||
|
||||
if (!verdict) break;
|
||||
if (run_statement(rtx, nde->body) <= -1) return -1;
|
||||
|
||||
if (rtx->exit_level == EXIT_BREAK)
|
||||
{
|
||||
rtx->exit_level = EXIT_NONE;
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -139,6 +139,18 @@ function main()
|
||||
tap_ensure(!!@[1], @true, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!dummy, @false, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!!dummy, @true, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tmp = 0;
|
||||
tap_ensure(!tmp && 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp && 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp || 0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp || 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(1 && !tmp, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(0 || !tmp, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tmp = 1;
|
||||
tap_ensure(!tmp && 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp && 1, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp || 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!tmp || 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_ensure(sprintf("%d", @true), "1", @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(sprintf("%d", @false), "0", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
Reference in New Issue
Block a user