aboutsummaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2010-11-22 21:05:09 +0200
committerArnold D. Robbins <arnold@skeeve.com>2010-11-22 21:05:09 +0200
commit8bfefd698dfeec91e11d9dc7da9658b1d9c59a7a (patch)
tree3cbe58cafd7664d670ddea561721acc058ff8810 /eval.c
parent72e119f16dd53b93638cbc713d9325ef9ddb0f0c (diff)
downloadegawk-8bfefd698dfeec91e11d9dc7da9658b1d9c59a7a.tar.gz
egawk-8bfefd698dfeec91e11d9dc7da9658b1d9c59a7a.tar.bz2
egawk-8bfefd698dfeec91e11d9dc7da9658b1d9c59a7a.zip
Fixes from John Haque.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c211
1 files changed, 114 insertions, 97 deletions
diff --git a/eval.c b/eval.c
index 5279f245..6c5aaeda 100644
--- a/eval.c
+++ b/eval.c
@@ -1390,6 +1390,96 @@ eval_condition(NODE *t)
return (t->stlen != 0);
}
+/* cmp_scalar -- compare two nodes on the stack */
+
+static inline int
+cmp_scalar()
+{
+ NODE *t1, *t2;
+ int di;
+
+ t2 = POP_SCALAR();
+ t1 = TOP();
+ if (t1->type == Node_var_array) {
+ DEREF(t2);
+ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t1));
+ }
+ di = cmp_nodes(t1, t2);
+ DEREF(t1);
+ DEREF(t2);
+ return di;
+}
+
+/* op_assign --- assignment operators excluding = */
+
+static void
+op_assign(OPCODE op)
+{
+ NODE **lhs;
+ NODE *r;
+ AWKNUM x, x1, x2;
+#ifdef _CRAY
+ long lx;
+#endif
+
+ lhs = POP_ADDRESS();
+ x1 = force_number(*lhs);
+ TOP_NUMBER(x2);
+ unref(*lhs);
+ switch (op) {
+ case Op_assign_plus:
+ r = *lhs = make_number(x1 + x2);
+ break;
+ case Op_assign_minus:
+ r = *lhs = make_number(x1 - x2);
+ break;
+ case Op_assign_times:
+ r = *lhs = make_number(x1 * x2);
+ break;
+ case Op_assign_quotient:
+ if (x2 == (AWKNUM) 0) {
+ decr_sp();
+ fatal(_("division by zero attempted in `/='"));
+ }
+#ifdef _CRAY
+ /* special case for integer division, put in for Cray */
+ lx = x2;
+ if (lx == 0) {
+ r = *lhs = make_number(x1 / x2);
+ break;
+ }
+ lx = (long) x1 / lx;
+ if (lx * x1 == x2)
+ r = *lhs = make_number((AWKNUM) lx);
+ else
+#endif /* _CRAY */
+ r = *lhs = make_number(x1 / x2);
+ break;
+ case Op_assign_mod:
+ if (x2 == (AWKNUM) 0) {
+ decr_sp();
+ fatal(_("division by zero attempted in `%%='"));
+ }
+#ifdef HAVE_FMOD
+ r = *lhs = make_number(fmod(x1, x2));
+#else /* ! HAVE_FMOD */
+ (void) modf(x1 / x2, &x);
+ x = x1 - x2 * x;
+ r = *lhs = make_number(x);
+#endif /* ! HAVE_FMOD */
+ break;
+ case Op_assign_exp:
+ r = *lhs = make_number((AWKNUM) calc_exp((double) x1, (double) x2));
+ break;
+ default:
+ break;
+ }
+
+ UPREF(r);
+ REPLACE(r);
+}
+
+
/* PUSH_CODE --- push a code onto the runtime stack */
void
@@ -1748,40 +1838,34 @@ top:
break;
case Op_equal:
-
-/* compare two nodes on the stack */
-#define compare(X, Y) \
-t2 = POP_SCALAR(); \
-t1 = TOP_SCALAR(); \
-X = cmp_nodes(t1, t2); \
-DEREF(t1); \
-DEREF(t2); \
-r = make_number((AWKNUM) (Y)); \
-REPLACE(r);
-
- compare(di, di == 0);
+ r = make_number((AWKNUM) (cmp_scalar() == 0));
+ REPLACE(r);
break;
case Op_notequal:
- compare(di, di != 0);
+ r = make_number((AWKNUM) (cmp_scalar() != 0));
+ REPLACE(r);
break;
case Op_less:
- compare(di, di < 0);
+ r = make_number((AWKNUM) (cmp_scalar() < 0));
+ REPLACE(r);
break;
case Op_greater:
- compare(di, di > 0);
+ r = make_number((AWKNUM) (cmp_scalar() > 0));
+ REPLACE(r);
break;
case Op_leq:
- compare(di, di <= 0);
+ r = make_number((AWKNUM) (cmp_scalar() <= 0));
+ REPLACE(r);
break;
case Op_geq:
- compare(di, di >= 0);
+ r = make_number((AWKNUM) (cmp_scalar() >= 0));
+ REPLACE(r);
break;
-#undef compare
case Op_plus_i:
x2 = force_number(pc->memory);
@@ -1839,11 +1923,10 @@ exponent:
case Op_quotient:
POP_NUMBER(x2);
quotient:
- TOP_NUMBER(x1);
- if (x2 == 0) {
- decr_sp();
+ if (x2 == 0)
fatal(_("division by zero attempted"));
- }
+
+ TOP_NUMBER(x1);
#ifdef _CRAY
/* special case for integer division, put in for Cray */
lx2 = x2;
@@ -1870,12 +1953,10 @@ quotient:
case Op_mod:
POP_NUMBER(x2);
mod:
- TOP_NUMBER(x1);
-
- if (x2 == 0) {
- decr_sp();
+ if (x2 == 0)
fatal(_("division by zero attempted in `%%'"));
- }
+
+ TOP_NUMBER(x1);
#ifdef HAVE_FMOD
x = fmod(x1, x2);
#else /* ! HAVE_FMOD */
@@ -1949,7 +2030,7 @@ post:
*/
Func_ptr assign;
- t1 = TOP();
+ t1 = TOP_SCALAR();
lhs = r_get_field(t1, &assign, FALSE);
decr_sp();
DEREF(t1);
@@ -1970,7 +2051,7 @@ post:
if (t1 != t2 && t1->valref == 1 && (t1->flags & PERM) == 0) {
size_t nlen = t1->stlen + t2->stlen;
- erealloc(t1->stptr, char *, nlen + 2, "interpret");
+ erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
t1->stlen = nlen;
t1->stptr[nlen] = '\0';
@@ -1978,7 +2059,7 @@ post:
size_t nlen = t1->stlen + t2->stlen;
char *p;
- emalloc(p, char *, nlen + 2, "interpret");
+ emalloc(p, char *, nlen + 2, "r_interpret");
memcpy(p, t1->stptr, t1->stlen);
memcpy(p + t1->stlen, t2->stptr, t2->stlen);
unref(*lhs);
@@ -1997,79 +2078,16 @@ post:
REPLACE(r);
break;
+ /* numeric assignments */
case Op_assign_plus:
-#define assign_common(X, Y) \
-lhs = POP_ADDRESS(); \
-X = force_number(*lhs); \
-TOP_NUMBER(Y); \
-unref(*lhs)
-
-#define assign(X, Y, Z) \
-assign_common(X, Y); \
-r = *lhs = make_number(Z); \
-UPREF(r); \
-REPLACE(r)
-
- assign(x1, x2, x1 + x2);
- break;
-
case Op_assign_minus:
- assign(x1, x2, x1 - x2);
- break;
-
case Op_assign_times:
- assign(x1, x2, x1 * x2);
- break;
-
case Op_assign_quotient:
- assign_common(x1, x2);
- if (x2 == (AWKNUM) 0) {
- decr_sp();
- fatal(_("division by zero attempted in `/='"));
- }
-#ifdef _CRAY
- /* special case for integer division, put in for Cray */
- lx = x2;
- if (lx == 0) {
- r = *lhs = make_number(x1 / x2);
- UPREF(r);
- REPLACE(r);
- break;
- }
- lx = (long) x1 / lx;
- if (lx * x1 == x2)
- r = *lhs = make_number((AWKNUM) lx);
- else
-#endif /* _CRAY */
- r = *lhs = make_number(x1 / x2);
- UPREF(r);
- REPLACE(r);
- break;
-
case Op_assign_mod:
- assign_common(x1, x2);
- if (x2 == (AWKNUM) 0) {
- decr_sp();
- fatal(_("division by zero attempted in `%%='"));
- }
-#ifdef HAVE_FMOD
- r = *lhs = make_number(fmod(x1, x2));
-#else /* ! HAVE_FMOD */
- (void) modf(x1 / x2, &x);
- x = x1 - x2 * x;
- r = *lhs = make_number(x);
-#endif /* ! HAVE_FMOD */
- UPREF(r);
- REPLACE(r);
- break;
-
case Op_assign_exp:
- assign(x1, x2, (AWKNUM) calc_exp((double) x1, (double) x2));
+ op_assign(pc->opcode);
break;
-#undef assign
-#undef assign_common
-
case Op_var_update: /* update value of NR, FNR or NF */
pc->memory->var_update();
break;
@@ -2091,7 +2109,6 @@ REPLACE(r)
{
INSTRUCTION *curr;
int match_found = FALSE;
-
t1 = TOP_SCALAR(); /* switch expression */
for (curr = pc->case_val; curr != NULL; curr = curr->nexti) {
if (curr->opcode == Op_K_case) {
@@ -2471,7 +2488,7 @@ func_call:
ni = POP_CODE(); /* Op_newfile */
ni = ni->target_jmp; /* end_block or Op_atexit */
} else if (inrec(curfile) == 0)
- break; /* prog block */
+ break; /* prog(rule) block */
else
ni = POP_CODE(); /* Op_newfile */
JUMPTO(ni);