Compare commits
6 Commits
b9dd73ee9f
...
479b74d1a3
| Author | SHA1 | Date | |
|---|---|---|---|
| 479b74d1a3 | |||
| f444cc92fe | |||
| b5464605d8 | |||
| 9e5804a15b | |||
| ecc1c4bfb3 | |||
| 1428e7dc2f |
@@ -358,7 +358,8 @@ BEGIN {
|
||||
|
||||
### Arithmetic and Comparison
|
||||
|
||||
- Arithmetic: `+`, `-`, `*`, `/`, `%`, `**` (exponentiation), `++`, `--`, `<<`, `>>`.
|
||||
- Arithmetic: `+`, `-`, `*`, `/`, `\`(integer division), `%`(modulo), `**` or '^'(exponentiation), `++`, `--`, `<<`, `>>`.
|
||||
- Compound assignment: `=`, `+=`, `-=`, `*=`, `/=`, `\=`, `%=`, `^=` or `**=`, `%%=`.
|
||||
- Comparisons: `==`, `!=`, `<`, `<=`, `>`, `>=`.
|
||||
- Type-precise compare: `===` and `!==`.
|
||||
|
||||
@@ -367,7 +368,11 @@ Example:
|
||||
```awk
|
||||
BEGIN {
|
||||
x = 10 + 5 * 2
|
||||
x += 3
|
||||
s = "ha"
|
||||
s %%= "wk"
|
||||
if (x >= 20) print x
|
||||
print s
|
||||
if ("10" === 10) print "no"
|
||||
}
|
||||
```
|
||||
@@ -404,6 +409,7 @@ BEGIN {
|
||||
|
||||
- Bitwise AND/OR/XOR: `&`, `|`, ^^
|
||||
- Unary bitwise negation: ~
|
||||
- Compound bitwise assignment: `&=`, `|=`, `^^=`, `<<=`, `>>=`
|
||||
- `|` also denotes pipes, so use parentheses when you mean bitwise OR.
|
||||
- `>>` is also used for append redirection; use parentheses when you mean right shift.
|
||||
|
||||
|
||||
+538
-208
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -54,15 +54,15 @@ int hawk_rtx_readiobytes (
|
||||
|
||||
int hawk_rtx_writeioval (
|
||||
hawk_rtx_t* rtx, hawk_out_type_t out_type,
|
||||
const hawk_ooch_t* name, hawk_val_t* v);
|
||||
const hawk_ooch_t* name, const hawk_val_t* v);
|
||||
|
||||
int hawk_rtx_writeiostr (
|
||||
hawk_rtx_t* rtx, hawk_out_type_t out_type,
|
||||
const hawk_ooch_t* name, hawk_ooch_t* str, hawk_oow_t len);
|
||||
const hawk_ooch_t* name, const hawk_ooch_t* str, hawk_oow_t len);
|
||||
|
||||
int hawk_rtx_writeiobytes (
|
||||
hawk_rtx_t* rtx, hawk_out_type_t out_type,
|
||||
const hawk_ooch_t* name, hawk_bch_t* str, hawk_oow_t len);
|
||||
const hawk_ooch_t* name, const hawk_bch_t* str, hawk_oow_t len);
|
||||
|
||||
int hawk_rtx_flushio (
|
||||
hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name);
|
||||
|
||||
@@ -1138,7 +1138,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, hawk_in_type_t in_type, const hawk_oo
|
||||
}
|
||||
|
||||
|
||||
int hawk_rtx_writeioval (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, hawk_val_t* v)
|
||||
int hawk_rtx_writeioval (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, const hawk_val_t* v)
|
||||
{
|
||||
hawk_val_type_t vtype;
|
||||
vtype = HAWK_RTX_GETVALTYPE(rtx, v);
|
||||
@@ -1275,7 +1275,7 @@ static int prepare_for_write_io_data (hawk_rtx_t* rtx, hawk_out_type_t out_type,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hawk_rtx_writeiostr (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, hawk_ooch_t* str, hawk_oow_t len)
|
||||
int hawk_rtx_writeiostr (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, const hawk_ooch_t* str, hawk_oow_t len)
|
||||
{
|
||||
int x;
|
||||
write_io_data_t wid;
|
||||
@@ -1286,7 +1286,7 @@ int hawk_rtx_writeiostr (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_o
|
||||
{
|
||||
hawk_ooi_t n;
|
||||
|
||||
n = wid.handler(rtx, HAWK_RIO_CMD_WRITE, wid.p, str, len);
|
||||
n = wid.handler(rtx, HAWK_RIO_CMD_WRITE, wid.p, (void*)str, len);
|
||||
if (n <= -1) return -1;
|
||||
|
||||
if (n == 0)
|
||||
@@ -1302,7 +1302,7 @@ int hawk_rtx_writeiostr (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_o
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hawk_rtx_writeiobytes (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, hawk_bch_t* str, hawk_oow_t len)
|
||||
int hawk_rtx_writeiobytes (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* name, const hawk_bch_t* str, hawk_oow_t len)
|
||||
{
|
||||
int x;
|
||||
write_io_data_t wid;
|
||||
@@ -1313,7 +1313,7 @@ int hawk_rtx_writeiobytes (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk
|
||||
{
|
||||
hawk_ooi_t n;
|
||||
|
||||
n = wid.handler(rtx, HAWK_RIO_CMD_WRITE_BYTES, wid.p, str, len);
|
||||
n = wid.handler(rtx, HAWK_RIO_CMD_WRITE_BYTES, wid.p, (void*)str, len);
|
||||
if (n <= -1) return -1;
|
||||
|
||||
if (n == 0)
|
||||
|
||||
@@ -84,6 +84,7 @@ static int init_globals (hawk_rtx_t* rtx);
|
||||
static void refdown_globals (hawk_rtx_t* rtx, int pop);
|
||||
|
||||
static void fbc_eval_stack_fini (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack);
|
||||
static hawk_val_t* fbc_eval_stack_pop (hawk_fbc_eval_stack_t* stack);
|
||||
|
||||
static int run_pblocks (hawk_rtx_t* rtx);
|
||||
static int run_pblock_chain (hawk_rtx_t* rtx, hawk_chain_t* cha);
|
||||
@@ -1463,12 +1464,12 @@ hawk_mod_t* hawk_rtx_querymodulewithoocs (hawk_rtx_t* rtx, const hawk_oocs_t* na
|
||||
/* the logic here must match hawk_querymodulewithoocs() in parse.c */
|
||||
dc = hawk_find_oochars_in_oochars(name->ptr, name->len, HAWK_T("::"), 2, 0);
|
||||
HAWK_ASSERT(dc != HAWK_NULL);
|
||||
if (HAWK_UNLIKELY(!dc)) goto internal_error_unrolling;
|
||||
if (HAWK_UNLIKELY(!dc)) goto internal_error_unrolling; /* this must not happend but .. */
|
||||
len = dc - name->ptr;
|
||||
|
||||
pair = hawk_rbt_search(rtx->modtab, name->ptr, len);
|
||||
HAWK_ASSERT(pair != HAWK_NULL);
|
||||
if (HAWK_UNLIKELY(!pair))
|
||||
if (HAWK_UNLIKELY(!pair)) /* this must not happen but .. */
|
||||
{
|
||||
internal_error_unrolling:
|
||||
hawk_rtx_seterrbfmt(rtx, HAWK_NULL, HAWK_EINTERN,
|
||||
@@ -1480,9 +1481,9 @@ hawk_mod_t* hawk_rtx_querymodulewithoocs (hawk_rtx_t* rtx, const hawk_oocs_t* na
|
||||
/* skip the fini callback because the init callback returned failure. not calling m->fini().
|
||||
* invoke the unload() callback if needed and unload the module itself. */
|
||||
hawk_modtab_unload_module(rtx->modtab, pair, rtx->hawk);
|
||||
hawk_rbt_delete(rtx->modtab, name->ptr, len);
|
||||
}
|
||||
|
||||
hawk_rbt_delete(rtx->modtab, name->ptr, len);
|
||||
m = HAWK_NULL; /* indicate failure */
|
||||
}
|
||||
}
|
||||
@@ -1493,7 +1494,7 @@ hawk_mod_t* hawk_rtx_querymodulewithoocs (hawk_rtx_t* rtx, const hawk_oocs_t* na
|
||||
hawk_mod_t* hawk_rtx_querymodulewithname (hawk_rtx_t* rtx, const hawk_ooch_t* name, hawk_mod_sym_t* sym, int flags)
|
||||
{
|
||||
hawk_oocs_t oocs;
|
||||
oocs.ptr = name;
|
||||
oocs.ptr = (hawk_ooch_t*)name;
|
||||
oocs.len = hawk_count_oocstr(name);
|
||||
return hawk_rtx_querymodulewithoocs(rtx, &oocs, sym, flags);
|
||||
}
|
||||
@@ -1717,7 +1718,6 @@ static int run_blocks_for_bpae_loop (hawk_rtx_t* rtx, hawk_nde_t* blk_head, int
|
||||
|
||||
static hawk_val_t* run_bpae_loop (hawk_rtx_t* rtx)
|
||||
{
|
||||
hawk_nde_t* nde;
|
||||
hawk_oow_t nargs, i;
|
||||
hawk_val_t* retv;
|
||||
int ret = 0;
|
||||
@@ -2668,28 +2668,33 @@ static int call_signal_handlers (hawk_rtx_t* rtx)
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static HAWK_INLINE int run_pending_signal_handlers (hawk_rtx_t* rtx)
|
||||
{
|
||||
if (rtx->sig_handling) return 0;
|
||||
|
||||
/* run singal handlers if there are raised signals */
|
||||
#if defined(HAWK_ATOMIC_LOAD)
|
||||
if (HAWK_ATOMIC_LOAD(&rtx->sig_pending_any, HAWK_ATOMIC_RELAXED) != 0 &&
|
||||
call_signal_handlers(rtx) <= -1) return -1;
|
||||
#else
|
||||
/* NOTE:
|
||||
* rtx->sig_pending_any accessed non-atomically without mutex concurrently
|
||||
* from multiple threads(e.g. hawk_rtx_raisesig() called from a different
|
||||
* thread) is undefined behavior. but ignore this path as i believe most
|
||||
* modern compilers should support the atomic primitives. */
|
||||
if (rtx->sig_pending_any && call_signal_handlers(rtx) <= -1) return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_statement (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||
{
|
||||
int xret;
|
||||
hawk_val_t* tmp;
|
||||
|
||||
ON_STATEMENT(rtx, nde);
|
||||
|
||||
if (!rtx->sig_handling)
|
||||
{
|
||||
/* run singal handlers if there are raised signals */
|
||||
#if defined(HAWK_ATOMIC_LOAD)
|
||||
if (HAWK_ATOMIC_LOAD(&rtx->sig_pending_any, HAWK_ATOMIC_RELAXED) != 0 &&
|
||||
call_signal_handlers(rtx) <= -1) return -1;
|
||||
#else
|
||||
/* NOTE:
|
||||
* rtx->sig_pending_any accessed non-atomically without mutex concurrently
|
||||
* from multiple threads(e.g. hawk_rtx_raisesig() called from a different
|
||||
* thread) is undefined behavior. but ignore this path as i believe most
|
||||
* modern compilers should support the atomic primitives. */
|
||||
if (rtx->sig_pending_any && call_signal_handlers(rtx) <= -1) return -1;
|
||||
#endif
|
||||
}
|
||||
if (run_pending_signal_handlers(rtx) <= -1) return -1;
|
||||
|
||||
/* run the actual statement */
|
||||
switch (nde->type)
|
||||
@@ -3862,9 +3867,7 @@ static int run_reset (hawk_rtx_t* rtx, hawk_nde_reset_t* nde)
|
||||
}
|
||||
}
|
||||
|
||||
static int io_val_to_str (
|
||||
hawk_rtx_t* rtx, hawk_val_t* v, const hawk_loc_t* loc,
|
||||
hawk_oocs_t* dst, int seterr)
|
||||
static int io_val_to_str (hawk_rtx_t* rtx, hawk_val_t* v, const hawk_loc_t* loc, hawk_oocs_t* dst, int seterr)
|
||||
{
|
||||
dst->ptr = hawk_rtx_getvaloocstr(rtx, v, &dst->len);
|
||||
if (HAWK_UNLIKELY(!dst->ptr)) return -1;
|
||||
@@ -3893,7 +3896,7 @@ static int io_val_to_str (
|
||||
return 0;
|
||||
}
|
||||
|
||||
static hawk_val_t* io_nde_to_str(hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_oocs_t* dst, int seterr)
|
||||
static hawk_val_t* io_nde_to_str (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_oocs_t* dst, int seterr)
|
||||
{
|
||||
hawk_val_t* v;
|
||||
|
||||
@@ -3910,9 +3913,7 @@ static hawk_val_t* io_nde_to_str(hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_oocs_t*
|
||||
return v;
|
||||
}
|
||||
|
||||
static int fbc_write_print_str (
|
||||
hawk_rtx_t* rtx, hawk_nde_print_t* nde, const hawk_ooch_t* ptr, hawk_oow_t len,
|
||||
hawk_val_t* out_v)
|
||||
static int fbc_write_print_str (hawk_rtx_t* rtx, hawk_nde_print_t* nde, const hawk_ooch_t* ptr, hawk_oow_t len, hawk_val_t* out_v)
|
||||
{
|
||||
hawk_oocs_t out;
|
||||
int n;
|
||||
@@ -7602,10 +7603,8 @@ static hawk_val_t* eval_fncall_fnc (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||
return hawk_rtx_evalcall(rtx, call, HAWK_NULL, push_arg_from_nde, (void*)call->u.fnc.spec.arg.spec, HAWK_NULL, HAWK_NULL);
|
||||
}
|
||||
|
||||
static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||
static HAWK_INLINE hawk_fun_t* resolve_fncall_fun (hawk_rtx_t* rtx, hawk_nde_fncall_t* call)
|
||||
{
|
||||
/* user-defined function */
|
||||
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
|
||||
hawk_fun_t* fun;
|
||||
#if defined(HAWK_ATOMIC_CAS_BOOL)
|
||||
hawk_fun_t* expected;
|
||||
@@ -7628,7 +7627,7 @@ static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde
|
||||
pair = hawk_htb_search(rtx->hawk->tree.funs, call->u.fun.name.ptr, call->u.fun.name.len);
|
||||
if (!pair)
|
||||
{
|
||||
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_EFUNNF, HAWK_T("function '%.*js' not found"), call->u.fun.name.len, call->u.fun.name.ptr);
|
||||
hawk_rtx_seterrfmt(rtx, &call->loc, HAWK_EFUNNF, HAWK_T("function '%.*js' not found"), call->u.fun.name.len, call->u.fun.name.ptr);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
|
||||
@@ -7661,12 +7660,22 @@ static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde
|
||||
|
||||
if (call->nargs > fun->nargs && !fun->variadic)
|
||||
{
|
||||
/* TODO: is this correct? what if i want to
|
||||
* allow arbitarary numbers of arguments? */
|
||||
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
|
||||
hawk_rtx_seterrfmt(rtx, &call->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
|
||||
return fun;
|
||||
}
|
||||
|
||||
static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||
{
|
||||
/* user-defined function */
|
||||
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
|
||||
hawk_fun_t* fun;
|
||||
|
||||
fun = resolve_fncall_fun(rtx, call);
|
||||
if (!fun) return HAWK_NULL;
|
||||
|
||||
/* push_arg_from_nde() has special handling for references when the function
|
||||
* argument spec contains 'r' or 'R'.
|
||||
* a reference is passed to a built-in function as a reference value
|
||||
@@ -7747,6 +7756,114 @@ static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static hawk_val_t* fbc_eval_call (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* evstk, hawk_nde_fncall_t* call)
|
||||
{
|
||||
hawk_val_t* args_fixed[8];
|
||||
hawk_val_t** args = args_fixed;
|
||||
hawk_val_t* callee_val = HAWK_NULL;
|
||||
hawk_val_t* rv = HAWK_NULL;
|
||||
hawk_fun_t* fun = HAWK_NULL;
|
||||
struct pafv_t pafv;
|
||||
hawk_oow_t i;
|
||||
|
||||
if (!call)
|
||||
{
|
||||
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
|
||||
if (call->nargs > HAWK_COUNTOF(args_fixed))
|
||||
{
|
||||
args = (hawk_val_t**)hawk_rtx_allocmem(rtx, call->nargs * HAWK_SIZEOF(*args));
|
||||
if (HAWK_UNLIKELY(!args)) return HAWK_NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < call->nargs; i++) args[i] = HAWK_NULL;
|
||||
for (i = call->nargs; i > 0; i--)
|
||||
{
|
||||
args[i - 1] = fbc_eval_stack_pop(evstk);
|
||||
if (!args[i - 1])
|
||||
{
|
||||
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function combines the subset of these three functions:
|
||||
* eval_fncall_fnc(), eval_fncall_fun(), eval_fncall_var() */
|
||||
switch (call->type)
|
||||
{
|
||||
case HAWK_NDE_FNCALL_FNC: /* builtin function */
|
||||
if (call->u.fnc.flags & HAWK_NDE_FNCALL_FNC_DEFERRED_MODFNC)
|
||||
{
|
||||
hawk_rtx_seterrnum(rtx, &call->loc, HAWK_EINTERN);
|
||||
goto oops;
|
||||
}
|
||||
HAWK_ASSERT(call->nargs >= call->u.fnc.spec.arg.min && call->nargs <= call->u.fnc.spec.arg.max);
|
||||
break;
|
||||
|
||||
case HAWK_NDE_FNCALL_FUN: /* pure hawk function */
|
||||
fun = resolve_fncall_fun(rtx, call);
|
||||
if (!fun) goto oops;
|
||||
break;
|
||||
|
||||
case HAWK_NDE_FNCALL_EXPR: /* function pointed to by another variable or a return value of another call, etc */
|
||||
callee_val = fbc_eval_stack_pop(evstk); /* the stack top has the callee expression result */
|
||||
if (!callee_val)
|
||||
{
|
||||
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
fun = hawk_rtx_valtofun(rtx, callee_val);
|
||||
if (!fun)
|
||||
{
|
||||
if (hawk_rtx_geterrnum(rtx) == HAWK_EINVAL)
|
||||
{
|
||||
if (nde_is_var(call->u.expr.callable))
|
||||
{
|
||||
hawk_nde_var_t* v = (hawk_nde_var_t*)call->u.expr.callable;
|
||||
hawk_rtx_seterrfmt(rtx, &call->loc, HAWK_ENOTFUN, HAWK_T("non-function value in '%.*js'"), v->id.name.len, v->id.name.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_rtx_seterrnum(rtx, &call->loc, HAWK_ENOTFUN);
|
||||
}
|
||||
}
|
||||
ADJERR_LOC(rtx, &call->loc);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (call->nargs > fun->nargs && !fun->variadic)
|
||||
{
|
||||
hawk_rtx_seterrfmt(rtx, &call->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
|
||||
goto oops;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
hawk_rtx_seterrnum(rtx, &call->loc, HAWK_EINTERN);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* TODO: this implementation is extremely inefficient... we must be able to call hawk_rtx_evalcall without push_arg_from_vals... */
|
||||
pafv.args = args;
|
||||
pafv.nargs = call->nargs;
|
||||
pafv.argspec = HAWK_NULL;
|
||||
pafv.argspeclen = 0;
|
||||
|
||||
rv = hawk_rtx_evalcall(rtx, call, fun, push_arg_from_vals, (void*)&pafv, HAWK_NULL, HAWK_NULL);
|
||||
|
||||
oops:
|
||||
if (callee_val) hawk_rtx_refdownval(rtx, callee_val);
|
||||
for (i = 0; i < call->nargs; i++)
|
||||
{
|
||||
if (args[i]) hawk_rtx_refdownval(rtx, args[i]);
|
||||
}
|
||||
if (args != args_fixed) hawk_rtx_freemem(rtx, args);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void fbc_eval_stack_unwind (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack, hawk_oow_t base)
|
||||
{
|
||||
while (stack->len > base)
|
||||
@@ -7882,6 +7999,8 @@ static int run_funbc (hawk_rtx_t* rtx, hawk_fun_t* fun)
|
||||
hawk_fbc_ins_t* ins = &bc->code[pc];
|
||||
hawk_val_t* val;
|
||||
|
||||
if (HAWK_UNLIKELY(run_pending_signal_handlers(rtx) <= -1)) goto oops;
|
||||
|
||||
/*hawk_logbfmt(rtx->hawk, HAWK_LOG_STDERR, "opcode = 0x%x [%d]\n", ins->opcode, ins->opcode);*/
|
||||
switch (ins->opcode)
|
||||
{
|
||||
@@ -8252,6 +8371,12 @@ static int run_funbc (hawk_rtx_t* rtx, hawk_fun_t* fun)
|
||||
hawk_rtx_refdownval(rtx, val);
|
||||
break;
|
||||
|
||||
case HAWK_FBC_OP_CALL:
|
||||
val = fbc_eval_call(rtx, evstk, (hawk_nde_fncall_t*)ins->u.nde);
|
||||
if (HAWK_UNLIKELY(!val)) goto oops;
|
||||
if (fbc_eval_stack_push(rtx, evstk, val) <= -1) goto oops;
|
||||
break;
|
||||
|
||||
case HAWK_FBC_OP_RET:
|
||||
val = fbc_eval_stack_pop(evstk);
|
||||
if (!val)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ endif
|
||||
check_SCRIPTS += h-003.hawk h-004.hawk h-009.hawk h-010.hawk \
|
||||
h-011.hawk h-012.hawk h-013.hawk h-014.hawk h-015.hawk \
|
||||
h-016.hawk h-017.hawk h-018.hawk h-019.hawk h-020.hawk \
|
||||
h-021.hawk
|
||||
h-021.hawk h-022.hawk h-023.hawk
|
||||
|
||||
check_SCRIPTS += regress-filename.sh
|
||||
|
||||
|
||||
+1
-1
@@ -650,7 +650,7 @@ LIBADD_COMMON = ../lib/libhawk.la $(LIBM)
|
||||
check_SCRIPTS = $(am__append_1) h-003.hawk h-004.hawk h-009.hawk \
|
||||
h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk \
|
||||
h-015.hawk h-016.hawk h-017.hawk h-018.hawk h-019.hawk \
|
||||
h-020.hawk h-021.hawk regress-filename.sh
|
||||
h-020.hawk h-021.hawk h-022.hawk h-023.hawk regress-filename.sh
|
||||
check_ERRORS = e-001.err
|
||||
EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \
|
||||
journal-toc.hawk journal-toc.in journal-toc.out journal-toc-html.out \
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
@pragma implicit off
|
||||
@pragma pedantic on
|
||||
@pragma entry main
|
||||
@pragma xcall on
|
||||
|
||||
@include "tap.inc";
|
||||
|
||||
@global G = func(a, b) {
|
||||
return a + b
|
||||
}
|
||||
|
||||
@global seq;
|
||||
|
||||
function mark(v)
|
||||
{
|
||||
seq = seq sprintf("%d", v);
|
||||
return v;
|
||||
}
|
||||
|
||||
function pair(a, b)
|
||||
{
|
||||
return a * 10 + b;
|
||||
}
|
||||
|
||||
function zero()
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
function bump(&x)
|
||||
{
|
||||
x += 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
@local v, s, f;
|
||||
|
||||
seq = "";
|
||||
tap_ensure(pair(mark(1), mark(2)), 12, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(seq, "12", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_ensure(zero(), 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
s = sprintf("%d/%d", pair(3, 4), zero());
|
||||
tap_ensure(s, "34/7", @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_ensure(G(5, 6), 11, @SCRIPTNAME, @SCRIPTLINE);
|
||||
f = G;
|
||||
tap_ensure(f(7, 8), 15, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
v = 9;
|
||||
tap_ensure(bump(v), 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(v, 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_end();
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
@pragma entry main
|
||||
@pragma implicit off
|
||||
|
||||
@include "tap.inc";
|
||||
|
||||
@global g_calls = 0;
|
||||
|
||||
function tick (v)
|
||||
{
|
||||
g_calls = g_calls + 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
function main ()
|
||||
{
|
||||
@local i, j, k, l, m, n, o, p, q, r;
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = 0;
|
||||
l = 0;
|
||||
m = 0;
|
||||
n = 0;
|
||||
o = 0;
|
||||
p = 0;
|
||||
q = 0;
|
||||
r = 0;
|
||||
|
||||
while (0) { i = i + 1; }
|
||||
while (@false) { j = j + 1; }
|
||||
while ((0)) { k = k + 1; }
|
||||
while ((@false)) { l = l + 1; }
|
||||
|
||||
tap_ensure(i, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(j, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(k, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(l, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
if ((1, 0))
|
||||
m = 1;
|
||||
else
|
||||
m = 2;
|
||||
|
||||
if (((0, "", 5)))
|
||||
n = 1;
|
||||
else
|
||||
n = 2;
|
||||
|
||||
if (((1, 2, @false)))
|
||||
o = 1;
|
||||
else
|
||||
o = 2;
|
||||
|
||||
if ((((1, 2), (3, 4), 0)))
|
||||
p = 1;
|
||||
else
|
||||
p = 2;
|
||||
|
||||
while ((1, 0)) { q = q + 1; }
|
||||
while ((((1, 2), (3, 4), 0))) { r = r + 1; }
|
||||
|
||||
tap_ensure(m, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(n, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(o, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(p, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(q, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(r, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_ensure(2 ^ 10, 1024, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 ^ -3, 0.125, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(7.5 \ 2, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(8.5 / 2, 4.25, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(17 % 5, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(17.5 % 5, 2.5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(6 & 3, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(6 ^^ 3, 5, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(6 | 3, 7, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(3 << 4, 48, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(48 >> 4, 3, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(6.9 & 3, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(8 >> 1.9, 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 == 2.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 != 2.0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 < 2.5, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2.5 >= 2, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 === 2.0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(2 !== 2.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!@true === @false, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!@false === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!@nil === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!"" === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!"x" === @false, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!@b"" === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!@b"x" === @false, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!((1, 0)) === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(!((1, 2, "x")) === @false, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
g_calls = 0;
|
||||
if ((tick(1), 0))
|
||||
m = 10;
|
||||
else
|
||||
m = 20;
|
||||
tap_ensure(m, 20, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(g_calls, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
g_calls = 0;
|
||||
if ((((1, tick(0))), 1))
|
||||
n = 10;
|
||||
else
|
||||
n = 20;
|
||||
tap_ensure(n, 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(g_calls, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
g_calls = 0;
|
||||
while ((tick(1), 0)) { o = o + 1; }
|
||||
tap_ensure(o, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(g_calls, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
g_calls = 0;
|
||||
tap_ensure(!(tick(1), 0) === @true, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
tap_ensure(g_calls, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||
|
||||
tap_end ();
|
||||
}
|
||||
Reference in New Issue
Block a user