Compare commits

..

2 Commits

Author SHA1 Message Date
hyung-hwan f3dc3052a7 added some test cases to cover unary with relational ops
continuous-integration/drone/push Build is failing
2026-05-25 10:28:23 +09:00
hyung-hwan ece6c0e286 interim checkpoint for execution stack implementation 2026-05-24 20:07:48 +09:00
3 changed files with 174 additions and 50 deletions
+14
View File
@@ -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;
+148 -50
View File
@@ -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)
{
+12
View File
@@ -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);