diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 69065a69..86c12c55 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -399,7 +399,7 @@ enum hawk_nde_type_t /* expression */ /* if you change the following values including their order, - * you should change __evaluator of __eval_expression + * you should change __evaluator of eval_expression0() * in run.c accordingly */ HAWK_NDE_GRP, HAWK_NDE_ASS, @@ -416,6 +416,7 @@ enum hawk_nde_type_t HAWK_NDE_STR, HAWK_NDE_MBS, HAWK_NDE_REX, + HAWK_NDE_XNIL, HAWK_NDE_FUN, /* keep this order for the following items otherwise, you may have diff --git a/hawk/lib/parse-prv.h b/hawk/lib/parse-prv.h index 0f1cb55a..564004a8 100644 --- a/hawk/lib/parse-prv.h +++ b/hawk/lib/parse-prv.h @@ -35,6 +35,7 @@ enum hawk_kwid_t HAWK_KWID_XINCLUDE, HAWK_KWID_XINCLUDE_ONCE, HAWK_KWID_XLOCAL, + HAWK_KWID_XNIL, HAWK_KWID_XPRAGMA, HAWK_KWID_XRESET, HAWK_KWID_BEGIN, diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index 8ba9ddce..158bdfe6 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -178,6 +178,7 @@ enum tok_t TOK_STR, TOK_MBS, TOK_REX, + TOK_XNIL, __TOKEN_COUNT__ }; @@ -281,13 +282,14 @@ struct kwent_t static kwent_t kwtab[] = { - /* keep this table in sync with the kw_t enums in . + /* keep this table in sync with the kw_t enums in "parse-prv.h". * also keep it sorted by the first field for binary search */ { { HAWK_T("@abort"), 6 }, TOK_XABORT, 0 }, { { HAWK_T("@global"), 7 }, TOK_XGLOBAL, 0 }, { { HAWK_T("@include"), 8 }, TOK_XINCLUDE, 0 }, { { HAWK_T("@include_once"), 13 }, TOK_XINCLUDE_ONCE, 0 }, { { HAWK_T("@local"), 6 }, TOK_XLOCAL, 0 }, + { { HAWK_T("@nil"), 4 }, TOK_XNIL, 0 }, { { HAWK_T("@pragma"), 7 }, TOK_XPRAGMA, 0 }, { { HAWK_T("@reset"), 6 }, TOK_XRESET, 0 }, { { HAWK_T("BEGIN"), 5 }, TOK_BEGIN, HAWK_PABLOCK }, @@ -1566,7 +1568,7 @@ static hawk_nde_t* parse_function (hawk_t* hawk) hawk_arr_clear (hawk->parse.params); fun = (hawk_fun_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*fun)); - if (fun == HAWK_NULL) + if (HAWK_UNLIKELY(!fun)) { ADJERR_LOC (hawk, &hawk->tok.loc); goto oops; @@ -1579,7 +1581,7 @@ static hawk_nde_t* parse_function (hawk_t* hawk) fun->body = body; pair = hawk_htb_insert(hawk->tree.funs, name.ptr, name.len, fun, 0); - if (pair == HAWK_NULL) + if (HAWK_UNLIKELY(!pair)) { /* if hawk_htb_insert() fails for other reasons than memory * shortage, there should be implementaion errors as duplicate @@ -1616,8 +1618,8 @@ static hawk_nde_t* parse_begin (hawk_t* hawk) HAWK_ASSERT (MATCH(hawk,TOK_LBRACE)); if (get_token(hawk) <= -1) return HAWK_NULL; - nde = parse_block_dc (hawk, &xloc, 1); - if (nde == HAWK_NULL) return HAWK_NULL; + nde = parse_block_dc(hawk, &xloc, 1); + if (HAWK_UNLIKELY(!nde)) return HAWK_NULL; if (hawk->tree.begin == HAWK_NULL) { @@ -1642,8 +1644,8 @@ static hawk_nde_t* parse_end (hawk_t* hawk) HAWK_ASSERT (MATCH(hawk,TOK_LBRACE)); if (get_token(hawk) <= -1) return HAWK_NULL; - nde = parse_block_dc (hawk, &xloc, 1); - if (nde == HAWK_NULL) return HAWK_NULL; + nde = parse_block_dc(hawk, &xloc, 1); + if (HAWK_UNLIKELY(!nde)) return HAWK_NULL; if (hawk->tree.end == HAWK_NULL) { @@ -1658,8 +1660,7 @@ static hawk_nde_t* parse_end (hawk_t* hawk) return nde; } -static hawk_chain_t* parse_action_block ( - hawk_t* hawk, hawk_nde_t* ptn, int blockless) +static hawk_chain_t* parse_action_block (hawk_t* hawk, hawk_nde_t* ptn, int blockless) { hawk_nde_t* nde; hawk_chain_t* chain; @@ -1672,11 +1673,11 @@ static hawk_chain_t* parse_action_block ( HAWK_ASSERT (MATCH(hawk,TOK_LBRACE)); if (get_token(hawk) <= -1) return HAWK_NULL; nde = parse_block_dc(hawk, &xloc, 1); - if (nde == HAWK_NULL) return HAWK_NULL; + if (HAWK_UNLIKELY(!nde)) return HAWK_NULL; } chain = (hawk_chain_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*chain)); - if (chain == HAWK_NULL) + if (HAWK_UNLIKELY(!chain)) { hawk_clrpt (hawk, nde); ADJERR_LOC (hawk, &xloc); @@ -1749,13 +1750,13 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) /* @local ... */ if (get_token(hawk) <= -1) { - hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); + hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls) - nlcls); return HAWK_NULL; } - if (collect_locals (hawk, nlcls, istop) == HAWK_NULL) + if (collect_locals(hawk, nlcls, istop) == HAWK_NULL) { - hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); + hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls) - nlcls); return HAWK_NULL; } } @@ -1776,10 +1777,8 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) /* if EOF is met before the right brace, this is an error */ if (MATCH(hawk,TOK_EOF)) { - hawk_arr_delete ( - hawk->parse.lcls, nlcls, - HAWK_ARR_SIZE(hawk->parse.lcls) - nlcls); - if (head != HAWK_NULL) hawk_clrpt (hawk, head); + hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls) - nlcls); + if (head) hawk_clrpt (hawk, head); hawk_seterrnum (hawk, &hawk->tok.loc, HAWK_EEOF); return HAWK_NULL; } @@ -1789,10 +1788,8 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) { if (get_token(hawk) <= -1) { - hawk_arr_delete ( - hawk->parse.lcls, nlcls, - HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); - if (head != HAWK_NULL) hawk_clrpt (hawk, head); + hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); + if (head) hawk_clrpt (hawk, head); return HAWK_NULL; } @@ -1827,14 +1824,12 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) { hawk_loc_t sloc; sloc = hawk->tok.loc; - nde = parse_statement (hawk, &sloc); + nde = parse_statement(hawk, &sloc); } if (HAWK_UNLIKELY(!nde)) { - hawk_arr_delete ( - hawk->parse.lcls, nlcls, - HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); + hawk_arr_delete (hawk->parse.lcls, nlcls, HAWK_ARR_SIZE(hawk->parse.lcls)-nlcls); if (head) hawk_clrpt (hawk, head); return HAWK_NULL; } @@ -1846,8 +1841,7 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) hawk_clrpt (hawk, nde); continue; } - if (nde->type == HAWK_NDE_BLK && - ((hawk_nde_blk_t*)nde)->body == HAWK_NULL) + if (nde->type == HAWK_NDE_BLK && ((hawk_nde_blk_t*)nde)->body == HAWK_NULL) { hawk_clrpt (hawk, nde); continue; @@ -1871,7 +1865,7 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int istop) tmp = HAWK_ARR_SIZE(hawk->parse.lcls); if (tmp > hawk->parse.nlcls_max) hawk->parse.nlcls_max = tmp; - /* remove all lcls to move it up to the top level */ + /* remove all lcls to move them up to the top level */ hawk_arr_delete (hawk->parse.lcls, nlcls, tmp - nlcls); /* adjust the number of lcls for a block without any statements */ @@ -1904,6 +1898,7 @@ static hawk_nde_t* parse_block_dc (hawk_t* hawk, const hawk_loc_t* xloc, int ist { hawk_nde_t* nde; + /* perform the depth check before calling parse_block() */ if (hawk->opt.depth.s.block_parse > 0 && hawk->parse.depth.block >= hawk->opt.depth.s.block_parse) { @@ -3015,11 +3010,9 @@ static hawk_nde_t* parse_delete (hawk_t* hawk, const hawk_loc_t* xloc) hawk_nde_type_t type; int inparen = 0; - HAWK_ASSERT (hawk->ptok.type == TOK_DELETE || - hawk->ptok.type == TOK_XRESET); + HAWK_ASSERT (hawk->ptok.type == TOK_DELETE || hawk->ptok.type == TOK_XRESET); - type = (hawk->ptok.type == TOK_DELETE)? - HAWK_NDE_DELETE: HAWK_NDE_RESET; + type = (hawk->ptok.type == TOK_DELETE)? HAWK_NDE_DELETE: HAWK_NDE_RESET; if (MATCH(hawk,TOK_LPAREN)) { @@ -3455,7 +3448,7 @@ static hawk_nde_t* parse_statement (hawk_t* hawk, const hawk_loc_t* xloc) tloc = hawk->ptok.loc; if (get_token(hawk) <= -1) return HAWK_NULL; - nde = parse_block_dc (hawk, &tloc, 0); + nde = parse_block_dc(hawk, &tloc, 0); } else { @@ -4532,8 +4525,8 @@ static hawk_nde_t* parse_increment (hawk_t* hawk, const hawk_loc_t* xloc) } ploc = hawk->tok.loc; - left = parse_primary (hawk, &ploc); - if (left == HAWK_NULL) return HAWK_NULL; + left = parse_primary(hawk, &ploc); + if (HAWK_UNLIKELY(!left)) return HAWK_NULL; /* check for postfix increment operator */ opcode2 = MATCH(hawk,TOK_PLUSPLUS)? HAWK_INCOP_PLUS: @@ -5076,6 +5069,31 @@ oops: return HAWK_NULL; } +static hawk_nde_t* parse_primary_xnil (hawk_t* hawk, const hawk_loc_t* xloc) +{ + hawk_nde_xnil_t* nde; + + nde = (hawk_nde_xnil_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde)); + if (HAWK_UNLIKELY(!nde)) + { + ADJERR_LOC (hawk, xloc); + return HAWK_NULL; + } + + nde->type = HAWK_NDE_XNIL; + nde->loc = *xloc; + + if (get_token(hawk) <= -1) goto oops; + + return (hawk_nde_t*)nde; + +oops: + HAWK_ASSERT (nde != HAWK_NULL); + hawk_freemem (hawk, nde); + return HAWK_NULL; +} + + static hawk_nde_t* parse_primary_nopipe (hawk_t* hawk, const hawk_loc_t* xloc) { switch (hawk->tok.type) @@ -5111,6 +5129,10 @@ static hawk_nde_t* parse_primary_nopipe (hawk_t* hawk, const hawk_loc_t* xloc) case TOK_GETLINE: return parse_primary_getline(hawk, xloc, 0); + case TOK_XNIL: + return parse_primary_xnil(hawk, xloc); + + default: { hawk_tok_t* xtok; diff --git a/hawk/lib/run.c b/hawk/lib/run.c index c9d12c63..6317c06c 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -162,6 +162,7 @@ static hawk_val_t* eval_flt (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_str (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_mbs (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_rex (hawk_rtx_t* rtx, hawk_nde_t* nde); +static hawk_val_t* eval_xnil (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_fun (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_named (hawk_rtx_t* rtx, hawk_nde_t* nde); static hawk_val_t* eval_gbl (hawk_rtx_t* rtx, hawk_nde_t* nde); @@ -3621,6 +3622,7 @@ static hawk_val_t* eval_expression0 (hawk_rtx_t* rtx, hawk_nde_t* nde) eval_str, eval_mbs, eval_rex, + eval_xnil, eval_fun, eval_named, eval_gbl, @@ -6892,7 +6894,7 @@ static hawk_val_t* eval_int (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_val_t* val; val = hawk_rtx_makeintval(rtx, ((hawk_nde_int_t*)nde)->val); - if (val == HAWK_NULL) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); else if (HAWK_VTR_IS_POINTER(val)) ((hawk_val_int_t*)val)->nde = nde; return val; } @@ -6901,7 +6903,7 @@ static hawk_val_t* eval_flt (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_val_t* val; val = hawk_rtx_makefltval(rtx, ((hawk_nde_flt_t*)nde)->val); - if (val == HAWK_NULL) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); else ((hawk_val_flt_t*)val)->nde = nde; return val; } @@ -6910,7 +6912,7 @@ static hawk_val_t* eval_str (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_val_t* val; val = hawk_rtx_makestrvalwithoochars(rtx, ((hawk_nde_str_t*)nde)->ptr, ((hawk_nde_str_t*)nde)->len); - if (val == HAWK_NULL) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); return val; } @@ -6918,7 +6920,7 @@ static hawk_val_t* eval_mbs (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_val_t* val; val = hawk_rtx_makembsvalwithbchars(rtx, ((hawk_nde_mbs_t*)nde)->ptr, ((hawk_nde_mbs_t*)nde)->len); - if (val == HAWK_NULL) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); return val; } @@ -6926,7 +6928,15 @@ static hawk_val_t* eval_rex (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_val_t* val; val = hawk_rtx_makerexval(rtx, &((hawk_nde_rex_t*)nde)->str, ((hawk_nde_rex_t*)nde)->code); - if (val == HAWK_NULL) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); + return val; +} + +static hawk_val_t* eval_xnil (hawk_rtx_t* rtx, hawk_nde_t* nde) +{ + hawk_val_t* val; + val = hawk_rtx_makenilval(rtx); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); return val; } @@ -6958,7 +6968,7 @@ static hawk_val_t* eval_fun (hawk_rtx_t* rtx, hawk_nde_t* nde) } val = hawk_rtx_makefunval(rtx, fun); - if (!val) ADJERR_LOC (rtx, &nde->loc); + if (HAWK_UNLIKELY(!val)) ADJERR_LOC (rtx, &nde->loc); return val; } diff --git a/hawk/lib/tree-prv.h b/hawk/lib/tree-prv.h index de4cfe83..4335a530 100644 --- a/hawk/lib/tree-prv.h +++ b/hawk/lib/tree-prv.h @@ -63,6 +63,7 @@ typedef struct hawk_nde_str_t hawk_nde_str_t; typedef struct hawk_nde_mbs_t hawk_nde_mbs_t; typedef struct hawk_nde_rex_t hawk_nde_rex_t; typedef struct hawk_nde_fun_t hawk_nde_fun_t; +typedef struct hawk_nde_xnil_t hawk_nde_xnil_t; typedef struct hawk_nde_var_t hawk_nde_var_t; typedef struct hawk_nde_fncall_t hawk_nde_fncall_t; @@ -174,6 +175,11 @@ struct hawk_nde_rex_t hawk_tre_t* code[2]; /* [0]: case sensitive, [1]: case insensitive */ }; +struct hawk_nde_xnil_t +{ + HAWK_NDE_HDR; +}; + /* HAWK_NDE_FUN - function as a value */ struct hawk_nde_fun_t { diff --git a/hawk/lib/tree.c b/hawk/lib/tree.c index 234e0f6b..ac21bc40 100644 --- a/hawk/lib/tree.c +++ b/hawk/lib/tree.c @@ -498,6 +498,12 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde) break; } + case HAWK_NDE_XNIL: + { + PUT_SRCSTR (hawk, HAWK_T("@nil")); + break; + } + case HAWK_NDE_FUN: { PUT_SRCSTRN (hawk, @@ -715,9 +721,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde) PUT_SRCSTR (hawk, HAWK_T("(")); - if (px->in != HAWK_NULL && - (px->in_type == HAWK_IN_PIPE || - px->in_type == HAWK_IN_RWPIPE)) + if (px->in && (px->in_type == HAWK_IN_PIPE || px->in_type == HAWK_IN_RWPIPE)) { PRINT_EXPR (hawk, px->in); PUT_SRCSTR (hawk, HAWK_T(" ")); @@ -727,14 +731,13 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde) hawk_getkwname (hawk, (px->mbs? HAWK_KWID_GETBLINE: HAWK_KWID_GETLINE), &kw); PUT_SRCSTRN (hawk, kw.ptr, kw.len); - if (px->var != HAWK_NULL) + if (px->var) { PUT_SRCSTR (hawk, HAWK_T(" ")); PRINT_EXPR (hawk, px->var); } - if (px->in != HAWK_NULL && - px->in_type == HAWK_IN_FILE) + if (px->in && px->in_type == HAWK_IN_FILE) { PUT_SRCSTR (hawk, HAWK_T(" ")); PUT_SRCSTR (hawk, getline_inop_str[px->in_type]); @@ -750,7 +753,7 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde) case HAWK_NDE_PRINTF: { PUT_SRCSTR (hawk, HAWK_T("(")); - if (print_printx (hawk, (hawk_nde_print_t*)nde) <= -1) return -1; + if (print_printx(hawk, (hawk_nde_print_t*)nde) <= -1) return -1; PUT_SRCSTR (hawk, HAWK_T(")")); break; } @@ -1385,6 +1388,12 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree) break; } + case HAWK_NDE_XNIL: + { + hawk_freemem (hawk, p); + break; + } + case HAWK_NDE_FUN: { hawk_freemem (hawk, ((hawk_nde_fun_t*)p)->name.ptr); diff --git a/hawk/t/h-002.hawk b/hawk/t/h-002.hawk index 59ea09c5..9fd737ed 100644 --- a/hawk/t/h-002.hawk +++ b/hawk/t/h-002.hawk @@ -244,7 +244,7 @@ function main() { @local bool, b, c; - @reset(c); + c = @nil; bool = ((b = 1) in c); ensure (bool, 0, @SCRIPTNAME, @SCRIPTLINE); ensure (b, 1, @SCRIPTNAME, @SCRIPTLINE);