diff options
Diffstat (limited to 'interpret.h')
-rw-r--r-- | interpret.h | 81 |
1 files changed, 34 insertions, 47 deletions
diff --git a/interpret.h b/interpret.h index e9abdffb..50eea9f2 100644 --- a/interpret.h +++ b/interpret.h @@ -144,6 +144,7 @@ top: case Op_push: case Op_push_arg: + case Op_push_arg_untyped: { NODE *save_symbol; bool isparam = false; @@ -175,19 +176,23 @@ top: case Node_var_new: uninitialized_scalar: - m->type = Node_var; - m->var_value = dupnode(Nnull_string); + if (op != Op_push_arg_untyped) { + /* convert untyped to scalar */ + m->type = Node_var; + m->var_value = dupnode(Nnull_string); + } if (do_lint) lintwarn(isparam ? _("reference to uninitialized argument `%s'") : _("reference to uninitialized variable `%s'"), save_symbol->vname); - m = dupnode(Nnull_string); + if (op != Op_push_arg_untyped) + m = dupnode(Nnull_string); PUSH(m); break; case Node_var_array: - if (op == Op_push_arg) + if (op == Op_push_arg || op == Op_push_arg_untyped) PUSH(m); else fatal(_("attempt to use array `%s' in a scalar context"), @@ -439,37 +444,37 @@ uninitialized_scalar: break; case Op_equal: - r = node_Boolean[cmp_scalars() == 0]; + r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) == 0]; UPREF(r); REPLACE(r); break; case Op_notequal: - r = node_Boolean[cmp_scalars() != 0]; + r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) != 0]; UPREF(r); REPLACE(r); break; case Op_less: - r = node_Boolean[cmp_scalars() < 0]; + r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) < 0]; UPREF(r); REPLACE(r); break; case Op_greater: - r = node_Boolean[cmp_scalars() > 0]; + r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) > 0]; UPREF(r); REPLACE(r); break; case Op_leq: - r = node_Boolean[cmp_scalars() <= 0]; + r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) <= 0]; UPREF(r); REPLACE(r); break; case Op_geq: - r = node_Boolean[cmp_scalars() >= 0]; + r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) >= 0]; UPREF(r); REPLACE(r); break; @@ -611,6 +616,11 @@ mod: REPLACE(r); break; + case Op_unary_plus: + // Force argument to be numeric + t1 = TOP_NUMBER(); + break; + case Op_store_sub: /* * array[sub] assignment optimization, @@ -709,7 +719,7 @@ mod: if (t1 != t2 && t1->valref == 1 && (t1->flags & MPFN) == 0) { size_t nlen = t1->stlen + t2->stlen; - erealloc(t1->stptr, char *, nlen + 2, "r_interpret"); + erealloc(t1->stptr, char *, nlen + 1, "r_interpret"); memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen); t1->stlen = nlen; t1->stptr[nlen] = '\0'; @@ -719,7 +729,7 @@ mod: size_t wlen = t1->wstlen + t2->wstlen; erealloc(t1->wstptr, wchar_t *, - sizeof(wchar_t) * (wlen + 2), "r_interpret"); + sizeof(wchar_t) * (wlen + 1), "r_interpret"); memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen); t1->wstlen = wlen; t1->wstptr[wlen] = L'\0'; @@ -730,9 +740,10 @@ mod: size_t nlen = t1->stlen + t2->stlen; char *p; - emalloc(p, char *, nlen + 2, "r_interpret"); + emalloc(p, char *, nlen + 1, "r_interpret"); memcpy(p, t1->stptr, t1->stlen); memcpy(p + t1->stlen, t2->stptr, t2->stlen); + /* N.B. No NUL-termination required, since make_str_node will do it. */ unref(*lhs); t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED); } @@ -826,12 +837,11 @@ mod: t2 = TOP_SCALAR(); /* switch expression */ t2 = force_string(t2); rp = re_update(m); - di = (research(rp, t2->stptr, 0, t2->stlen, - avoid_dfa(m, t2->stptr, t2->stlen)) >= 0); + di = (research(rp, t2->stptr, 0, t2->stlen, RE_NO_FLAGS) >= 0); } else { t1 = POP_SCALAR(); /* case value */ t2 = TOP_SCALAR(); /* switch expression */ - di = (cmp_nodes(t2, t1) == 0); + di = (cmp_nodes(t2, t1, true) == 0); DEREF(t1); } @@ -942,16 +952,12 @@ arrayfor: break; case Op_ext_builtin: - case Op_old_ext_builtin: { int arg_count = pc->expr_count; awk_value_t result; PUSH_CODE(pc); - if (op == Op_ext_builtin) - r = awk_value_to_node(pc->extfunc(arg_count, & result)); - else - r = pc->builtin(arg_count); + r = awk_value_to_node(pc->extfunc(arg_count, & result)); (void) POP_CODE(); while (arg_count-- > 0) { t1 = POP(); @@ -994,20 +1000,7 @@ arrayfor: t1 = *get_field(0, (Func_ptr *) 0); match_re: rp = re_update(m); - /* - * Any place where research() is called with a last parameter of - * zero, we need to use the avoid_dfa test. This appears here and - * in the code for Op_K_case. - * - * A new or improved dfa that distinguishes beginning/end of - * string from beginning/end of line will allow us to get rid of - * this hack. - * - * The avoid_dfa() function is in re.c; it is not very smart. - */ - - di = research(rp, t1->stptr, 0, t1->stlen, - avoid_dfa(m, t1->stptr, t1->stlen)); + di = research(rp, t1->stptr, 0, t1->stlen, RE_NO_FLAGS); di = (di == -1) ^ (op != Op_nomatch); if (op != Op_match_rec) { decr_sp(); @@ -1078,8 +1071,7 @@ match_re: PUSH(r); break; } else if (f->type != Node_func) { - if ( f->type == Node_ext_func - || f->type == Node_old_ext_func) { + if (f->type == Node_ext_func) { /* code copied from below, keep in sync */ INSTRUCTION *bc; char *fname = pc->func_name; @@ -1090,10 +1082,7 @@ match_re: bc = f->code_ptr; assert(bc->opcode == Op_symbol); - if (f->type == Node_ext_func) - npc[0].opcode = Op_ext_builtin; /* self modifying code */ - else - npc[0].opcode = Op_old_ext_builtin; /* self modifying code */ + npc[0].opcode = Op_ext_builtin; /* self modifying code */ npc[0].extfunc = bc->extfunc; npc[0].expr_count = arg_count; /* actual argument count */ npc[1] = pc[1]; @@ -1119,12 +1108,12 @@ match_re: f = pc->func_body; if (f == NULL) { f = lookup(pc->func_name); - if (f == NULL || (f->type != Node_func && f->type != Node_ext_func && f->type != Node_old_ext_func)) + if (f == NULL || (f->type != Node_func && f->type != Node_ext_func)) fatal(_("function `%s' not defined"), pc->func_name); pc->func_body = f; /* save for next call */ } - if (f->type == Node_ext_func || f->type == Node_old_ext_func) { + if (f->type == Node_ext_func) { /* keep in sync with indirect call code */ INSTRUCTION *bc; char *fname = pc->func_name; @@ -1132,10 +1121,7 @@ match_re: bc = f->code_ptr; assert(bc->opcode == Op_symbol); - if (f->type == Node_ext_func) - pc->opcode = Op_ext_builtin; /* self modifying code */ - else - pc->opcode = Op_old_ext_builtin; /* self modifying code */ + pc->opcode = Op_ext_builtin; /* self modifying code */ pc->extfunc = bc->extfunc; pc->expr_count = arg_count; /* actual argument count */ (pc + 1)->func_name = fname; /* name of the builtin */ @@ -1417,6 +1403,7 @@ match_re: case Op_K_if: case Op_K_else: case Op_cond_exp: + case Op_comment: break; default: |