diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 15:19:14 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-02 15:21:36 +0200 |
commit | 640212ae0ea8a1b47cd73a080d77b25b9f3ccd40 (patch) | |
tree | 4bdd98a112118c2a79e073ab6ca474fc7004c30d /editors | |
parent | ef5463cf16f88c0992b2073a30ab6081c86fdf23 (diff) |
awk: do not special-case "delete"
Rework of the previous fix:
Can use operation attributes to disable arg evaluation instead of special-casing.
function old new delta
.rodata 104032 104036 +4
evaluate 3223 3215 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-8) Total: -4 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/editors/awk.c b/editors/awk.c index 068ed687b..a3dda6959 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -319,7 +319,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \ #define xV OF_RES2 #define xS (OF_RES2 | OF_STR2) #define Vx OF_RES1 -#define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED) +#define Rx OF_REQUIRED #define VV (OF_RES1 | OF_RES2) #define Nx (OF_RES1 | OF_NUM1) #define NV (OF_RES1 | OF_NUM1 | OF_RES2) @@ -2750,32 +2750,6 @@ static var *evaluate(node *op, var *res) op1 = op->l.n; debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn); - /* "delete" is special: - * "delete array[var--]" must evaluate index expr only once, - * must not evaluate it in "execute inevitable things" part. - */ - if (XC(opinfo & OPCLSMASK) == XC(OC_DELETE)) { - uint32_t info = op1->info & OPCLSMASK; - var *v; - - debug_printf_eval("DELETE\n"); - if (info == OC_VAR) { - v = op1->l.v; - } else if (info == OC_FNARG) { - v = &fnargs[op1->l.aidx]; - } else { - syntax_error(EMSG_NOT_ARRAY); - } - if (op1->r.n) { /* array ref? */ - const char *s; - s = getvar_s(evaluate(op1->r.n, TMPVAR0)); - hash_remove(iamarray(v), s); - } else { - clear_array(iamarray(v)); - } - goto next; - } - /* execute inevitable things */ if (opinfo & OF_RES1) L.v = evaluate(op1, TMPVAR0); @@ -2905,7 +2879,31 @@ static var *evaluate(node *op, var *res) break; } - /* case XC( OC_DELETE ): - moved to happen before arg evaluation */ + case XC( OC_DELETE ): + debug_printf_eval("DELETE\n"); + { + /* "delete" is special: + * "delete array[var--]" must evaluate index expr only once. + */ + uint32_t info = op1->info & OPCLSMASK; + var *v; + + if (info == OC_VAR) { + v = op1->l.v; + } else if (info == OC_FNARG) { + v = &fnargs[op1->l.aidx]; + } else { + syntax_error(EMSG_NOT_ARRAY); + } + if (op1->r.n) { /* array ref? */ + const char *s; + s = getvar_s(evaluate(op1->r.n, TMPVAR0)); + hash_remove(iamarray(v), s); + } else { + clear_array(iamarray(v)); + } + break; + } case XC( OC_NEWSOURCE ): debug_printf_eval("NEWSOURCE\n"); @@ -3342,7 +3340,7 @@ static var *evaluate(node *op, var *res) default: syntax_error(EMSG_POSSIBLE_ERROR); } /* switch */ - next: + if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS) op = op->a.n; if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS) |