From 1c2bab8289f901c9981eca63f426291ade9b1836 Mon Sep 17 00:00:00 2001 From: Emden Gansner Date: Wed, 15 Feb 2012 11:28:38 -0500 Subject: [PATCH] Update libexpr to include Glenn's more recent additions, including variable scopes; reverted back to Glenn's format so that future diffs and updates will be easier. --- lib/expr/Makefile.am | 2 +- lib/expr/excc.c | 1254 ++++++++--------- lib/expr/excontext.c | 76 +- lib/expr/exdata.c | 89 +- lib/expr/exerror.c | 76 +- lib/expr/exeval.c | 3183 +++++++++++++++++++++--------------------- lib/expr/exexpr.c | 31 +- lib/expr/exgram.h | 1205 ++++++++-------- lib/expr/exlexname.c | 46 +- lib/expr/exlib.h | 142 +- lib/expr/exopen.c | 71 +- lib/expr/exparse.y | 225 +-- lib/expr/expr.h | 445 +++--- lib/expr/exrewind.c | 56 +- lib/expr/extoken.c | 1485 ++++++++++---------- lib/expr/extype.c | 22 +- lib/expr/exzero.c | 35 +- 17 files changed, 4294 insertions(+), 4149 deletions(-) diff --git a/lib/expr/Makefile.am b/lib/expr/Makefile.am index 57881258d..a40a80584 100644 --- a/lib/expr/Makefile.am +++ b/lib/expr/Makefile.am @@ -30,7 +30,7 @@ pdf_DATA = expr.3.pdf libexpr_C_la_SOURCES = excc.c excontext.c exdata.c exerror.c \ exeval.c exexpr.c exlexname.c exopen.c exrewind.c extoken.c \ - extype.c exzero.c exparse.y + extype.c exzero.c exparse.y exnospace.c exstash.c libexpr_C_la_LIBADD = \ $(top_builddir)/lib/ast/libast_C.la \ $(top_builddir)/lib/vmalloc/libvmalloc_C.la \ diff --git a/lib/expr/excc.c b/lib/expr/excc.c index 25020c8a8..f408bb83e 100644 --- a/lib/expr/excc.c +++ b/lib/expr/excc.c @@ -1,5 +1,4 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -22,592 +21,599 @@ char* id; /* prefix + _ */ \ int lastop; /* last op */ \ int tmp; /* temp var index */ \ - Exccdisc_t* ccdisc; /* excc() discipline */ + Exccdisc_t* ccdisc; /* excc() discipline */ #include "exlib.h" #include #define EX_CC_DUMP 0x8000 -static const char quote[] = "\""; +static const char quote[] = "\""; -static void gen(Excc_t *, Exnode_t *); +static void gen(Excc_t*, Exnode_t*); /* * return C name for op */ -char *exopname(int op) +char* +exopname(int op) { - static char buf[16]; - - switch (op) { - case '!': - return "!"; - case '%': - return "%"; - case '&': - return "&"; - case '(': - return "("; - case '*': - return "*"; - case '+': - return "+"; - case ',': - return ","; - case '-': - return "-"; - case '/': - return "/"; - case ':': - return ":"; - case '<': - return "<"; - case '=': - return "="; - case '>': - return ">"; - case '?': - return "?"; - case '^': - return "^"; - case '|': - return "|"; - case '~': - return "~"; - case AND: - return "&&"; - case EQ: - return "=="; - case GE: - return ">="; - case LE: - return "<="; - case LS: - return "<<"; - case NE: - return "!="; - case OR: - return "||"; - case RS: - return ">>"; - } - sfsprintf(buf, sizeof(buf) - 1, "(OP=%03d)", op); - return buf; + static char buf[16]; + + switch (op) + { + case '!': + return "!"; + case '%': + return "%"; + case '&': + return "&"; + case '(': + return "("; + case '*': + return "*"; + case '+': + return "+"; + case ',': + return ","; + case '-': + return "-"; + case '/': + return "/"; + case ':': + return ":"; + case '<': + return "<"; + case '=': + return "="; + case '>': + return ">"; + case '?': + return "?"; + case '^': + return "^"; + case '|': + return "|"; + case '~': + return "~"; + case AND: + return "&&"; + case EQ: + return "=="; + case GE: + return ">="; + case LE: + return "<="; + case LS: + return "<<"; + case NE: + return "!="; + case OR: + return "||"; + case RS: + return ">>"; + } + sfsprintf(buf, sizeof(buf) - 1, "(OP=%03o)", op); + return buf; } /* * generate printf() */ -static void print(Excc_t * cc, Exnode_t * expr) +static void +print(Excc_t* cc, Exnode_t* expr) { - register Print_t *x; - register int i; - - if ((x = expr->data.print.args)) { - sfprintf(cc->ccdisc->text, "sfprintf(%s, \"%s", - expr->data.print.descriptor->op == CONSTANT - && expr->data.print.descriptor->data.constant.value. - integer == 2 ? "sfstderr" : "sfstdout", fmtesq(x->format, - quote)); - while ((x = x->next)) - sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote)); - sfprintf(cc->ccdisc->text, "\""); - for (x = expr->data.print.args; x; x = x->next) { - if (x->arg) { - for (i = 0; i < elementsof(x->param) && x->param[i]; i++) { - sfprintf(cc->ccdisc->text, ", ("); - gen(cc, x->param[i]); - sfprintf(cc->ccdisc->text, ")"); + register Print_t* x; + register int i; + + if ((x = expr->data.print.args)) + { + sfprintf(cc->ccdisc->text, "sfprintf(%s, \"%s", expr->data.print.descriptor->op == CONSTANT && expr->data.print.descriptor->data.constant.value.integer == 2 ? "sfstderr" : "sfstdout", fmtesq(x->format, quote)); + while ((x = x->next)) + sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote)); + sfprintf(cc->ccdisc->text, "\""); + for (x = expr->data.print.args; x; x = x->next) + { + if (x->arg) + { + for (i = 0; i < elementsof(x->param) && x->param[i]; i++) + { + sfprintf(cc->ccdisc->text, ", ("); + gen(cc, x->param[i]); + sfprintf(cc->ccdisc->text, ")"); + } + sfprintf(cc->ccdisc->text, ", ("); + gen(cc, x->arg); + sfprintf(cc->ccdisc->text, ")"); + } } - sfprintf(cc->ccdisc->text, ", ("); - gen(cc, x->arg); - sfprintf(cc->ccdisc->text, ")"); - } + sfprintf(cc->ccdisc->text, ");\n"); } - sfprintf(cc->ccdisc->text, ");\n"); - } } /* * generate scanf() */ -static void scan(Excc_t * cc, Exnode_t * expr) +static void +scan(Excc_t* cc, Exnode_t* expr) { - register Print_t *x; - register int i; - - if ((x = expr->data.print.args)) { - sfprintf(cc->ccdisc->text, "sfscanf(sfstdin, \"%s", - fmtesq(x->format, quote)); - while ((x = x->next)) - sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote)); - sfprintf(cc->ccdisc->text, "\""); - for (x = expr->data.print.args; x; x = x->next) { - if (x->arg) { - for (i = 0; i < elementsof(x->param) && x->param[i]; i++) { - sfprintf(cc->ccdisc->text, ", &("); - gen(cc, x->param[i]); - sfprintf(cc->ccdisc->text, ")"); + register Print_t* x; + register int i; + + if ((x = expr->data.print.args)) + { + sfprintf(cc->ccdisc->text, "sfscanf(sfstdin, \"%s", fmtesq(x->format, quote)); + while ((x = x->next)) + sfprintf(cc->ccdisc->text, "%s", fmtesq(x->format, quote)); + sfprintf(cc->ccdisc->text, "\""); + for (x = expr->data.print.args; x; x = x->next) + { + if (x->arg) + { + for (i = 0; i < elementsof(x->param) && x->param[i]; i++) + { + sfprintf(cc->ccdisc->text, ", &("); + gen(cc, x->param[i]); + sfprintf(cc->ccdisc->text, ")"); + } + sfprintf(cc->ccdisc->text, ", &("); + gen(cc, x->arg); + sfprintf(cc->ccdisc->text, ")"); + } } - sfprintf(cc->ccdisc->text, ", &("); - gen(cc, x->arg); - sfprintf(cc->ccdisc->text, ")"); - } + sfprintf(cc->ccdisc->text, ");\n"); } - sfprintf(cc->ccdisc->text, ");\n"); - } } /* * internal excc */ -static void gen(Excc_t * cc, register Exnode_t * expr) +static void +gen(Excc_t* cc, register Exnode_t* expr) { - register Exnode_t *x; - register Exnode_t *y; - register int n; - register int m; - register int t; - char *s; - Extype_t *v; - Extype_t **p; - - if (!expr) - return; - if (expr->op == CALL) { - sfprintf(cc->ccdisc->text, "%s(", expr->data.call.procedure->name); - if (expr->data.call.args) - gen(cc, expr->data.call.args); - sfprintf(cc->ccdisc->text, ")"); - return; - } - x = expr->data.operand.left; - switch (expr->op) { - case BREAK: - sfprintf(cc->ccdisc->text, "break;\n"); - return; - case CONTINUE: - sfprintf(cc->ccdisc->text, "continue;\n"); - return; - case CONSTANT: - switch (expr->type) { - case FLOATING: - sfprintf(cc->ccdisc->text, "%g", - expr->data.constant.value.floating); - break; - case STRING: - sfprintf(cc->ccdisc->text, "\"%s\"", - fmtesq(expr->data.constant.value.string, quote)); - break; - case UNSIGNED: - sfprintf(cc->ccdisc->text, "%I*u", - sizeof(expr->data.constant.value.integer), - expr->data.constant.value.integer); - break; - default: - sfprintf(cc->ccdisc->text, "%I*d", - sizeof(expr->data.constant.value.integer), - expr->data.constant.value.integer); - break; - } - return; - case DEC: - sfprintf(cc->ccdisc->text, "%s--", x->data.variable.symbol->name); - return; - case DYNAMIC: - sfprintf(cc->ccdisc->text, "%s", expr->data.variable.symbol->name); - return; - case EXIT: - sfprintf(cc->ccdisc->text, "exit("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ");\n"); - return; - case FUNCTION: - gen(cc, x); - sfprintf(cc->ccdisc->text, "("); - if ((y = expr->data.operand.right)) { - gen(cc, y); - } - sfprintf(cc->ccdisc->text, ")"); - return; - case RAND: - sfprintf(cc->ccdisc->text, "rand();\n"); - return; - case SRAND: - if (expr->binary) { - sfprintf(cc->ccdisc->text, "srand("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ");\n"); - } else - sfprintf(cc->ccdisc->text, "srand();\n"); - return; - case GSUB: - case SUB: - case SUBSTR: - s = (expr->op == GSUB ? "gsub(" : expr->op == - SUB ? "sub(" : "substr("); - sfprintf(cc->ccdisc->text, s); - gen(cc, expr->data.string.base); - sfprintf(cc->ccdisc->text, ", "); - gen(cc, expr->data.string.pat); - if (expr->data.string.repl) { - sfprintf(cc->ccdisc->text, ", "); - gen(cc, expr->data.string.repl); - } - sfprintf(cc->ccdisc->text, ")"); - return; - case IN_OP: - gen(cc, expr->data.variable.index); - sfprintf(cc->ccdisc->text, " in %s", expr->data.variable.symbol->name); - return; - case IF: - sfprintf(cc->ccdisc->text, "if ("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ") {\n"); - gen(cc, expr->data.operand.right->data.operand.left); - if (expr->data.operand.right->data.operand.right) { - sfprintf(cc->ccdisc->text, "} else {\n"); - gen(cc, expr->data.operand.right->data.operand.right); - } - sfprintf(cc->ccdisc->text, "}\n"); - return; - case FOR: - sfprintf(cc->ccdisc->text, "for ("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ");"); - if (expr->data.operand.left) { - sfprintf(cc->ccdisc->text, "("); - gen(cc, expr->data.operand.left); - sfprintf(cc->ccdisc->text, ")"); - } - sfprintf(cc->ccdisc->text, ") {"); - if (expr->data.operand.right) - gen(cc, expr->data.operand.right); - sfprintf(cc->ccdisc->text, "}"); - return; - case ID: - if (cc->ccdisc->ccf) - (*cc->ccdisc->ccf) (cc, expr, expr->data.variable.symbol, - expr->data.variable.reference, - expr->data.variable.index, cc->ccdisc); - else - sfprintf(cc->ccdisc->text, "%s", - expr->data.variable.symbol->name); - return; - case INC: - sfprintf(cc->ccdisc->text, "%s++", x->data.variable.symbol->name); - return; - case ITERATE: - case ITERATER: - if (expr->op == DYNAMIC) { - sfprintf(cc->ccdisc->text, "{ Exassoc_t* %stmp_%d;", cc->id, - ++cc->tmp); - sfprintf(cc->ccdisc->text, - "for (%stmp_%d = (Exassoc_t*)dtfirst(%s); %stmp_%d && (%s = %stmp_%d->name); %stmp_%d = (Exassoc_t*)dtnext(%s, %stmp_%d)) {", - cc->id, cc->tmp, - expr->data.generate.array->data.variable.symbol->name, - cc->id, cc->tmp, expr->data.generate.index->name, - cc->id, cc->tmp, cc->id, cc->tmp, - expr->data.generate.array->data.variable.symbol->name, - cc->id, cc->tmp); - gen(cc, expr->data.generate.statement); - sfprintf(cc->ccdisc->text, "} }"); + register Exnode_t* x; + register Exnode_t* y; + register int n; + register int m; + register int t; + char* s; + Extype_t* v; + Extype_t** p; + + if (!expr) + return; + if (expr->op == CALL) { + sfprintf(cc->ccdisc->text, "%s(", expr->data.call.procedure->name); + if (expr->data.call.args) + gen(cc, expr->data.call.args); + sfprintf(cc->ccdisc->text, ")"); + return; } - return; - case PRINT: - sfprintf(cc->ccdisc->text, "print"); - if (x) - gen(cc, x); - else - sfprintf(cc->ccdisc->text, "()"); - return; - case PRINTF: - print(cc, expr); - return; - case RETURN: - sfprintf(cc->ccdisc->text, "return("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ");\n"); - return; - case SCANF: - scan(cc, expr); - return; - case SPLIT: - case TOKENS: - if (expr->op == SPLIT) - sfprintf(cc->ccdisc->text, "split ("); - else - sfprintf(cc->ccdisc->text, "tokens ("); - gen(cc, expr->data.split.string); - sfprintf(cc->ccdisc->text, ", %s", expr->data.split.array->name); - if (expr->data.split.seps) { - sfprintf(cc->ccdisc->text, ","); - gen(cc, expr->data.split.seps); - } - sfprintf(cc->ccdisc->text, ")"); - return; - case SWITCH: - t = x->type; - sfprintf(cc->ccdisc->text, "{ %s %stmp_%d = ", extype(t), cc->id, - ++cc->tmp); - gen(cc, x); - sfprintf(cc->ccdisc->text, ";"); - x = expr->data.operand.right; - y = x->data.select.statement; - n = 0; - while ((x = x->data.select.next)) { - if (n) - sfprintf(cc->ccdisc->text, "else "); - if (!(p = x->data.select.constant)) + x = expr->data.operand.left; + switch (expr->op) + { + case BREAK: + sfprintf(cc->ccdisc->text, "break;\n"); + return; + case CONTINUE: + sfprintf(cc->ccdisc->text, "continue;\n"); + return; + case CONSTANT: + switch (expr->type) + { + case FLOATING: + sfprintf(cc->ccdisc->text, "%g", expr->data.constant.value.floating); + break; + case STRING: + sfprintf(cc->ccdisc->text, "\"%s\"", fmtesq(expr->data.constant.value.string, quote)); + break; + case UNSIGNED: + sfprintf(cc->ccdisc->text, "%I*u", sizeof(expr->data.constant.value.integer), expr->data.constant.value.integer); + break; + default: + sfprintf(cc->ccdisc->text, "%I*d", sizeof(expr->data.constant.value.integer), expr->data.constant.value.integer); + break; + } + return; + case DEC: + sfprintf(cc->ccdisc->text, "%s--", x->data.variable.symbol->name); + return; + case DYNAMIC: + sfprintf(cc->ccdisc->text, "%s", expr->data.variable.symbol->name); + return; + case EXIT: + sfprintf(cc->ccdisc->text, "exit("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ");\n"); + return; + case FUNCTION: + gen(cc, x); + sfprintf(cc->ccdisc->text, "("); + if ((y = expr->data.operand.right)) { + gen(cc, y); + } + sfprintf(cc->ccdisc->text, ")"); + return; + case RAND: + sfprintf(cc->ccdisc->text, "rand();\n"); + return; + case SRAND: + if (expr->binary) { + sfprintf(cc->ccdisc->text, "srand("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ");\n"); + } else + sfprintf(cc->ccdisc->text, "srand();\n"); + return; + case GSUB: + case SUB: + case SUBSTR: + s = (expr->op == GSUB ? "gsub(" : expr->op == SUB ? "sub(" : "substr("); + sfprintf(cc->ccdisc->text, s); + gen(cc, expr->data.string.base); + sfprintf(cc->ccdisc->text, ", "); + gen(cc, expr->data.string.pat); + if (expr->data.string.repl) { + sfprintf(cc->ccdisc->text, ", "); + gen(cc, expr->data.string.repl); + } + sfprintf(cc->ccdisc->text, ")"); + return; + case IN_OP: + gen(cc, expr->data.variable.index); + sfprintf(cc->ccdisc->text, " in %s", expr->data.variable.symbol->name); + return; + case IF: + sfprintf(cc->ccdisc->text, "if ("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ") {\n"); + gen(cc, expr->data.operand.right->data.operand.left); + if (expr->data.operand.right->data.operand.right) + { + sfprintf(cc->ccdisc->text, "} else {\n"); + gen(cc, expr->data.operand.right->data.operand.right); + } + sfprintf(cc->ccdisc->text, "}\n"); + return; + case FOR: + sfprintf(cc->ccdisc->text, "for (;"); + gen(cc, x); + sfprintf(cc->ccdisc->text, ");"); + if (expr->data.operand.left) + { + sfprintf(cc->ccdisc->text, "("); + gen(cc, expr->data.operand.left); + sfprintf(cc->ccdisc->text, ")"); + } + sfprintf(cc->ccdisc->text, ") {"); + if (expr->data.operand.right) + gen(cc, expr->data.operand.right); + sfprintf(cc->ccdisc->text, "}"); + return; + case ID: + if (cc->ccdisc->ccf) + (*cc->ccdisc->ccf)(cc, expr, expr->data.variable.symbol, expr->data.variable.reference, expr->data.variable.index, cc->ccdisc); + else + sfprintf(cc->ccdisc->text, "%s", expr->data.variable.symbol->name); + return; + case INC: + sfprintf(cc->ccdisc->text, "%s++", x->data.variable.symbol->name); + return; + case ITERATE: + case ITERATER: + if (expr->op == DYNAMIC) + { + sfprintf(cc->ccdisc->text, "{ Exassoc_t* %stmp_%d;", cc->id, ++cc->tmp); + sfprintf(cc->ccdisc->text, "for (%stmp_%d = (Exassoc_t*)dtfirst(%s); %stmp_%d && (%s = %stmp_%d->name); %stmp_%d = (Exassoc_t*)dtnext(%s, %stmp_%d)) {", cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp, expr->data.generate.index->name, cc->id, cc->tmp, cc->id, cc->tmp, expr->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp); + gen(cc, expr->data.generate.statement); + sfprintf(cc->ccdisc->text, "} }"); + } + return; + case PRINT: + sfprintf(cc->ccdisc->text, "print"); + if (x) + gen(cc, x); + else + sfprintf(cc->ccdisc->text, "()"); + return; + case PRINTF: + print(cc, expr); + return; + case RETURN: + sfprintf(cc->ccdisc->text, "return("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ");\n"); + return; + case SCANF: + scan(cc, expr); + return; + case SPLIT: + case TOKENS: + if (expr->op == SPLIT) + sfprintf(cc->ccdisc->text, "split ("); + else + sfprintf(cc->ccdisc->text, "tokens ("); + gen(cc, expr->data.split.string); + sfprintf(cc->ccdisc->text, ", %s", expr->data.split.array->name); + if (expr->data.split.seps) { + sfprintf(cc->ccdisc->text, ","); + gen(cc, expr->data.split.seps); + } + sfprintf(cc->ccdisc->text, ")"); + return; + case SWITCH: + t = x->type; + sfprintf(cc->ccdisc->text, "{ %s %stmp_%d = ", extype(t), cc->id, ++cc->tmp); + gen(cc, x); + sfprintf(cc->ccdisc->text, ";"); + x = expr->data.operand.right; y = x->data.select.statement; - else { - m = 0; - while ((v = *p++)) { - if (m) - sfprintf(cc->ccdisc->text, "||"); - else { - m = 1; - sfprintf(cc->ccdisc->text, "if ("); - } - if (t == STRING) - sfprintf(cc->ccdisc->text, - "strmatch(%stmp_%d, \"%s\")", cc->id, - cc->tmp, fmtesq(v->string, quote)); - else { - sfprintf(cc->ccdisc->text, "%stmp_%d == ", cc->id, - cc->tmp); - switch (t) { - case INTEGER: - case UNSIGNED: - sfprintf(cc->ccdisc->text, "%I*u", - sizeof(v->integer), v->integer); - break; - default: - sfprintf(cc->ccdisc->text, "%g", v->floating); - break; + n = 0; + while ((x = x->data.select.next)) + { + if (n) + sfprintf(cc->ccdisc->text, "else "); + if (!(p = x->data.select.constant)) + y = x->data.select.statement; + else + { + m = 0; + while ((v = *p++)) + { + if (m) + sfprintf(cc->ccdisc->text, "||"); + else + { + m = 1; + sfprintf(cc->ccdisc->text, "if ("); + } + if (t == STRING) + sfprintf(cc->ccdisc->text, "strmatch(%stmp_%d, \"%s\")", cc->id, cc->tmp, fmtesq(v->string, quote)); + else + { + sfprintf(cc->ccdisc->text, "%stmp_%d == ", cc->id, cc->tmp); + switch (t) + { + case INTEGER: + case UNSIGNED: + sfprintf(cc->ccdisc->text, "%I*u", sizeof(v->integer), v->integer); + break; + default: + sfprintf(cc->ccdisc->text, "%g", v->floating); + break; + } + } + } + sfprintf(cc->ccdisc->text, ") {"); + gen(cc, x->data.select.statement); + sfprintf(cc->ccdisc->text, "}"); } - } } + if (y) + { + if (n) + sfprintf(cc->ccdisc->text, "else "); + sfprintf(cc->ccdisc->text, "{"); + gen(cc, y); + sfprintf(cc->ccdisc->text, "}"); + } + sfprintf(cc->ccdisc->text, "}"); + return; + case UNSET: + sfprintf(cc->ccdisc->text, "unset(%s", expr->data.variable.symbol->name); + if (expr->data.variable.index) { + sfprintf(cc->ccdisc->text, ","); + gen(cc, expr->data.variable.index); + } + sfprintf(cc->ccdisc->text, ")"); + return; + case WHILE: + sfprintf(cc->ccdisc->text, "while ("); + gen(cc, x); sfprintf(cc->ccdisc->text, ") {"); - gen(cc, x->data.select.statement); + if (expr->data.operand.right) + gen(cc, expr->data.operand.right); sfprintf(cc->ccdisc->text, "}"); - } - } - if (y) { - if (n) - sfprintf(cc->ccdisc->text, "else "); - sfprintf(cc->ccdisc->text, "{"); - gen(cc, y); - sfprintf(cc->ccdisc->text, "}"); - } - sfprintf(cc->ccdisc->text, "}"); - return; - case UNSET: - sfprintf(cc->ccdisc->text, "unset(%s", expr->data.variable.symbol->name); - if (expr->data.variable.index) { - sfprintf(cc->ccdisc->text, ","); - gen(cc, expr->data.variable.index); - } - sfprintf(cc->ccdisc->text, ")"); - return; - case WHILE: - sfprintf(cc->ccdisc->text, "while ("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ") {"); - if (expr->data.operand.right) - gen(cc, expr->data.operand.right); - sfprintf(cc->ccdisc->text, "}"); - return; + return; case '#': - sfprintf(cc->ccdisc->text, "# %s", - expr->data.variable.symbol->name); - return; - case '=': - sfprintf(cc->ccdisc->text, "(%s%s=", x->data.variable.symbol->name, - expr->subop == '=' ? "" : exopname(expr->subop)); - gen(cc, expr->data.operand.right); - sfprintf(cc->ccdisc->text, ")"); - return; - case ';': - for (;;) { - if (!(x = expr->data.operand.right)) - switch (cc->lastop = expr->data.operand.left->op) { - case FOR: - case IF: - case PRINTF: - case PRINT: - case RETURN: - case WHILE: - break; - default: - sfprintf(cc->ccdisc->text, "_%svalue=", cc->id); - break; + sfprintf(cc->ccdisc->text, "# %s", expr->data.variable.symbol->name); + return; + case '=': + sfprintf(cc->ccdisc->text, "(%s%s=", x->data.variable.symbol->name, expr->subop == '=' ? "" : exopname(expr->subop)); + gen(cc, expr->data.operand.right); + sfprintf(cc->ccdisc->text, ")"); + return; + case ';': + for (;;) + { + if (!(x = expr->data.operand.right)) + switch (cc->lastop = expr->data.operand.left->op) + { + case FOR: + case IF: + case PRINTF: + case PRINT: + case RETURN: + case WHILE: + break; + default: + sfprintf(cc->ccdisc->text, "_%svalue=", cc->id); + break; + } + gen(cc, expr->data.operand.left); + sfprintf(cc->ccdisc->text, ";\n"); + if (!(expr = x)) + break; + switch (cc->lastop = expr->op) + { + case ';': + continue; + case FOR: + case IF: + case PRINTF: + case PRINT: + case RETURN: + case WHILE: + break; + default: + sfprintf(cc->ccdisc->text, "_%svalue=", cc->id); + break; + } + gen(cc, expr); + sfprintf(cc->ccdisc->text, ";\n"); + break; } - gen(cc, expr->data.operand.left); - sfprintf(cc->ccdisc->text, ";\n"); - if (!(expr = x)) - break; - switch (cc->lastop = expr->op) { - case ';': - continue; - case FOR: - case IF: - case PRINTF: - case PRINT: - case RETURN: - case WHILE: - break; - default: - sfprintf(cc->ccdisc->text, "_%svalue=", cc->id); - break; - } - gen(cc, expr); - sfprintf(cc->ccdisc->text, ";\n"); - break; - } - return; - case ',': - sfprintf(cc->ccdisc->text, "("); - gen(cc, x); - while ((expr = expr->data.operand.right) && expr->op == ',') { - sfprintf(cc->ccdisc->text, "), ("); - gen(cc, expr->data.operand.left); - } - if (expr) { - sfprintf(cc->ccdisc->text, "), ("); - gen(cc, expr); - } - sfprintf(cc->ccdisc->text, ")"); - return; - case '?': - sfprintf(cc->ccdisc->text, "("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ") ? ("); - gen(cc, expr->data.operand.right->data.operand.left); - sfprintf(cc->ccdisc->text, ") : ("); - gen(cc, expr->data.operand.right->data.operand.right); - sfprintf(cc->ccdisc->text, ")"); - return; - case AND: - sfprintf(cc->ccdisc->text, "("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ") && ("); - gen(cc, expr->data.operand.right); - sfprintf(cc->ccdisc->text, ")"); - return; - case OR: - sfprintf(cc->ccdisc->text, "("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ") || ("); - gen(cc, expr->data.operand.right); - sfprintf(cc->ccdisc->text, ")"); - return; - case F2I: - sfprintf(cc->ccdisc->text, "(%s)(", extype(INTEGER)); - gen(cc, x); - sfprintf(cc->ccdisc->text, ")"); - return; - case I2F: - sfprintf(cc->ccdisc->text, "(%s)(", extype(FLOATING)); - gen(cc, x); - sfprintf(cc->ccdisc->text, ")"); - return; - case S2I: - sfprintf(cc->ccdisc->text, "strtoll("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ",(char**)0,0)"); - return; - case X2I: - sfprintf(cc->ccdisc->text, "X2I("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ")"); - return; - case X2X: - sfprintf(cc->ccdisc->text, "X2X("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ")"); - return; - } - y = expr->data.operand.right; - if (x->type == STRING) { - switch (expr->op) { - case S2B: - sfprintf(cc->ccdisc->text, "*("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ")!=0"); - return; - case S2F: - sfprintf(cc->ccdisc->text, "strtod("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ",0)"); - return; + return; + case ',': + sfprintf(cc->ccdisc->text, "("); + gen(cc, x); + while ((expr = expr->data.operand.right) && expr->op == ',') + { + sfprintf(cc->ccdisc->text, "), ("); + gen(cc, expr->data.operand.left); + } + if (expr) + { + sfprintf(cc->ccdisc->text, "), ("); + gen(cc, expr); + } + sfprintf(cc->ccdisc->text, ")"); + return; + case '?': + sfprintf(cc->ccdisc->text, "("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ") ? ("); + gen(cc, expr->data.operand.right->data.operand.left); + sfprintf(cc->ccdisc->text, ") : ("); + gen(cc, expr->data.operand.right->data.operand.right); + sfprintf(cc->ccdisc->text, ")"); + return; + case AND: + sfprintf(cc->ccdisc->text, "("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ") && ("); + gen(cc, expr->data.operand.right); + sfprintf(cc->ccdisc->text, ")"); + return; + case OR: + sfprintf(cc->ccdisc->text, "("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ") || ("); + gen(cc, expr->data.operand.right); + sfprintf(cc->ccdisc->text, ")"); + return; + case F2I: + sfprintf(cc->ccdisc->text, "(%s)(", extype(INTEGER)); + gen(cc, x); + sfprintf(cc->ccdisc->text, ")"); + return; + case I2F: + sfprintf(cc->ccdisc->text, "(%s)(", extype(FLOATING)); + gen(cc, x); + sfprintf(cc->ccdisc->text, ")"); + return; case S2I: - sfprintf(cc->ccdisc->text, "strtol("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ",0,0)"); - return; - case S2X: - sfprintf(cc->ccdisc->text, - "** cannot convert string value to external **"); - return; - case NE: - sfprintf(cc->ccdisc->text, "!"); - /*FALLTHROUGH*/ case EQ: - sfprintf(cc->ccdisc->text, "strmatch("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ","); - gen(cc, y); - sfprintf(cc->ccdisc->text, ")"); - return; - case '+': - case '|': - case '&': - case '^': - case '%': - case '*': - sfprintf(cc->ccdisc->text, "** string bits not supported **"); - return; + /* sfprintf(cc->ccdisc->text, "strto%s(", sizeof(intmax_t) > sizeof(long) ? "ll" : "l"); */ + sfprintf(cc->ccdisc->text, "strtoll("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ",(char**)0,0)"); + return; + case X2I: + sfprintf(cc->ccdisc->text, "X2I("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ")"); + return; + case X2X: + sfprintf(cc->ccdisc->text, "X2X("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ")"); + return; } - switch (expr->op) { - case '<': - s = "<0"; - break; - case LE: - s = "<=0"; - break; - case GE: - s = ">=0"; - break; - case '>': - s = ">0"; - break; - default: - s = "** unknown string op **"; - break; + y = expr->data.operand.right; + if (x->type == STRING) + { + switch (expr->op) + { + case S2B: + sfprintf(cc->ccdisc->text, "*("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ")!=0"); + return; + case S2F: + sfprintf(cc->ccdisc->text, "strtod("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ",0)"); + return; + case S2I: + sfprintf(cc->ccdisc->text, "strtol("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ",0,0)"); + return; + case S2X: + sfprintf(cc->ccdisc->text, "** cannot convert string value to external **"); + return; + case NE: + sfprintf(cc->ccdisc->text, "!"); + /*FALLTHROUGH*/ + case EQ: + sfprintf(cc->ccdisc->text, "strmatch("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ","); + gen(cc, y); + sfprintf(cc->ccdisc->text, ")"); + return; + case '+': + case '|': + case '&': + case '^': + case '%': + case '*': + sfprintf(cc->ccdisc->text, "** string bits not supported **"); + return; + } + switch (expr->op) + { + case '<': + s = "<0"; + break; + case LE: + s = "<=0"; + break; + case GE: + s = ">=0"; + break; + case '>': + s = ">0"; + break; + default: + s = "** unknown string op **"; + break; + } + sfprintf(cc->ccdisc->text, "strcoll("); + gen(cc, x); + sfprintf(cc->ccdisc->text, ","); + gen(cc, y); + sfprintf(cc->ccdisc->text, ")%s", s); + return; } - sfprintf(cc->ccdisc->text, "strcoll("); - gen(cc, x); - sfprintf(cc->ccdisc->text, ","); - gen(cc, y); - sfprintf(cc->ccdisc->text, ")%s", s); - return; - } else { - if (!y) - sfprintf(cc->ccdisc->text, "%s", exopname(expr->op)); - sfprintf(cc->ccdisc->text, "("); - gen(cc, x); - if (y) { - sfprintf(cc->ccdisc->text, ")%s(", exopname(expr->op)); - gen(cc, y); + else + { + if (!y) + sfprintf(cc->ccdisc->text, "%s", exopname(expr->op)); + sfprintf(cc->ccdisc->text, "("); + gen(cc, x); + if (y) + { + sfprintf(cc->ccdisc->text, ")%s(", exopname(expr->op)); + gen(cc, y); + } + sfprintf(cc->ccdisc->text, ")"); } - sfprintf(cc->ccdisc->text, ")"); - } - return; + return; } /* @@ -615,119 +621,123 @@ static void gen(Excc_t * cc, register Exnode_t * expr) */ static int -global (Dt_t * table, void *object, void *handle) { - register Excc_t *cc = (Excc_t *) handle; - register Exid_t *sym = (Exid_t *) object; - - if (sym->lex == DYNAMIC) - sfprintf(cc->ccdisc->text, "static %s %s;\n", extype(sym->type), - sym->name); - return 0; +global(Dt_t* table, void* object, void* handle) +{ + register Excc_t* cc = (Excc_t*)handle; + register Exid_t* sym = (Exid_t*)object; + + if (sym->lex == DYNAMIC) + sfprintf(cc->ccdisc->text, "static %s %s;\n", extype(sym->type), sym->name); + return 0; } /* * open C program generator context */ -Excc_t *exccopen(Expr_t * expr, Exccdisc_t * disc) +Excc_t* +exccopen(Expr_t* expr, Exccdisc_t* disc) { - register Excc_t *cc; - char *id; - - if (!(id = disc->id)) - id = ""; - if (!(cc = newof(0, Excc_t, 1, strlen(id) + 2))) - return 0; - cc->expr = expr; - cc->disc = expr->disc; - cc->id = (char *) (cc + 1); - cc->ccdisc = disc; - if (!(disc->flags & EX_CC_DUMP)) { - sfprintf(disc->text, "/* : : generated by %s : : */\n", exversion); - sfprintf(disc->text, "\n#include \n"); - if (*id) - sfsprintf(cc->id, strlen(id) + 2, "%s_", id); - sfprintf(disc->text, "\n"); - dtwalk(expr->symbols, global, cc); - } - return cc; + register Excc_t* cc; + char* id; + + if (!(id = disc->id)) + id = ""; + if (!(cc = newof(0, Excc_t, 1, strlen(id) + 2))) + return 0; + cc->expr = expr; + cc->disc = expr->disc; + cc->id = (char*)(cc + 1); + cc->ccdisc = disc; + if (!(disc->flags & EX_CC_DUMP)) + { + sfprintf(disc->text, "/* : : generated by %s : : */\n", exversion); + sfprintf(disc->text, "\n#include \n"); + if (*id) + sfsprintf(cc->id, strlen(id) + 2, "%s_", id); + sfprintf(disc->text, "\n"); + dtwalk(expr->symbols, global, cc); + } + return cc; } /* * close C program generator context */ -int exccclose(Excc_t * cc) +int +exccclose(Excc_t* cc) { - int r = 0; - - if (!cc) - r = -1; - else { - if (!(cc->ccdisc->flags & EX_CC_DUMP)) { - if (cc->ccdisc->text) - sfclose(cc->ccdisc->text); - else + int r = 0; + + if (!cc) r = -1; + else + { + if (!(cc->ccdisc->flags & EX_CC_DUMP)) + { + if (cc->ccdisc->text) + sfclose(cc->ccdisc->text); + else + r = -1; + } + free(cc); } - free(cc); - } - return r; + return r; } /* * generate the program for name or sym coerced to type */ -int excc(Excc_t * cc, const char *name, Exid_t * sym, int type) +int +excc(Excc_t* cc, const char* name, Exid_t* sym, int type) { - register char *t; - - if (!cc) + register char* t; + + if (!cc) + return -1; + if (!sym) + sym = name ? (Exid_t*)dtmatch(cc->expr->symbols, name) : &cc->expr->main; + if (sym && sym->lex == PROCEDURE && sym->value) + { + t = extype(type); + sfprintf(cc->ccdisc->text, "\n%s %s%s(data) char** data; {\n%s _%svalue = 0;\n", t, cc->id, sym->name, t, cc->id); + gen(cc, sym->value->data.procedure.body); + sfprintf(cc->ccdisc->text, ";\n"); + if (cc->lastop != RETURN) + sfprintf(cc->ccdisc->text, "return _%svalue;\n", cc->id); + sfprintf(cc->ccdisc->text, "}\n"); + return 0; + } return -1; - if (!sym) - sym = - name ? (Exid_t *) dtmatch(cc->expr->symbols, - name) : &cc->expr->main; - if (sym && sym->lex == PROCEDURE && sym->value) { - t = extype(type); - sfprintf(cc->ccdisc->text, - "\n%s %s%s(data) char** data; {\n%s _%svalue = 0;\n", t, - cc->id, sym->name, t, cc->id); - gen(cc, sym->value->data.procedure.body); - sfprintf(cc->ccdisc->text, ";\n"); - if (cc->lastop != RETURN) - sfprintf(cc->ccdisc->text, "return _%svalue;\n", cc->id); - sfprintf(cc->ccdisc->text, "}\n"); - return 0; - } - return -1; } /* * dump an expression tree on sp */ -int exdump(Expr_t * expr, Exnode_t * node, Sfio_t * sp) +int +exdump(Expr_t* expr, Exnode_t* node, Sfio_t* sp) { - Excc_t *cc; - Exccdisc_t ccdisc; - Exid_t *sym; - - memset(&ccdisc, 0, sizeof(ccdisc)); - ccdisc.flags = EX_CC_DUMP; - ccdisc.text = sp; - if (!(cc = exccopen(expr, &ccdisc))) - return -1; - if (node) - gen(cc, node); - else - for (sym = (Exid_t *) dtfirst(expr->symbols); sym; - sym = (Exid_t *) dtnext(expr->symbols, sym)) - if (sym->lex == PROCEDURE && sym->value) { - sfprintf(sp, "\n%s:\n", sym->name); - gen(cc, sym->value->data.procedure.body); - } - sfprintf(sp, "\n"); - return exccclose(cc); + Excc_t* cc; + Exccdisc_t ccdisc; + Exid_t* sym; + + memset(&ccdisc, 0, sizeof(ccdisc)); + ccdisc.flags = EX_CC_DUMP; + ccdisc.text = sp; + if (!(cc = exccopen(expr, &ccdisc))) + return -1; + if (node) + gen(cc, node); + else + for (sym = (Exid_t*)dtfirst(expr->symbols); sym; sym = (Exid_t*)dtnext(expr->symbols, sym)) + if (sym->lex == PROCEDURE && sym->value) + { + sfprintf(sp, "%s:\n", sym->name); + gen(cc, sym->value->data.procedure.body); + } + sfprintf(sp, "\n"); + return exccclose(cc); } diff --git a/lib/expr/excontext.c b/lib/expr/excontext.c index 96dc6e1da..7353ac417 100644 --- a/lib/expr/excontext.c +++ b/lib/expr/excontext.c @@ -1,4 +1,3 @@ -/* $Id$ $Revision$ */ /* vim:set shiftwidth=4 ts=8: */ /************************************************************************* @@ -25,44 +24,45 @@ * end of buf returned */ -char *excontext(Expr_t * p, char *buf, int n) +char* +excontext(Expr_t* p, char* buf, int n) { - register char *s; - register char *t; - register char *e; + register char* s; + register char* t; + register char* e; - s = buf; - if (p->linep > p->line || p->linewrap) { - e = buf + n - 5; - if (p->linewrap) { - t = p->linep + 1; - while (t < &p->line[sizeof(p->line)] && isspace(*t)) - t++; - if ((n = - (sizeof(p->line) - (t - (p->linep + 1))) - (e - s)) > 0) { - if (n > &p->line[sizeof(p->line)] - t) - t = &p->line[sizeof(p->line)]; - else - t += n; - } - while (t < &p->line[sizeof(p->line)]) - *s++ = *t++; + s = buf; + if (p->linep > p->line || p->linewrap) + { + e = buf + n - 5; + if (p->linewrap) + { + t = p->linep + 1; + while (t < &p->line[sizeof(p->line)] && isspace(*t)) + t++; + if ((n = (sizeof(p->line) - (t - (p->linep + 1))) - (e - s)) > 0) + { + if (n > &p->line[sizeof(p->line)] - t) + t = &p->line[sizeof(p->line)]; + else t += n; + } + while (t < &p->line[sizeof(p->line)]) + *s++ = *t++; + } + t = p->line; + if (p->linewrap) + p->linewrap = 0; + else while (t < p->linep && isspace(*t)) + t++; + if ((n = (p->linep - t) - (e - s)) > 0) + t += n; + while (t < p->linep) + *s++ = *t++; + p->linep = p->line; + t = "<<< "; + while ((*s = *t++)) + s++; } - t = p->line; - if (p->linewrap) - p->linewrap = 0; - else - while (t < p->linep && isspace(*t)) - t++; - if ((n = (p->linep - t) - (e - s)) > 0) - t += n; - while (t < p->linep) - *s++ = *t++; - p->linep = p->line; - t = "<<< "; - while ((*s = *t++)) - s++; - } - *s = 0; - return s; + *s = 0; + return s; } diff --git a/lib/expr/exdata.c b/lib/expr/exdata.c index c3752513c..d46d809de 100644 --- a/lib/expr/exdata.c +++ b/lib/expr/exdata.c @@ -1,5 +1,4 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -18,55 +17,57 @@ * expression library readonly tables */ -static const char id[] = - "\n@(#)$Id$\0\n"; +static const char id[] = "\n@(#)$Id: libexpr (AT&T Research) 2011-06-30 $\0\n"; #include -const char *exversion = id + 10; +const char* exversion = id + 10; -Exid_t exbuiltin[] = { +Exid_t exbuiltin[] = +{ - /* id_string references the first entry */ + /* id_string references the first entry */ - EX_ID("string", DECLARE, STRING, STRING, 0), + EX_ID("string", DECLARE, STRING, STRING, 0), - /* order not important after this point (but sorted anyway) */ + /* order not important after this point (but sorted anyway) */ - EX_ID("break", BREAK, BREAK, 0, 0), - EX_ID("case", CASE, CASE, 0, 0), - EX_ID("char", DECLARE, CHARACTER, CHARACTER, 0), - EX_ID("continue", CONTINUE, CONTINUE, 0, 0), - EX_ID("default", DEFAULT, DEFAULT, 0, 0), - EX_ID("double", DECLARE, FLOATING, FLOATING, 0), - EX_ID("else", ELSE, ELSE, 0, 0), - EX_ID("exit", EXIT, EXIT, INTEGER, 0), - EX_ID("for", FOR, FOR, 0, 0), - EX_ID("forr", ITERATER, ITERATER, 0, 0), - EX_ID("float", DECLARE, FLOATING, FLOATING, 0), - EX_ID("gsub", GSUB, GSUB, STRING, 0), - EX_ID("if", IF, IF, 0, 0), - EX_ID("in", IN_OP, IN_OP, 0, 0), - EX_ID("int", DECLARE, INTEGER, INTEGER, 0), - EX_ID("long", DECLARE, INTEGER, INTEGER, 0), - EX_ID("print", PRINT, PRINT, INTEGER, 0), - EX_ID("printf", PRINTF, PRINTF, INTEGER, 0), - EX_ID("query", QUERY, QUERY, INTEGER, 0), - EX_ID("rand", RAND, RAND, FLOATING, 0), - EX_ID("return", RETURN, RETURN, 0, 0), - EX_ID("scanf", SCANF, SCANF, INTEGER, 0), - EX_ID("sscanf", SSCANF, SSCANF, INTEGER, 0), - EX_ID("split", SPLIT, SPLIT, INTEGER, 0), - EX_ID("sprintf", SPRINTF, SPRINTF, STRING, 0), - EX_ID("srand", SRAND, SRAND, INTEGER, 0), - EX_ID("sub", SUB, SUB, STRING, 0), - EX_ID("substr", SUBSTR, SUBSTR, STRING, 0), - EX_ID("switch", SWITCH, SWITCH, 0, 0), - EX_ID("tokens", TOKENS, TOKENS, INTEGER, 0), - EX_ID("unsigned", DECLARE, UNSIGNED, UNSIGNED, 0), - EX_ID("void", DECLARE, VOIDTYPE, 0, 0), - EX_ID("unset", UNSET, UNSET, 0, 0), - EX_ID("while", WHILE, WHILE, 0, 0), - EX_ID({0}, 0, 0, 0, 0) + EX_ID("break", BREAK, BREAK, 0, 0), + EX_ID("case", CASE, CASE, 0, 0), + EX_ID("char", DECLARE, CHARACTER, CHARACTER, 0), + EX_ID("continue",CONTINUE, CONTINUE, 0, 0), + EX_ID("default", DEFAULT, DEFAULT, 0, 0), + EX_ID("double", DECLARE, FLOATING, FLOATING,0), + EX_ID("else", ELSE, ELSE, 0, 0), + EX_ID("exit", EXIT, EXIT, INTEGER,0), + EX_ID("for", FOR, FOR, 0, 0), + EX_ID("forr", ITERATER, ITERATER, 0, 0), + EX_ID("float", DECLARE, FLOATING, FLOATING,0), + EX_ID("gsub", GSUB, GSUB, STRING, 0), + EX_ID("if", IF, IF, 0, 0), + EX_ID("in", IN_OP, IN_OP, 0, 0), + EX_ID("int", DECLARE, INTEGER, INTEGER,0), + EX_ID("long", DECLARE, INTEGER, INTEGER,0), + EX_ID("print", PRINT, PRINT, INTEGER,0), + EX_ID("printf", PRINTF, PRINTF, INTEGER,0), + EX_ID("query", QUERY, QUERY, INTEGER,0), + EX_ID("rand", RAND, RAND, FLOATING,0), + EX_ID("return", RETURN, RETURN, 0, 0), + EX_ID("scanf", SCANF, SCANF, INTEGER,0), + EX_ID("sscanf", SSCANF, SSCANF, INTEGER,0), + EX_ID("split", SPLIT, SPLIT, INTEGER,0), + EX_ID("sprintf", SPRINTF, SPRINTF, STRING, 0), + EX_ID("srand", SRAND, SRAND, INTEGER,0), + EX_ID("static", STATIC, STATIC, 0, 0), + EX_ID("sub", SUB, SUB, STRING, 0), + EX_ID("substr", SUBSTR, SUBSTR, STRING, 0), + EX_ID("switch", SWITCH, SWITCH, 0, 0), + EX_ID("tokens", TOKENS, TOKENS, INTEGER,0), + EX_ID("unset", UNSET, UNSET, 0, 0), + EX_ID("unsigned",DECLARE, UNSIGNED, UNSIGNED,0), + EX_ID("void", DECLARE, VOIDTYPE, 0, 0), + EX_ID("while", WHILE, WHILE, 0, 0), + EX_ID("while", WHILE, WHILE, 0, 0), + EX_ID({0}, 0, 0, 0, 0) }; diff --git a/lib/expr/exerror.c b/lib/expr/exerror.c index cdfa3a800..235d4f9de 100644 --- a/lib/expr/exerror.c +++ b/lib/expr/exerror.c @@ -1,4 +1,3 @@ -/* $Id$ $Revision$ */ /* vim:set shiftwidth=4 ts=8: */ /************************************************************************* @@ -24,51 +23,52 @@ * library error handler */ -void exerror(const char *format, ...) +void +exerror(const char* format, ...) { - Sfio_t *sp; + Sfio_t* sp; - if (expr.program->disc->errorf && !expr.program->errors - && (sp = sfstropen())) { - va_list ap; - char *s; - char buf[64]; + if (expr.program->disc->errorf && !expr.program->errors && (sp = sfstropen())) + { + va_list ap; + char* s; + char buf[64]; - expr.program->errors = 1; - excontext(expr.program, buf, sizeof(buf)); - sfputr(sp, buf, -1); - sfputr(sp, "\n -- ", -1); - va_start(ap, format); - sfvprintf(sp, format, ap); - va_end(ap); - s = sfstruse(sp); - (*expr.program->disc->errorf) (expr.program, expr.program->disc, - (expr.program->disc-> - flags & EX_FATAL) ? ERROR_FATAL : - ERROR_ERROR, "%s", s); - sfclose(sp); - } else if (expr.program->disc->flags & EX_FATAL) - exit(1); + expr.program->errors = 1; + excontext(expr.program, buf, sizeof(buf)); + sfputr(sp, buf, -1); + sfputr(sp, "\n -- ", -1); + va_start(ap, format); + sfvprintf(sp, format, ap); + va_end(ap); + if (!(s = sfstruse(sp))) + s = "out of space"; + (*expr.program->disc->errorf)(expr.program, expr.program->disc, (expr.program->disc->flags & EX_FATAL) ? 3 : 2, "%s", s); + sfclose(sp); + } + else if (expr.program->disc->flags & EX_FATAL) + exit(1); } -void exwarn(const char *format, ...) +void +exwarn(const char *format, ...) { - Sfio_t *sp; + Sfio_t *sp; - if (expr.program->disc->errorf && (sp = sfstropen())) { - va_list ap; - char *s; - char buf[64]; + if (expr.program->disc->errorf && (sp = sfstropen())) { + va_list ap; + char *s; + char buf[64]; - excontext(expr.program, buf, sizeof(buf)); - sfputr(sp, buf, -1); - sfputr(sp, "\n -- ", -1); - va_start(ap, format); - sfvprintf(sp, format, ap); - va_end(ap); - s = sfstruse(sp); - (*expr.program->disc->errorf) (expr.program, expr.program->disc, + excontext(expr.program, buf, sizeof(buf)); + sfputr(sp, buf, -1); + sfputr(sp, "\n -- ", -1); + va_start(ap, format); + sfvprintf(sp, format, ap); + va_end(ap); + s = sfstruse(sp); + (*expr.program->disc->errorf) (expr.program, expr.program->disc, ERROR_WARNING, "%s", s); sfclose(sp); - } + } } diff --git a/lib/expr/exeval.c b/lib/expr/exeval.c index 246f10430..8c3cbcf7c 100644 --- a/lib/expr/exeval.c +++ b/lib/expr/exeval.c @@ -1,5 +1,4 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -37,39 +36,47 @@ #define drand48 rand #endif +#ifdef OLD +#include +#else +#define TIME_LEN 80 /* max. characters to store time */ +#endif -static Extype_t eval(Expr_t *, Exnode_t *, void *); +static Extype_t eval(Expr_t*, Exnode_t*, void*); #define TOTNAME 4 #define MAXNAME 16 #define FRAME 64 -static char *lexname(int op, int subop) +static char* +lexname(int op, int subop) { - register char *b; - - static int n; - static char buf[TOTNAME][MAXNAME]; - - if (op > MINTOKEN && op < MAXTOKEN) - return (char *) exop[op - MINTOKEN]; - if (++n >= TOTNAME) - n = 0; - b = buf[n]; - if (op == '=') { - if (subop > MINTOKEN && subop < MAXTOKEN) - sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); - else if (subop > ' ' && subop <= '~') - sfsprintf(b, MAXNAME, "%c=", subop); + register char* b; + + static int n; + static char buf[TOTNAME][MAXNAME]; + + if (op > MINTOKEN && op < MAXTOKEN) + return (char*)exop[op - MINTOKEN]; + if (++n >= TOTNAME) + n = 0; + b = buf[n]; + if (op == '=') + { + if (subop > MINTOKEN && subop < MAXTOKEN) + sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); + else if (subop > ' ' && subop <= '~') + sfsprintf(b, MAXNAME, "%c=", subop); + else + sfsprintf(b, MAXNAME, "(%d)=", subop); + } + else if (subop < 0) + sfsprintf(b, MAXNAME, "(EXTERNAL:%d)", op); + else if (op > ' ' && op <= '~') + sfsprintf(b, MAXNAME, "%c", op); else - sfsprintf(b, MAXNAME, "(%d)=", subop); - } else if (subop < 0) - sfsprintf(b, MAXNAME, "(EXTERNAL:%d)", op); - else if (op > ' ' && op <= '~') - sfsprintf(b, MAXNAME, "%c", op); - else - sfsprintf(b, MAXNAME, "(%d)", op); - return b; + sfsprintf(b, MAXNAME, "(%d)", op); + return b; } /* evaldyn: @@ -80,41 +87,39 @@ static char *lexname(int op, int subop) static int evaldyn (Expr_t * ex, register Exnode_t * expr, void *env, int delete) { - Exassoc_t *b; - Extype_t v; - char buf[32]; - Extype_t key; - char *keyname; - - v = eval(ex, expr->data.variable.index, env); - if (expr->data.variable.symbol->index_type == INTEGER) { - if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable. - symbol->local.pointer, &v))) { - return 0; - } - } - else { - int type = expr->data.variable.index->type; - if (type != STRING) { - if (!BUILTIN(type)) { - key = (*ex->disc->keyf) (ex, v, type, ex->disc); + Exassoc_t *b; + Extype_t v; + char buf[32]; + Extype_t key; + char *keyname; + + v = eval(ex, expr->data.variable.index, env); + if (expr->data.variable.symbol->index_type == INTEGER) { + if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable.symbol->local.pointer, &v))) { + return 0; + } + } + else { + int type = expr->data.variable.index->type; + if (type != STRING) { + if (!BUILTIN(type)) { + key = (*ex->disc->keyf) (ex, v, type, ex->disc); + } else + key.integer = v.integer; + sfsprintf(buf, sizeof(buf), "0x%I*x", sizeof(v.integer), key.integer); + keyname = buf; } else - key.integer = v.integer; - sfsprintf(buf, sizeof(buf), "0x%I*x", sizeof(v.integer), - key.integer); - keyname = buf; - } else - keyname = v.string; - if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable. - symbol->local.pointer, keyname))) { - return 0; + keyname = v.string; + if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable. + symbol->local.pointer, keyname))) { + return 0; + } } - } - if (delete) { - dtdelete ((Dt_t*)expr->data.variable.symbol->local.pointer, b); - free (b); - } - return 1; + if (delete) { + dtdelete ((Dt_t*)expr->data.variable.symbol->local.pointer, b); + free (b); + } + return 1; } /* @@ -123,225 +128,249 @@ evaldyn (Expr_t * ex, register Exnode_t * expr, void *env, int delete) */ static Extype_t -getdyn(Expr_t * ex, register Exnode_t * expr, void *env, - Exassoc_t ** assoc) +getdyn(Expr_t* ex, register Exnode_t* expr, void* env, Exassoc_t** assoc) { - Exassoc_t *b; - Extype_t v; - - if (expr->data.variable.index) { - char buf[32]; - Extype_t key; - char *keyname; + Exassoc_t* b; + Extype_t v; - v = eval(ex, expr->data.variable.index, env); - if (expr->data.variable.symbol->index_type == INTEGER) { - if (! - (b = - (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable. - symbol->local.pointer, &v))) { - if (!(b = newof(0, Exassoc_t, 1, 0))) - exerror("out of space [assoc]"); - b->key = v; - dtinsert((Dt_t *) expr->data.variable.symbol->local. - pointer, b); - } - } else { - int type = expr->data.variable.index->type; - if (type != STRING) { - if (!BUILTIN(type)) { - key = (*ex->disc->keyf) (ex, v, type, ex->disc); - } else - key.integer = v.integer; - sfsprintf(buf, sizeof(buf), "0x%I*x", sizeof(v.integer), - key.integer); - keyname = buf; - } else - keyname = v.string; - if (! - (b = - (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable. - symbol->local.pointer, keyname))) { - if (!(b = newof(0, Exassoc_t, 1, strlen(keyname)))) - exerror("out of space [assoc]"); - strcpy(b->name, keyname); - b->key = v; - dtinsert((Dt_t *) expr->data.variable.symbol->local. - pointer, b); - } - } - *assoc = b; - if (b) { - if (expr->data.variable.symbol->type == STRING - && !b->value.string) - b->value = exzero(expr->data.variable.symbol->type); - return b->value; + if (expr->data.variable.index) + { + char buf[9]; + Extype_t key; + char *keyname; + + v = eval(ex, expr->data.variable.index, env); + if (expr->data.variable.symbol->index_type == INTEGER) { + if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable.symbol->local.pointer, &v))) + { + if (!(b = newof(0, Exassoc_t, 1, 0))) + exnospace(); + b->key = v; + dtinsert((Dt_t *) expr->data.variable.symbol->local. pointer, b); + } + } else { + int type = expr->data.variable.index->type; + if (type != STRING) { + if (!BUILTIN(type)) { + key = (*ex->disc->keyf) (ex, v, type, ex->disc); + } else + key.integer = v.integer; + sfsprintf(buf, sizeof(buf), "0x%I*x", sizeof(v.integer), key.integer); + keyname = buf; + } else + keyname = v.string; + if (!(b = (Exassoc_t *) dtmatch((Dt_t *) expr->data.variable.symbol->local.pointer, keyname))) + { + if (!(b = newof(0, Exassoc_t, 1, strlen(keyname)))) + exnospace(); + strcpy(b->name, keyname); + b->key = v; + dtinsert((Dt_t *) expr->data.variable.symbol->local.pointer, b); + } + } + *assoc = b; + if (b) + { + if (expr->data.variable.symbol->type == STRING && !b->value.string) + b->value = exzero(expr->data.variable.symbol->type); + return b->value; + } + v = exzero(expr->data.variable.symbol->type); + return v; } - v = exzero(expr->data.variable.symbol->type); - return v; - } - *assoc = 0; - return expr->data.variable.symbol->value->data.constant.value; + *assoc = 0; + return expr->data.variable.symbol->value->data.constant.value; } -typedef struct { - Sffmt_t fmt; - Expr_t *expr; - void *env; - Print_t *args; - Extype_t value; - Exnode_t *actuals; - Sfio_t *tmp; +typedef struct +{ + Sffmt_t fmt; + Expr_t* expr; + void* env; + Print_t* args; + Extype_t value; + Exnode_t* actuals; + Sfio_t* tmp; } Fmt_t; /* * printf %! extension function */ -#define TIME_LEN 80 /* max. characters to store time */ -static int prformat(Sfio_t * sp, void *vp, Sffmt_t * dp) +static int +prformat(Sfio_t* sp, void* vp, Sffmt_t* dp) { - register Fmt_t *fmt = (Fmt_t *) dp; - register Exnode_t *node; - register char *s; - register char *txt; - int n; - int from; - int to = 0; - time_t tm; + register Fmt_t* fmt = (Fmt_t*)dp; + register Exnode_t* node; + register char* s; + register char* txt; + int n; + int from; + int to = 0; + time_t tm; +#ifndef OLD struct tm *stm; +#endif + - dp->flags |= SFFMT_VALUE; - if (fmt->args) { - if ((node = - (dp->fmt == - '*') ? fmt->args->param[dp->size] : fmt->args->arg)) - fmt->value = exeval(fmt->expr, node, fmt->env); + dp->flags |= SFFMT_VALUE; + if (fmt->args) + { + if ((node = (dp->fmt == '*') ? fmt->args->param[dp->size] : fmt->args->arg)) + fmt->value = exeval(fmt->expr, node, fmt->env); + else + fmt->value.integer = 0; + to = fmt->args->arg->type; + } + else if (!(fmt->actuals = fmt->actuals->data.operand.right)) + exerror("printf: not enough arguments"); else - fmt->value.integer = 0; - to = fmt->args->arg->type; - } else if (!(fmt->actuals = fmt->actuals->data.operand.right)) - exerror("printf: not enough arguments"); - else { - node = fmt->actuals->data.operand.left; - from = node->type; - switch (dp->fmt) { - case 'f': - case 'g': - to = FLOATING; - break; - case 's': - to = STRING; - break; - default: - switch (from) { - case INTEGER: - case UNSIGNED: - to = from; + { + node = fmt->actuals->data.operand.left; + from = node->type; + switch (dp->fmt) + { + case 'f': + case 'g': + to = FLOATING; + break; + case 's': + to = STRING; + break; + default: + switch (from) + { + case INTEGER: + case UNSIGNED: + to = from; + break; + default: + to = INTEGER; + break; + } + break; + } + if (to == from) + fmt->value = exeval(fmt->expr, node, fmt->env); + else + { + node = excast(fmt->expr, node, to, NiL, 0); + fmt->value = exeval(fmt->expr, node, fmt->env); + node->data.operand.left = 0; + exfree(fmt->expr, node); + if (to == STRING) + { + if (fmt->value.string) + { + n = strlen(fmt->value.string); + if ((s = fmtbuf(n + 1))) + memcpy(s, fmt->value.string, n + 1); + vmfree(fmt->expr->vm, fmt->value.string); + fmt->value.string = s; + } + if (!fmt->value.string) + fmt->value.string = ""; + } + } + } + switch (to) + { + case STRING: + *((char**)vp) = fmt->value.string; + fmt->fmt.size = -1; + break; + case FLOATING: + *((double*)vp) = fmt->value.floating; + fmt->fmt.size = sizeof(double); break; - default: - to = INTEGER; + default: + *((Sflong_t*)vp) = fmt->value.integer; + dp->size = sizeof(Sflong_t); break; - } - break; } - if (to == from) - fmt->value = exeval(fmt->expr, node, fmt->env); - else { - node = excast(fmt->expr, node, to, NiL, 0); - fmt->value = exeval(fmt->expr, node, fmt->env); - node->data.operand.left = 0; - exfree(fmt->expr, node); - if (to == STRING) { - if (fmt->value.string) { - n = strlen(fmt->value.string); - if ((s = fmtbuf(n + 1))) - memcpy(s, fmt->value.string, n + 1); - vmfree(fmt->expr->vm, fmt->value.string); - fmt->value.string = s; + if (dp->n_str > 0) + { + if (!fmt->tmp && !(fmt->tmp = sfstropen())) + txt = exnospace(); + else + { + sfprintf(fmt->tmp, "%.*s", dp->n_str, dp->t_str); + txt = exstash(fmt->tmp, NiL); } - if (!fmt->value.string) - fmt->value.string = ""; - } } - } - switch (to) { - case STRING: - *((char **) vp) = fmt->value.string; - fmt->fmt.size = -1; - break; - case FLOATING: - *((double *) vp) = fmt->value.floating; - fmt->fmt.size = sizeof(double); - break; - default: - *((Sflong_t *) vp) = fmt->value.integer; - dp->size = sizeof(Sflong_t); - break; - } - if (dp->n_str > 0) { - if (!fmt->tmp) - fmt->tmp = sfstropen(); - sfprintf(fmt->tmp, "%.*s", (int) (dp->n_str), dp->t_str); - txt = sfstruse(fmt->tmp); - } else - txt = 0; - switch (dp->fmt) { - case 'q': - case 'Q': - s = *((char **) vp); - *((char **) vp) = fmtquote(s, "$'", "'", strlen(s), 0); - dp->fmt = 's'; - dp->size = -1; - break; - case 'S': - dp->flags &= ~SFFMT_LONG; - s = *((char **) vp); - if (txt) { - if (streq(txt, "identifier")) { - if (*s && !isalpha(*s)) - *s++ = '_'; - for (; *s; s++) - if (!isalnum(*s)) - *s = '_'; - } else if (streq(txt, "invert")) { - for (; *s; s++) - if (isupper(*s)) - *s = tolower(*s); - else if (islower(*s)) - *s = toupper(*s); - } else if (streq(txt, "lower")) { - for (; *s; s++) - if (isupper(*s)) - *s = tolower(*s); - } else if (streq(txt, "upper")) { - for (; *s; s++) - if (islower(*s)) - *s = toupper(*s); - } else if (streq(txt, "variable")) { - for (; *s; s++) - if (!isalnum(*s) && *s != '_') - *s = '.'; - } + else + txt = 0; + switch (dp->fmt) + { + case 'q': + case 'Q': + s = *((char**)vp); + *((char**)vp) = fmtquote(s, "$'", "'", strlen(s), 0); + dp->fmt = 's'; + dp->size = -1; + break; + case 'S': + dp->flags &= ~SFFMT_LONG; + s = *((char**)vp); + if (txt) + { + if (streq(txt, "identifier")) + { + if (*s && !isalpha(*s)) + *s++ = '_'; + for (; *s; s++) + if (!isalnum(*s)) + *s = '_'; + } + else if (streq(txt, "invert")) + { + for (; *s; s++) + if (isupper(*s)) + *s = tolower(*s); + else if (islower(*s)) + *s = toupper(*s); + } + else if (streq(txt, "lower")) + { + for (; *s; s++) + if (isupper(*s)) + *s = tolower(*s); + } + else if (streq(txt, "upper")) + { + for (; *s; s++) + if (islower(*s)) + *s = toupper(*s); + } + else if (streq(txt, "variable")) + { + for (; *s; s++) + if (!isalnum(*s) && *s != '_') + *s = '.'; + } + } + dp->fmt = 's'; + dp->size = -1; + break; + case 't': + case 'T': + if ((tm = *((Sflong_t*)vp)) == -1) + tm = time(NiL); +#ifndef OLD + if (!txt) + txt = "%?%K"; + s = fmtbuf(TIME_LEN); + stm = localtime(&tm); + strftime(s, TIME_LEN, txt, stm); + *((char **) vp) = s; +#else + *((char**)vp) = fmttime(txt ? txt : "%?%K", tm); +#endif + dp->fmt = 's'; + dp->size = -1; + break; } - dp->fmt = 's'; - dp->size = -1; - break; - case 't': - case 'T': - if ((tm = *((Sflong_t *) vp)) == -1) - tm = time(0); - if (!txt) - txt = "%?%K"; - s = fmtbuf(TIME_LEN); - stm = localtime(&tm); - strftime(s, TIME_LEN, txt, stm); - *((char **) vp) = s; - dp->fmt = 's'; - dp->size = -1; - break; - } - return 0; + return 0; } /* @@ -368,257 +397,252 @@ prints(Expr_t * ex, register Exnode_t * expr, void *env, Sfio_t * sp) * do printf */ -static int print(Expr_t * ex, Exnode_t * expr, void *env, Sfio_t * sp) +static int +print(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp) { - register Print_t *x; - Extype_t v; - Fmt_t fmt; - - if (!sp) { - v = eval(ex, expr->data.print.descriptor, env); - if (v.integer < 0 || v.integer >= elementsof(ex->file) - || (!((sp = ex->file[v.integer])) - && - !((sp = ex->file[v.integer] = - sfnew(NiL, NiL, SF_UNBOUND, v.integer, - SF_READ | SF_WRITE))))) { - exerror("printf: %d: invalid descriptor", v.integer); - return -1; + register Print_t* x; + Extype_t v; + Fmt_t fmt; + + if (!sp) + { + v = eval(ex, expr->data.print.descriptor, env); + if (v.integer < 0 || v.integer >= elementsof(ex->file) || (!(sp = ex->file[v.integer]) && !(sp = ex->file[v.integer] = sfnew(NiL, NiL, SF_UNBOUND, v.integer, SF_READ|SF_WRITE)))) + { + exerror("printf: %d: invalid descriptor", v.integer); + return -1; + } } - } - memset(&fmt, 0, sizeof(fmt)); - fmt.fmt.version = SFIO_VERSION; - fmt.fmt.extf = prformat; - fmt.expr = ex; - fmt.env = env; - x = expr->data.print.args; - if (x->format) - do { - if (x->arg) { - fmt.fmt.form = x->format; - fmt.args = x; + memset(&fmt, 0, sizeof(fmt)); + fmt.fmt.version = SFIO_VERSION; + fmt.fmt.extf = prformat; + fmt.expr = ex; + fmt.env = env; + x = expr->data.print.args; + if (x->format) + do + { + if (x->arg) + { + fmt.fmt.form = x->format; + fmt.args = x; + sfprintf(sp, "%!", &fmt); + } + else + sfputr(sp, x->format, -1); + } while ((x = x->next)); + else + { + v = eval(ex, x->arg->data.operand.left, env); + fmt.fmt.form = v.string; + fmt.actuals = x->arg; sfprintf(sp, "%!", &fmt); - } else - sfputr(sp, x->format, -1); - } while ((x = x->next)); - else { - v = eval(ex, x->arg->data.operand.left, env); - fmt.fmt.form = v.string; - fmt.actuals = x->arg; - sfprintf(sp, "%!", &fmt); - if (fmt.actuals->data.operand.right) - exerror("(s)printf: \"%s\": too many arguments", fmt.fmt.form); - } - if (fmt.tmp) - sfstrclose(fmt.tmp); - return 0; + if (fmt.actuals->data.operand.right) + exerror("(s)printf: \"%s\": too many arguments", fmt.fmt.form); + } + if (fmt.tmp) + sfstrclose(fmt.tmp); + return 0; } /* * scanf %! extension function */ -static int scformat(Sfio_t * sp, void *vp, Sffmt_t * dp) +static int +scformat(Sfio_t* sp, void* vp, Sffmt_t* dp) { - register Fmt_t *fmt = (Fmt_t *) dp; - register Exnode_t *node; + register Fmt_t* fmt = (Fmt_t*)dp; + register Exnode_t* node; - if (!fmt->actuals) { - exerror("scanf: not enough arguments"); - return -1; - } - node = fmt->actuals->data.operand.left; - switch (dp->fmt) { - case 'f': - case 'g': - if (node->type != FLOATING) { - exerror - ("scanf: %s: floating variable address argument expected", - node->data.variable.symbol->name); - return -1; - } - fmt->fmt.size = sizeof(double); - *((void **) vp) = - &node->data.variable.symbol->value->data.constant.value; - break; - case 's': - if (node->type != STRING) { - exerror("scanf: %s: string variable address argument expected", - node->data.variable.symbol->name); - return -1; - } - if (node->data.variable.symbol->value->data.constant.value. - string == expr.nullstring) - node->data.variable.symbol->value->data.constant.value.string = - 0; - fmt->fmt.size = 1024; - *((void **) vp) = - node->data.variable.symbol->value->data.constant.value.string = - vmnewof(fmt->expr->vm, - node->data.variable.symbol->value->data.constant.value. - string, char, fmt->fmt.size, 0); - break; - case 'c': - if (node->type != CHARACTER) { - exerror("scanf: %s: char variable address argument expected", - node->data.variable.symbol->name); - return -1; + if (!fmt->actuals) + { + exerror("scanf: not enough arguments"); + return -1; } - fmt->fmt.size = sizeof(Sflong_t); - *((void **) vp) = - &node->data.variable.symbol->value->data.constant.value; - break; - default: - if (node->type != INTEGER && node->type != UNSIGNED) { - exerror - ("scanf: %s: integer variable address argument expected", - node->data.variable.symbol->name); - return -1; + node = fmt->actuals->data.operand.left; + switch (dp->fmt) + { + case 'f': + case 'g': + if (node->type != FLOATING) + { + exerror("scanf: %s: floating variable address argument expected", node->data.variable.symbol->name); + return -1; + } + fmt->fmt.size = sizeof(double); + *((void**)vp) = &node->data.variable.symbol->value->data.constant.value; + break; + case 's': + if (node->type != STRING) + { + exerror("scanf: %s: string variable address argument expected", node->data.variable.symbol->name); + return -1; + } + if (node->data.variable.symbol->value->data.constant.value.string == expr.nullstring) + node->data.variable.symbol->value->data.constant.value.string = 0; + fmt->fmt.size = 1024; + *((void**)vp) = node->data.variable.symbol->value->data.constant.value.string = vmnewof(fmt->expr->vm, node->data.variable.symbol->value->data.constant.value.string, char, fmt->fmt.size, 0); + break; + case 'c': + if (node->type != CHARACTER) { + exerror("scanf: %s: char variable address argument expected", node->data.variable.symbol->name); + return -1; + } + fmt->fmt.size = sizeof(Sflong_t); + *((void **) vp) = &node->data.variable.symbol->value->data.constant.value; + break; + default: + if (node->type != INTEGER && node->type != UNSIGNED) + { + exerror("scanf: %s: integer variable address argument expected", node->data.variable.symbol->name); + return -1; + } + dp->size = sizeof(Sflong_t); + *((void**)vp) = &node->data.variable.symbol->value->data.constant.value; + break; } - dp->size = sizeof(Sflong_t); - *((void **) vp) = - &node->data.variable.symbol->value->data.constant.value; - break; - } - fmt->actuals = fmt->actuals->data.operand.right; - dp->flags |= SFFMT_VALUE; - return 0; + fmt->actuals = fmt->actuals->data.operand.right; + dp->flags |= SFFMT_VALUE; + return 0; } /* * do scanf */ -static int scan(Expr_t * ex, Exnode_t * expr, void *env, Sfio_t * sp) +static int +scan(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp) { - Extype_t v; - Extype_t u; - Fmt_t fmt; - int n; - - if (!sp) { - if (expr->data.scan.descriptor) { - v = eval(ex, expr->data.scan.descriptor, env); - if (expr->data.scan.descriptor->type == STRING) - goto get; - } else - v.integer = 0; - if ((v.integer < 0) || - (v.integer >= elementsof(ex->file)) || - (!(sp = ex->file[v.integer]) && - !(sp = ex->file[v.integer] = - sfnew(NiL, NiL, SF_UNBOUND, v.integer, - SF_READ | SF_WRITE)))) { - exerror("scanf: %d: invalid descriptor", v.integer); - return 0; + Extype_t v; + Extype_t u; + Fmt_t fmt; + int n; + + if (!sp) + { + if (expr->data.scan.descriptor) + { + v = eval(ex, expr->data.scan.descriptor, env); + if (expr->data.scan.descriptor->type == STRING) + goto get; + } + else + v.integer = 0; + if ((v.integer < 0) || (v.integer >= elementsof(ex->file)) || (!(sp = ex->file[v.integer]) && !(sp = ex->file[v.integer] = sfnew(NiL, NiL, SF_UNBOUND, v.integer, SF_READ|SF_WRITE)))) + { + exerror("scanf: %d: invalid descriptor", v.integer); + return 0; + } } - } - get: - memset(&fmt, 0, sizeof(fmt)); - fmt.fmt.version = SFIO_VERSION; - fmt.fmt.extf = scformat; - fmt.expr = ex; - fmt.env = env; - u = eval(ex, expr->data.scan.format, env); - fmt.fmt.form = u.string; - fmt.actuals = expr->data.scan.args; - n = sp ? sfscanf(sp, "%!", &fmt) : sfsscanf(v.string, "%!", &fmt); - if (fmt.tmp) - sfstrclose(fmt.tmp); - if (fmt.actuals && !*fmt.fmt.form) - exerror("scanf: %s: too many arguments", - fmt.actuals->data.operand.left->data.variable.symbol-> - name); - return n; + get: + memset(&fmt, 0, sizeof(fmt)); + fmt.fmt.version = SFIO_VERSION; + fmt.fmt.extf = scformat; + fmt.expr = ex; + fmt.env = env; + u = eval(ex, expr->data.scan.format, env); + fmt.fmt.form = u.string; + fmt.actuals = expr->data.scan.args; + n = sp ? sfscanf(sp, "%!", &fmt) : sfsscanf(v.string, "%!", &fmt); + if (fmt.tmp) sfstrclose(fmt.tmp); + if (fmt.actuals && !*fmt.fmt.form) + exerror("scanf: %s: too many arguments", fmt.actuals->data.operand.left->data.variable.symbol->name); + return n; } /* * string add */ -static char *str_add(Expr_t * ex, register char *l, register char *r) +static char* +str_add(Expr_t* ex, register char* l, register char* r) { - sfprintf(ex->tmp, "%s%s", l, r); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + sfprintf(ex->tmp, "%s%s", l, r); + return exstash(ex->tmp, ex->ve); } /* * string ior */ -static char *str_ior(Expr_t * ex, register char *l, register char *r) +static char* +str_ior(Expr_t* ex, register char* l, register char* r) { - register int c; - register char *s = l; - - while ((c = *s++)) - if (!strchr(s, c)) - sfputc(ex->tmp, c); - while ((c = *r++)) - if (!strchr(l, c) && !strchr(r, c)) - sfputc(ex->tmp, c); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + register int c; + register char* s = l; + + while ((c = *s++)) + if (!strchr(s, c)) + sfputc(ex->tmp, c); + while ((c = *r++)) + if (!strchr(l, c) && !strchr(r, c)) + sfputc(ex->tmp, c); + return exstash(ex->tmp, ex->ve); } /* * string and */ -static char *str_and(Expr_t * ex, register char *l, register char *r) +static char* +str_and(Expr_t* ex, register char* l, register char* r) { - register int c; + register int c; - while ((c = *l++)) - if (strchr(r, c) && !strchr(l, c)) - sfputc(ex->tmp, c); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + while ((c = *l++)) + if (strchr(r, c) && !strchr(l, c)) + sfputc(ex->tmp, c); + return exstash(ex->tmp, ex->ve); } /* * string xor */ -static char *str_xor(Expr_t * ex, register char *l, register char *r) +static char* +str_xor(Expr_t* ex, register char* l, register char* r) { - register int c; - register char *s = l; - - while ((c = *s++)) - if (!strchr(r, c) && !strchr(s, c)) - sfputc(ex->tmp, c); - while ((c = *r++)) - if (!strchr(l, c) && !strchr(r, c)) - sfputc(ex->tmp, c); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + register int c; + register char* s = l; + + while ((c = *s++)) + if (!strchr(r, c) && !strchr(s, c)) + sfputc(ex->tmp, c); + while ((c = *r++)) + if (!strchr(l, c) && !strchr(r, c)) + sfputc(ex->tmp, c); + return exstash(ex->tmp, ex->ve); } /* * string mod */ -static char *str_mod(Expr_t * ex, register char *l, register char *r) +static char* +str_mod(Expr_t* ex, register char* l, register char* r) { - register int c; + register int c; - while ((c = *l++)) - if (!strchr(r, c) && !strchr(l, c)) - sfputc(ex->tmp, c); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + while ((c = *l++)) + if (!strchr(r, c) && !strchr(l, c)) + sfputc(ex->tmp, c); + return exstash(ex->tmp, ex->ve); } /* * string mpy */ - -static char *str_mpy(Expr_t * ex, register char *l, register char *r) +static char* +str_mpy(Expr_t* ex, register char* l, register char* r) { - register int lc; - register int rc; + register int lc; + register int rc; - while ((lc = *l++) && (rc = *r++)) - sfputc(ex->tmp, lc == rc ? lc : ' '); - return vmstrdup(ex->vc, sfstruse(ex->tmp)); + while ((lc = *l++) && (rc = *r++)) + sfputc(ex->tmp, lc == rc ? lc : ' '); + return exstash(ex->tmp, ex->ve); } /* replace: @@ -628,23 +652,23 @@ static char *str_mpy(Expr_t * ex, register char *l, register char *r) static void replace(Sfio_t * s, char *base, register char *repl, int ng, int *sub) { - char c; - int idx, offset; + char c; + int idx, offset; - while ((c = *repl++)) { + while ((c = *repl++)) { if (c == '\\') { if ((c = *repl) && isdigit(c)) { - idx = c - '0'; - if (idx < ng) { - offset = sub[2 * idx]; - sfwrite(s, base + offset, sub[2 * idx + 1] - offset); - } - repl++; + idx = c - '0'; + if (idx < ng) { + offset = sub[2 * idx]; + sfwrite(s, base + offset, sub[2 * idx + 1] - offset); + } + repl++; } else - sfputc(s, '\\'); + sfputc(s, '\\'); } else sfputc(s, c); - } + } } #define MCNT(s) (sizeof(s)/(2*sizeof(int))) @@ -652,15 +676,15 @@ replace(Sfio_t * s, char *base, register char *repl, int ng, int *sub) static void addItem (Dt_t* arr, Extype_t v, char* tok) { - Exassoc_t* b; + Exassoc_t* b; - if (!(b = (Exassoc_t *) dtmatch(arr, &v))) { - if (!(b = newof(0, Exassoc_t, 1, 0))) - exerror("out of space [assoc]"); - b->key = v; - dtinsert(arr, b); - } - b->value.string = tok; + if (!(b = (Exassoc_t *) dtmatch(arr, &v))) { + if (!(b = newof(0, Exassoc_t, 1, 0))) + exerror("out of space [assoc]"); + b->key = v; + dtinsert(arr, b); + } + b->value.string = tok; } /* exsplit: @@ -670,45 +694,45 @@ addItem (Dt_t* arr, Extype_t v, char* tok) Extype_t exsplit(Expr_t * ex, register Exnode_t * expr, void *env) { - Extype_t v; - char *str; - char *seps; - char *tok; - size_t sz; - Sfio_t* fp = ex->tmp; - Dt_t* arr = (Dt_t*)expr->data.split.array->local.pointer; - int i; + Extype_t v; + char *str; + char *seps; + char *tok; + size_t sz; + Sfio_t* fp = ex->tmp; + Dt_t* arr = (Dt_t*)expr->data.split.array->local.pointer; + int i; + + str = (eval(ex, expr->data.split.string, env)).string; + if (expr->data.split.seps) + seps = (eval(ex, expr->data.split.seps, env)).string; + else + seps = " \t\n"; - str = (eval(ex, expr->data.split.string, env)).string; - if (expr->data.split.seps) - seps = (eval(ex, expr->data.split.seps, env)).string; - else - seps = " \t\n"; - - v.integer = 0; - while (*str) { - sz = strspn (str, seps); - for (i = 0; i < sz; i++) { - addItem (arr, v, ""); - v.integer++; - } - str += sz; - if (*str == '\0') { - if (v.integer == sz) { /* only separators */ - addItem (arr, v, ""); + v.integer = 0; + while (*str) { + sz = strspn (str, seps); + for (i = 0; i < sz; i++) { + addItem (arr, v, ""); + v.integer++; + } + str += sz; + if (*str == '\0') { + if (v.integer == sz) { /* only separators */ + addItem (arr, v, ""); + v.integer++; + } + break; + } + sz = strcspn (str, seps); + sfwrite (fp, str, sz); + tok = exstrdup(ex, sfstruse(fp)); + addItem (arr, v, tok); v.integer++; - } - break; + str += sz; } - sz = strcspn (str, seps); - sfwrite (fp, str, sz); - tok = exstrdup(ex, sfstruse(fp)); - addItem (arr, v, tok); - v.integer++; - str += sz; - } - return v; + return v; } /* extoken: @@ -718,37 +742,37 @@ exsplit(Expr_t * ex, register Exnode_t * expr, void *env) Extype_t extokens(Expr_t * ex, register Exnode_t * expr, void *env) { - Extype_t v; - char *str; - char *seps; - char *tok; - size_t sz; - Sfio_t* fp = ex->tmp; - Dt_t* arr = (Dt_t*)expr->data.split.array->local.pointer; - - str = (eval(ex, expr->data.split.string, env)).string; - if (expr->data.split.seps) - seps = (eval(ex, expr->data.split.seps, env)).string; - else - seps = " \t\n"; - - v.integer = 0; - while (*str) { - sz = strspn (str, seps); - str += sz; - if (*str == '\0') - break; - - sz = strcspn (str, seps); - assert (sz); - sfwrite (fp, str, sz); - tok = exstrdup(ex, sfstruse(fp)); - addItem (arr, v, tok); - v.integer++; - str += sz; - } + Extype_t v; + char *str; + char *seps; + char *tok; + size_t sz; + Sfio_t* fp = ex->tmp; + Dt_t* arr = (Dt_t*)expr->data.split.array->local.pointer; + + str = (eval(ex, expr->data.split.string, env)).string; + if (expr->data.split.seps) + seps = (eval(ex, expr->data.split.seps, env)).string; + else + seps = " \t\n"; - return v; + v.integer = 0; + while (*str) { + sz = strspn (str, seps); + str += sz; + if (*str == '\0') + break; + + sz = strcspn (str, seps); + assert (sz); + sfwrite (fp, str, sz); + tok = exstrdup(ex, sfstruse(fp)); + addItem (arr, v, tok); + v.integer++; + str += sz; + } + + return v; } /* exsub: @@ -757,70 +781,70 @@ extokens(Expr_t * ex, register Exnode_t * expr, void *env) Extype_t exsub(Expr_t * ex, register Exnode_t * expr, void *env, int global) { - char *str; - char *pat; - char *repl; - char *p; - char *s; - Extype_t v; - int sub[20]; - int flags = STR_MAXIMAL; - int ng; - - str = (eval(ex, expr->data.string.base, env)).string; - pat = (eval(ex, expr->data.string.pat, env)).string; - if (expr->data.string.repl) - repl = (eval(ex, expr->data.string.repl, env)).string; - else - repl = 0; - - if (!global) { - if (*pat == '^') { - pat++; - flags |= STR_LEFT; + char *str; + char *pat; + char *repl; + char *p; + char *s; + Extype_t v; + int sub[20]; + int flags = STR_MAXIMAL; + int ng; + + str = (eval(ex, expr->data.string.base, env)).string; + pat = (eval(ex, expr->data.string.pat, env)).string; + if (expr->data.string.repl) + repl = (eval(ex, expr->data.string.repl, env)).string; + else + repl = 0; + + if (!global) { + if (*pat == '^') { + pat++; + flags |= STR_LEFT; + } + p = pat; + while (*p) + p++; + if (p > pat) + p--; + if (*p == '$') { + if ((p > pat) && (*(p - 1) == '\\')) { + *p-- = '\0'; + *p = '$'; + } else { + flags |= STR_RIGHT; + *p = '\0'; + } + } } - p = pat; - while (*p) - p++; - if (p > pat) - p--; - if (*p == '$') { - if ((p > pat) && (*(p - 1) == '\\')) { - *p-- = '\0'; - *p = '$'; - } else { - flags |= STR_RIGHT; - *p = '\0'; - } + if (*pat == '\0') { + v.string = vmstrdup(ex->ve, str); + return v; } - } - if (*pat == '\0') { - v.string = vmstrdup(ex->vc, str); - return v; - } - ng = strgrpmatch(str, pat, sub, MCNT(sub), flags); - if (ng == 0) { - v.string = vmstrdup(ex->vc, str); - return v; - } - sfwrite(ex->tmp, str, sub[0]); - if (repl) - replace(ex->tmp, str, repl, ng, sub); - - s = str + sub[1]; - if (global) { - while ((ng = strgrpmatch(s, pat, sub, MCNT(sub), flags))) { - sfwrite(ex->tmp, s, sub[0]); - if (repl) - replace(ex->tmp, s, repl, ng, sub); - s = s + sub[1]; + ng = strgrpmatch(str, pat, sub, MCNT(sub), flags); + if (ng == 0) { + v.string = vmstrdup(ex->ve, str); + return v; + } + sfwrite(ex->tmp, str, sub[0]); + if (repl) + replace(ex->tmp, str, repl, ng, sub); + + s = str + sub[1]; + if (global) { + while ((ng = strgrpmatch(s, pat, sub, MCNT(sub), flags))) { + sfwrite(ex->tmp, s, sub[0]); + if (repl) + replace(ex->tmp, s, repl, ng, sub); + s = s + sub[1]; + } } - } - sfputr(ex->tmp, s, -1); - v.string = vmstrdup(ex->vc, sfstruse(ex->tmp)); - return v; + sfputr(ex->tmp, s, -1); + v.string = exstash(ex->tmp,ex->ve); + return v; } /* exsubstr: @@ -828,33 +852,31 @@ exsub(Expr_t * ex, register Exnode_t * expr, void *env, int global) */ static Extype_t exsubstr(Expr_t * ex, register Exnode_t * expr, void *env) { - Extype_t s; - Extype_t i; - Extype_t l; - Extype_t v; - int len; - - s = eval(ex, expr->data.string.base, env); - len = strlen(s.string); - i = eval(ex, expr->data.string.pat, env); - if ((i.integer < 0) || (len < i.integer)) - exerror("illegal start index in substr(%s,%d)", - s.string, i.integer); - if (expr->data.string.repl) { - l = eval(ex, expr->data.string.repl, env); - if ((l.integer < 0) || (len - i.integer < l.integer)) - exerror("illegal length in substr(%s,%d,%d)", - s.string, i.integer, l.integer); - } else - l.integer = len - i.integer; + Extype_t s; + Extype_t i; + Extype_t l; + Extype_t v; + int len; + + s = eval(ex, expr->data.string.base, env); + len = strlen(s.string); + i = eval(ex, expr->data.string.pat, env); + if ((i.integer < 0) || (len < i.integer)) + exerror("illegal start index in substr(%s,%d)", s.string, i.integer); + if (expr->data.string.repl) { + l = eval(ex, expr->data.string.repl, env); + if ((l.integer < 0) || (len - i.integer < l.integer)) + exerror("illegal length in substr(%s,%d,%d)", s.string, i.integer, l.integer); + } else + l.integer = len - i.integer; - v.string = vmalloc(ex->vc, l.integer + 1); - if (expr->data.string.repl) { - strncpy(v.string, s.string + i.integer, l.integer); - v.string[l.integer] = '\0'; - } else - strcpy(v.string, s.string + i.integer); - return v; + v.string = vmalloc(ex->ve, l.integer + 1); + if (expr->data.string.repl) { + strncpy(v.string, s.string + i.integer, l.integer); + v.string[l.integer] = '\0'; + } else + strcpy(v.string, s.string + i.integer); + return v; } /* xConvert: @@ -864,17 +886,15 @@ static void xConvert(Expr_t * ex, Exnode_t * expr, int type, Extype_t v, Exnode_t * tmp) { - *tmp = *expr->data.operand.left; - tmp->data.constant.value = v; - if ((*ex->disc->convertf) (ex, tmp, type, - expr->data.operand.right ? expr->data. - operand.right->data.variable. - symbol : (Exid_t *) 0, 0, ex->disc)) - exerror("%s: cannot convert %s value to %s", - expr->data.operand.left->data.variable.symbol->name, - extypename(ex, expr->data.operand.left->type), - extypename(ex, type)); - tmp->type = type; + *tmp = *expr->data.operand.left; + tmp->data.constant.value = v; + if ((*ex->disc->convertf) (ex, tmp, type, expr->data.operand.right ? expr->data. + operand.right->data.variable.symbol : (Exid_t *) 0, 0, ex->disc)) { + exerror("%s: cannot convert %s value to %s", + expr->data.operand.left->data.variable.symbol->name, + extypename(ex, expr->data.operand.left->type), extypename(ex, type)); + } + tmp->type = type; } /* xPrint: @@ -883,13 +903,13 @@ xConvert(Expr_t * ex, Exnode_t * expr, int type, Extype_t v, static void xPrint(Expr_t * ex, Exnode_t * expr, Extype_t v, Exnode_t * tmp) { - *tmp = *expr->data.operand.left; - tmp->data.constant.value = v; - if ((*ex->disc->stringof) (ex, tmp, 0, ex->disc)) + *tmp = *expr->data.operand.left; + tmp->data.constant.value = v; + if ((*ex->disc->stringof) (ex, tmp, 0, ex->disc)) exerror("%s: no string representation of %s value", expr->data.operand.left->data.variable.symbol->name, extypename(ex, expr->data.operand.left->type)); - tmp->type = STRING; + tmp->type = STRING; } /* @@ -897,1068 +917,976 @@ xPrint(Expr_t * ex, Exnode_t * expr, Extype_t v, Exnode_t * tmp) */ static long seed; -static Extype_t eval(Expr_t * ex, register Exnode_t * expr, void *env) +static Extype_t +eval(Expr_t* ex, register Exnode_t* expr, void* env) { - register Exnode_t *x; - register Exnode_t *a; - register Extype_t **t; - register int n; - Extype_t v; - Extype_t r; - Extype_t i; - char *e; - Exnode_t tmp; - Exnode_t rtmp; - Exnode_t *rp; - Exassoc_t *assoc; - Extype_t args[FRAME]; - Extype_t save[FRAME]; - - if (!expr || ex->loopcount) { - v.integer = 1; - return v; - } - x = expr->data.operand.left; - switch (expr->op) { - case BREAK: - case CONTINUE: - v = eval(ex, x, env); - ex->loopcount = v.integer; - ex->loopop = expr->op; - return v; - case CONSTANT: - return expr->data.constant.value; - case DEC: - n = -1; - add: - if (x->op == DYNAMIC) - r = getdyn(ex, x, env, &assoc); - else { - if (x->data.variable.index) - i = eval(ex, x->data.variable.index, env); - else - i.integer = EX_SCALAR; + register Exnode_t* x; + register Exnode_t* a; + register Extype_t** t; + register int n; + Extype_t v; + Extype_t r; + Extype_t i; + char* e; + Exnode_t tmp; + Exnode_t rtmp; + Exnode_t* rp; + Exassoc_t* assoc; + Extype_t args[FRAME+1]; + Extype_t save[FRAME]; + + if (!expr || ex->loopcount) + { + v.integer = 1; + return v; + } + x = expr->data.operand.left; + switch (expr->op) + { + case BREAK: + case CONTINUE: + v = eval(ex, x, env); + ex->loopcount = v.integer; + ex->loopop = expr->op; + return v; + case CONSTANT: + return expr->data.constant.value; + case DEC: + n = -1; + add: + if (x->op == DYNAMIC) + r = getdyn(ex, x, env, &assoc); + else + { + if (x->data.variable.index) + i = eval(ex, x->data.variable.index, env); + else + i.integer = EX_SCALAR; #ifndef OLD - if (x->data.variable.dyna) { - Extype_t locv; - locv = getdyn(ex, x->data.variable.dyna, env, &assoc); - x->data.variable.dyna->data.variable.dyna->data.constant. - value = locv; - } + if (x->data.variable.dyna) { + Extype_t locv; + locv = getdyn(ex, x->data.variable.dyna, env, &assoc); + x->data.variable.dyna->data.variable.dyna->data.constant.value = locv; + } #endif - r = (*ex->disc->getf) (ex, x, x->data.variable.symbol, - x->data.variable.reference, env, - (int) i.integer, ex->disc); - } - v = r; - switch (x->type) { - case FLOATING: - v.floating += n; - break; - case INTEGER: - case UNSIGNED: - v.integer += n; - break; - default: - goto huh; - } - set: - if (x->op == DYNAMIC) { - if (x->type == STRING) { - v.string = vmstrdup(ex->vm, v.string); - if ((e = - assoc ? assoc->value.string : x->data.variable. - symbol->value->data.constant.value.string)) - vmfree(ex->vm, e); - } - if (assoc) - assoc->value = v; - else - x->data.variable.symbol->value->data.constant.value = v; - } else { - if (x->data.variable.index) - i = eval(ex, x->data.variable.index, env); - else - i.integer = EX_SCALAR; + r = (*ex->disc->getf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)i.integer, ex->disc); + } + v = r; + switch (x->type) + { + case FLOATING: + v.floating += n; + break; + case INTEGER: + case UNSIGNED: + v.integer += n; + break; + default: + goto huh; + } + set: + if (x->op == DYNAMIC) + { + if (x->type == STRING) + { + v.string = vmstrdup(ex->vm, v.string); + if ((e = assoc ? assoc->value.string : x->data.variable.symbol->value->data.constant.value.string)) + vmfree(ex->vm, e); + } + if (assoc) + assoc->value = v; + else + x->data.variable.symbol->value->data.constant.value = v; + } + else + { + if (x->data.variable.index) + i = eval(ex, x->data.variable.index, env); + else + i.integer = EX_SCALAR; #ifndef OLD - if (x->data.variable.dyna) { - Extype_t locv; - locv = getdyn(ex, x->data.variable.dyna, env, &assoc); - x->data.variable.dyna->data.variable.dyna->data.constant. - value = locv; - } + if (x->data.variable.dyna) { + Extype_t locv; + locv = getdyn(ex, x->data.variable.dyna, env, &assoc); + x->data.variable.dyna->data.variable.dyna->data.constant.value = locv; + } #endif - if ((*ex->disc->setf) (ex, x, x->data.variable.symbol, - x->data.variable.reference, env, - (int) i.integer, v, ex->disc) < 0) - exerror("%s: cannot set value", - x->data.variable.symbol->name); - } - if (expr->subop == PRE) - r = v; - return r; - case DYNAMIC: - return getdyn(ex, expr, env, &assoc); - case SPLIT: - return exsplit(ex, expr, env); - case TOKENS: - return extokens(ex, expr, env); - case GSUB: - return exsub(ex, expr, env, 1); - case SUB: - return exsub(ex, expr, env, 0); - case SUBSTR: - return exsubstr(ex, expr, env); - case SRAND: - v.integer = seed; - if (expr->binary) { - seed = eval(ex, x, env).integer; - } else - seed = time(0); - srand48(seed); - return v; - case RAND: - v.floating = drand48(); - return v; - case EXIT: - v = eval(ex, x, env); - if (ex->disc->exitf) - (*ex->disc->exitf) (ex, env, (int)v.integer); - else - exit((int) v.integer); - /*NOTREACHED*/ v.integer = -1; - return v; - case IF: - v = eval(ex, x, env); - if (v.integer) - eval(ex, expr->data.operand.right->data.operand.left, env); - else - eval(ex, expr->data.operand.right->data.operand.right, env); - v.integer = 1; - return v; - case FOR: - case WHILE: - expr = expr->data.operand.right; - for (;;) { - r = eval(ex, x, env); - if (!r.integer) { + if ((*ex->disc->setf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)i.integer, v, ex->disc) < 0) + exerror("%s: cannot set value", x->data.variable.symbol->name); + } + if (expr->subop == PRE) + r = v; + return r; + case DYNAMIC: + return getdyn(ex, expr, env, &assoc); + case SPLIT: + return exsplit(ex, expr, env); + case TOKENS: + return extokens(ex, expr, env); + case GSUB: + return exsub(ex, expr, env, 1); + case SUB: + return exsub(ex, expr, env, 0); + case SUBSTR: + return exsubstr(ex, expr, env); + case SRAND: + v.integer = seed; + if (expr->binary) { + seed = eval(ex, x, env).integer; + } else + seed = time(0); + srand48(seed); + return v; + case RAND: + v.floating = drand48(); + return v; + case EXIT: + v = eval(ex, x, env); + if (ex->disc->exitf) + (*ex->disc->exitf) (ex, env, (int)v.integer); + else + exit((int)v.integer); + /*NOTREACHED*/ + v.integer = -1; + return v; + case IF: + v = eval(ex, x, env); + if (v.integer) + eval(ex, expr->data.operand.right->data.operand.left, env); + else + eval(ex, expr->data.operand.right->data.operand.right, env); v.integer = 1; return v; - } - if (expr->data.operand.right) { - eval(ex, expr->data.operand.right, env); - if (ex->loopcount > 0 - && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { - v.integer = 0; - return v; + case FOR: + case WHILE: + expr = expr->data.operand.right; + for (;;) + { + r = eval(ex, x, env); + if (!r.integer) + { + v.integer = 1; + return v; + } + if (expr->data.operand.right) + { + eval(ex, expr->data.operand.right, env); + if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) + { + v.integer = 0; + return v; + } + } + if (expr->data.operand.left) + eval(ex, expr->data.operand.left, env); } - } - if (expr->data.operand.left) - eval(ex, expr->data.operand.left, env); - } - /*NOTREACHED*/ case SWITCH: - v = eval(ex, x, env); - i.integer = x->type; - r.integer = 0; - x = expr->data.operand.right; - a = x->data.select.statement; - n = 0; - while ((x = x->data.select.next)) { - if (!(t = x->data.select.constant)) - n = 1; - else - for (; *t; t++) { - switch ((int) i.integer) { - case INTEGER: - case UNSIGNED: - if ((*t)->integer == v.integer) - break; - continue; - case STRING: - if ((ex->disc->version >= 19981111L - && ex->disc->matchf) ? (*ex->disc-> - matchf) (ex, x, - (*t)->string, - expr->data. - operand.left, - v.string, - env, - ex-> - disc) : - strmatch((*t)->string, v.string)) - break; - continue; - case FLOATING: - if ((*t)->floating == v.floating) - break; - continue; - } - n = 1; - break; + /*NOTREACHED*/ + case SWITCH: + v = eval(ex, x, env); + i.integer = x->type; + r.integer = 0; + x = expr->data.operand.right; + a = x->data.select.statement; + n = 0; + while ((x = x->data.select.next)) + { + if (!(t = x->data.select.constant)) + n = 1; + else + for (; *t; t++) + { + switch ((int)i.integer) + { + case INTEGER: + case UNSIGNED: + if ((*t)->integer == v.integer) + break; + continue; + case STRING: + if ((ex->disc->version >= 19981111L && ex->disc->matchf) ? (*ex->disc->matchf)(ex, x, (*t)->string, expr->data.operand.left, v.string, env, ex->disc) : strmatch((*t)->string, v.string)) + break; + continue; + case FLOATING: + if ((*t)->floating == v.floating) + break; + continue; + } + n = 1; + break; + } + if (n) + { + if (!x->data.select.statement) + { + r.integer = 1; + break; + } + r = eval(ex, x->data.select.statement, env); + if (ex->loopcount > 0) + { + ex->loopcount--; + break; + } + } } - if (n) { - if (!x->data.select.statement) { - r.integer = 1; - break; + if (!n && a) + { + r = eval(ex, a, env); + if (ex->loopcount > 0) + ex->loopcount--; } - r = eval(ex, x->data.select.statement, env); - if (ex->loopcount > 0) { - ex->loopcount--; - break; + return r; + case ITERATE: + v.integer = 0; + if (expr->data.generate.array->op == DYNAMIC) + { + n = expr->data.generate.index->type == STRING; + for (assoc = (Exassoc_t*)dtfirst((Dt_t*)expr->data.generate.array->data.variable.symbol->local.pointer); assoc; assoc = (Exassoc_t*)dtnext((Dt_t*)expr->data.generate.array->data.variable.symbol->local.pointer, assoc)) + { + v.integer++; + if (n) + expr->data.generate.index->value->data.constant.value.string = assoc->name; + else + expr->data.generate.index->value->data.constant.value = assoc->key; + eval(ex, expr->data.generate.statement, env); + if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) + { + v.integer = 0; + break; + } + } } - } - } - if (!n && a) { - r = eval(ex, a, env); - if (ex->loopcount > 0) - ex->loopcount--; - } - return r; - case ITERATE: - v.integer = 0; - if (expr->data.generate.array->op == DYNAMIC) { - n = expr->data.generate.index->type == STRING; - for (assoc = - (Exassoc_t *) dtfirst((Dt_t *) expr->data.generate.array-> - data.variable.symbol->local. - pointer); assoc; - assoc = - (Exassoc_t *) dtnext((Dt_t *) expr->data.generate.array-> - data.variable.symbol->local.pointer, - assoc)) { - v.integer++; - if (n) - expr->data.generate.index->value->data.constant.value. - string = assoc->name; else - expr->data.generate.index->value->data.constant.value = - assoc->key; - eval(ex, expr->data.generate.statement, env); - if (ex->loopcount > 0 - && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { - v.integer = 0; - break; - } - } - } else { - r = (*ex->disc->getf) (ex, expr, - expr->data.generate.array->data. - variable.symbol, - expr->data.generate.array->data. - variable.reference, env, 0, ex->disc); - for (v.integer = 0; v.integer < r.integer; v.integer++) { - expr->data.generate.index->value->data.constant.value. - integer = v.integer; - eval(ex, expr->data.generate.statement, env); - if (ex->loopcount > 0 - && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { - v.integer = 0; - break; + { + r = (*ex->disc->getf)(ex, expr, expr->data.generate.array->data.variable.symbol, expr->data.generate.array->data.variable.reference, env, 0, ex->disc); + for (v.integer = 0; v.integer < r.integer; v.integer++) + { + expr->data.generate.index->value->data.constant.value.integer = v.integer; + eval(ex, expr->data.generate.statement, env); + if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) + { + v.integer = 0; + break; + } + } } - } - } - return v; + return v; case ITERATER: - v.integer = 0; - if (expr->data.generate.array->op == DYNAMIC) { - n = expr->data.generate.index->type == STRING; - for (assoc = - (Exassoc_t *) dtlast((Dt_t *) expr->data.generate.array-> - data.variable.symbol->local. - pointer); assoc; - assoc = - (Exassoc_t *) dtprev((Dt_t *) expr->data.generate.array-> - data.variable.symbol->local.pointer, - assoc)) { - v.integer++; - if (n) - expr->data.generate.index->value->data.constant.value. - string = assoc->name; - else - expr->data.generate.index->value->data.constant.value = - assoc->key; - eval(ex, expr->data.generate.statement, env); - if (ex->loopcount > 0 - && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { - v.integer = 0; - break; + v.integer = 0; + if (expr->data.generate.array->op == DYNAMIC) { + n = expr->data.generate.index->type == STRING; + for (assoc = (Exassoc_t *) dtlast((Dt_t *) expr->data.generate.array-> + data.variable.symbol->local. + pointer); assoc; + assoc = (Exassoc_t *) dtprev((Dt_t *) expr->data.generate.array-> + data.variable.symbol->local.pointer, + assoc)) { + v.integer++; + if (n) + expr->data.generate.index->value->data.constant.value.string = assoc->name; + else + expr->data.generate.index->value->data.constant.value = assoc->key; + eval(ex, expr->data.generate.statement, env); + if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { + v.integer = 0; + break; + } + } + } else { + r = (*ex->disc->getf) (ex, expr, expr->data.generate.array->data. + variable.symbol, expr->data.generate.array->data. variable.reference, env, 0, ex->disc); + for (v.integer = r.integer-1; 0 <= v.integer; v.integer--) { + expr->data.generate.index->value->data.constant.value.integer = v.integer; + eval(ex, expr->data.generate.statement, env); + if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { + v.integer = 0; + break; + } + } } - } - } else { - r = (*ex->disc->getf) (ex, expr, - expr->data.generate.array->data. - variable.symbol, - expr->data.generate.array->data. - variable.reference, env, 0, ex->disc); - for (v.integer = r.integer-1; 0 <= v.integer; v.integer--) { - expr->data.generate.index->value->data.constant.value. - integer = v.integer; - eval(ex, expr->data.generate.statement, env); - if (ex->loopcount > 0 - && (--ex->loopcount > 0 || ex->loopop != CONTINUE)) { - v.integer = 0; - break; + return v; + case '#': + v.integer = dtsize ((Dt_t*)expr->data.variable.symbol->local.pointer); + return v; + case IN_OP: + v.integer = evaldyn (ex, expr, env, 0); + return v; + case UNSET: + if (expr->data.variable.index) { + v.integer = evaldyn (ex, expr, env, 1); } - } - } - return v; - case '#': - v.integer = dtsize ((Dt_t*)expr->data.variable.symbol->local.pointer); - return v; - case IN_OP: - v.integer = evaldyn (ex, expr, env, 0); - return v; - case UNSET: - if (expr->data.variable.index) { - v.integer = evaldyn (ex, expr, env, 1); - } - else { - dtclear ((Dt_t*)expr->data.variable.symbol->local.pointer); - v.integer = 0; - } - return v; - case CALL: - x = expr->data.call.args; - for (n = 0, a = - expr->data.call.procedure->value->data.procedure.args; a && x; - a = a->data.operand.right) { - if (n < elementsof(args)) { - save[n] = - a->data.operand.left->data.variable.symbol->value-> - data.constant.value; - args[n++] = eval(ex, x->data.operand.left, env); - } else - a->data.operand.left->data.variable.symbol->value->data. - constant.value = eval(ex, x->data.operand.left, env); - x = x->data.operand.right; - } - for (n = 0, a = - expr->data.call.procedure->value->data.procedure.args; - a && n < elementsof(save); a = a->data.operand.right) - a->data.operand.left->data.variable.symbol->value->data. - constant.value = args[n++]; - if (x) - exerror("too many actual args"); - else if (a) - exerror("not enough actual args"); - v = exeval(ex, - expr->data.call.procedure->value->data.procedure.body, - env); - for (n = 0, a = - expr->data.call.procedure->value->data.procedure.args; - a && n < elementsof(save); a = a->data.operand.right) - a->data.operand.left->data.variable.symbol->value->data. - constant.value = save[n++]; - return v; - case ARRAY: - n = 0; - for (x = expr->data.operand.right; x && n < elementsof(args); - x = x->data.operand.right) - args[n++] = eval(ex, x->data.operand.left, env); - return (*ex->disc->getf) (ex, expr->data.operand.left, - expr->data.operand.left->data.variable. - symbol, - expr->data.operand.left->data.variable. - reference, args, EX_ARRAY, ex->disc); - case FUNCTION: - n = 0; - for (x = expr->data.operand.right; x && n < elementsof(args); - x = x->data.operand.right) - args[n++] = eval(ex, x->data.operand.left, env); - return (*ex->disc->getf) (ex, expr->data.operand.left, - expr->data.operand.left->data.variable. - symbol, - expr->data.operand.left->data.variable. - reference, args, EX_CALL, ex->disc); - case ID: - if (expr->data.variable.index) - i = eval(ex, expr->data.variable.index, env); - else - i.integer = EX_SCALAR; + else { + dtclear ((Dt_t*)expr->data.variable.symbol->local.pointer); + v.integer = 0; + } + return v; + case CALL: + x = expr->data.call.args; + for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && x; a = a->data.operand.right) + { + if (n < elementsof(args)) + { + save[n] = a->data.operand.left->data.variable.symbol->value->data.constant.value; + args[n++] = eval(ex, x->data.operand.left, env); + } + else + a->data.operand.left->data.variable.symbol->value->data.constant.value = eval(ex, x->data.operand.left, env); + x = x->data.operand.right; + } + for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && n < elementsof(save); a = a->data.operand.right) + a->data.operand.left->data.variable.symbol->value->data.constant.value = args[n++]; + if (x) + exerror("too many actual args"); + else if (a) + exerror("not enough actual args"); + v = exeval(ex, expr->data.call.procedure->value->data.procedure.body, env); + for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && n < elementsof(save); a = a->data.operand.right) + a->data.operand.left->data.variable.symbol->value->data.constant.value = save[n++]; + return v; + case ARRAY: + n = 0; + for (x = expr->data.operand.right; x && n < elementsof(args); x = x->data.operand.right) + args[n++] = eval(ex, x->data.operand.left, env); + return (*ex->disc->getf) (ex, expr->data.operand.left, expr->data.operand.left->data.variable.symbol, + expr->data.operand.left->data.variable.reference, args, EX_ARRAY, ex->disc); + case FUNCTION: + n = 0; + args[n++].string = (char*)env; + for (x = expr->data.operand.right; x && n < elementsof(args); x = x->data.operand.right) + args[n++] = eval(ex, x->data.operand.left, env); + return (*ex->disc->getf)(ex, expr->data.operand.left, expr->data.operand.left->data.variable.symbol, expr->data.operand.left->data.variable.reference, args+1, EX_CALL, ex->disc); + case ID: + if (expr->data.variable.index) + i = eval(ex, expr->data.variable.index, env); + else + i.integer = EX_SCALAR; #ifndef OLD - if (expr->data.variable.dyna) { - Extype_t locv; - locv = getdyn(ex, expr->data.variable.dyna, env, &assoc); - expr->data.variable.dyna->data.variable.dyna->data.constant. - value = locv; - } + if (expr->data.variable.dyna) { + Extype_t locv; + locv = getdyn(ex, expr->data.variable.dyna, env, &assoc); + expr->data.variable.dyna->data.variable.dyna->data.constant. value = locv; + } #endif - return (*ex->disc->getf) (ex, expr, expr->data.variable.symbol, - expr->data.variable.reference, env, - (int) i.integer, ex->disc); - case INC: - n = 1; - goto add; - case PRINT: - v.integer = prints(ex, expr, env, sfstdout); - return v; - case PRINTF: - v.integer = print(ex, expr, env, NiL); - return v; + return (*ex->disc->getf)(ex, expr, expr->data.variable.symbol, expr->data.variable.reference, env, (int)i.integer, ex->disc); + case INC: + n = 1; + goto add; + case PRINT: + v.integer = prints(ex, expr, env, sfstdout); + return v; + case PRINTF: + v.integer = print(ex, expr, env, NiL); + return v; #ifdef UNUSED - case QUERY: - print(ex, expr, env, sfstderr); - v.integer = !astquery(2, ""); - return v; + case QUERY: + print(ex, expr, env, sfstderr); + v.integer = !astquery(2, ""); + return v; #endif - case RETURN: - ex->loopret = eval(ex, x, env); - ex->loopcount = 32767; - ex->loopop = expr->op; - return ex->loopret; - case SCANF: - case SSCANF: - v.integer = scan(ex, expr, env, NiL); - return v; - case SPRINTF: - print(ex, expr, env, ex->tmp); - v.string = vmstrdup(ex->ve, sfstruse(ex->tmp)); - return v; - case '=': - v = eval(ex, expr->data.operand.right, env); - if (expr->subop != '=') { - r = v; - if (x->op == DYNAMIC) - v = getdyn(ex, x, env, &assoc); - else { - if (x->data.variable.index) - v = eval(ex, x->data.variable.index, env); - else - v.integer = EX_SCALAR; + case RETURN: + ex->loopret = eval(ex, x, env); + ex->loopcount = 32767; + ex->loopop = expr->op; + return ex->loopret; + case SCANF: + case SSCANF: + v.integer = scan(ex, expr, env, NiL); + return v; + case SPRINTF: + print(ex, expr, env, ex->tmp); + v.string = exstash(ex->tmp, ex->ve); + return v; + case '=': + v = eval(ex, expr->data.operand.right, env); + if (expr->subop != '=') + { + r = v; + if (x->op == DYNAMIC) + v = getdyn(ex, x, env, &assoc); + else + { + if (x->data.variable.index) + v = eval(ex, x->data.variable.index, env); + else + v.integer = EX_SCALAR; #ifndef OLD - if (x->data.variable.dyna) { - Extype_t locv; - locv = getdyn(ex, x->data.variable.dyna, env, &assoc); - x->data.variable.dyna->data.variable.dyna->data. - constant.value = locv; - } + if (x->data.variable.dyna) { + Extype_t locv; + locv = getdyn(ex, x->data.variable.dyna, env, &assoc); + x->data.variable.dyna->data.variable.dyna->data. constant.value = locv; + } #endif - v = (*ex->disc->getf) (ex, x, x->data.variable.symbol, - x->data.variable.reference, env, - (int) v.integer, ex->disc); - } - switch (x->type) { - case FLOATING: - switch (expr->subop) { - case '+': - v.floating += r.floating; - break; + v = (*ex->disc->getf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)v.integer, ex->disc); + } + switch (x->type) + { + case FLOATING: + switch (expr->subop) + { + case '+': + v.floating += r.floating; + break; + case '-': + v.floating -= r.floating; + break; + case '*': + v.floating *= r.floating; + break; + case '/': + if (r.floating == 0.0) + exerror("floating divide by 0"); + else + v.floating /= r.floating; + break; + case '%': + if ((r.integer = r.floating) == 0) + exerror("floating 0 modulus"); + else + v.floating = ((Sflong_t)v.floating) % r.integer; + break; + case '&': + v.floating = ((Sflong_t)v.floating) & ((Sflong_t)r.floating); + break; + case '|': + v.floating = ((Sflong_t)v.floating) | ((Sflong_t)r.floating); + break; + case '^': + v.floating = ((Sflong_t)v.floating) ^ ((Sflong_t)r.floating); + break; + case LS: + v.floating = ((Sflong_t)v.floating) << ((Sflong_t)r.floating); + break; + case RS: +#if _WIN32 + v.floating = (Sflong_t)(((Sfulong_t)v.floating) >> ((Sflong_t)r.floating)); +#else + v.floating = ((Sfulong_t)v.floating) >> ((Sflong_t)r.floating); +#endif + break; + default: + goto huh; + } + break; + case INTEGER: + case UNSIGNED: + switch (expr->subop) + { + case '+': + v.integer += r.integer; + break; + case '-': + v.integer -= r.integer; + break; + case '*': + v.integer *= r.integer; + break; + case '/': + if (r.integer == 0) + exerror("integer divide by 0"); + else + v.integer /= r.integer; + break; + case '%': + if (r.integer == 0) + exerror("integer 0 modulus"); + else + v.integer %= r.integer; + break; + case '&': + v.integer &= r.integer; + break; + case '|': + v.integer |= r.integer; + break; + case '^': + v.integer ^= r.integer; + break; + case LS: + v.integer <<= r.integer; + break; + case RS: + v.integer = (Sfulong_t)v.integer >> r.integer; + break; + default: + goto huh; + } + break; + case STRING: + switch (expr->subop) + { + case '+': + v.string = str_add(ex, v.string, r.string); + break; + case '|': + v.string = str_ior(ex, v.string, r.string); + break; + case '&': + v.string = str_and(ex, v.string, r.string); + break; + case '^': + v.string = str_xor(ex, v.string, r.string); + break; + case '%': + v.string = str_mod(ex, v.string, r.string); + break; + case '*': + v.string = str_mpy(ex, v.string, r.string); + break; + default: + goto huh; + } + break; + default: + goto huh; + } + } + else if (x->op == DYNAMIC) + getdyn(ex, x, env, &assoc); + else + assoc = 0; + r = v; + goto set; + case ';': + case ',': + v = eval(ex, x, env); + while ((expr = expr->data.operand.right) && (expr->op == ';' || expr->op == ',')) + { + v = eval(ex, expr->data.operand.left, env); + if (ex->loopcount) + return v; + } + return expr ? eval(ex, expr, env) : v; + case '?': + v = eval(ex, x, env); + return v.integer ? eval(ex, expr->data.operand.right->data.operand.left, env) : eval(ex, expr->data.operand.right->data.operand.right, env); + case AND: + v = eval(ex, x, env); + return v.integer ? eval(ex, expr->data.operand.right, env) : v; + case OR: + v = eval(ex, x, env); + return v.integer ? v : eval(ex, expr->data.operand.right, env); + } + v = eval(ex, x, env); + if ((x = expr->data.operand.right)) { + r = eval(ex, x, env); + if (!BUILTIN(x->type) && expr->binary) { + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + rtmp = *x; + rtmp.data.constant.value = r; + if (!(*ex->disc->binaryf) (ex, &tmp, expr, &rtmp, 0, ex->disc)) return tmp.data.constant.value; + } + } + switch (expr->data.operand.left->type) + { + case FLOATING: + switch (expr->op) + { + case F2I: + v.integer = v.floating; + return v; + case F2S: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if (expr->data.operand.left->op != DYNAMIC && expr->data.operand.left->op != ID) + { + sfprintf(ex->tmp, "%g", v.floating); + tmp.data.constant.value.string = exstash(ex->tmp, ex->ve); + } + else if ((*ex->disc->convertf)(ex, &tmp, STRING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) { + sfprintf(ex->tmp, "%g", v.floating); + tmp.data.constant.value.string = exstash(ex->tmp, ex->ve); + } + tmp.type = STRING; + return tmp.data.constant.value; + case F2X: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if ((*ex->disc->convertf)(ex, &tmp, expr->type, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) + exerror("%s: cannot convert floating value to external", tmp.data.variable.symbol->name); + tmp.type = expr->type; + return tmp.data.constant.value; + case '!': + v.floating = !((Sflong_t)v.floating); + return v; + case '~': + v.floating = ~((Sflong_t)v.floating); + return v; case '-': - v.floating -= r.floating; - break; - case '*': - v.floating *= r.floating; - break; - case '/': - if (r.floating == 0.0) - exerror("floating divide by 0"); - else - v.floating /= r.floating; - break; - case '%': - if ((r.integer = r.floating) == 0) - exerror("floating 0 modulus"); - else - v.floating = ((Sflong_t) v.floating) % r.integer; - break; + if (x) + v.floating -= r.floating; + else + v.floating = -v.floating; + return v; + case '+': + v.floating += r.floating; + return v; case '&': - v.floating = - ((Sflong_t) v.floating) & ((Sflong_t) r.floating); - break; + v.floating = (Sflong_t)v.floating & (Sflong_t)r.floating; + return v; case '|': - v.floating = - ((Sflong_t) v.floating) | ((Sflong_t) r.floating); - break; + v.floating = (Sflong_t)v.floating | (Sflong_t)r.floating; + return v; case '^': - v.floating = - ((Sflong_t) v.floating) ^ ((Sflong_t) r.floating); - break; + v.floating = (Sflong_t)v.floating ^ (Sflong_t)r.floating; + return v; + case '*': + v.floating *= r.floating; + return v; + case '/': + if (r.floating == 0.0) + exerror("floating divide by 0"); + else + v.floating /= r.floating; + return v; + case '%': + if ((r.integer = r.floating) == 0) + exerror("floating 0 modulus"); + else + v.floating = (Sflong_t)v.floating % r.integer; + return v; + case '<': + v.integer = v.floating < r.floating; + return v; + case LE: + v.integer = v.floating <= r.floating; + return v; + case EQ: + v.integer = v.floating == r.floating; + return v; + case NE: + v.integer = v.floating != r.floating; + return v; + case GE: + v.integer = v.floating >= r.floating; + return v; + case '>': + v.integer = v.floating > r.floating; + return v; case LS: /* IBM compilers can't deal with these shift operators on long long. - * v.floating = ((Sflong_t)v.floating) << ((Sflong_t)r.floating); + * v.floating = ((Sflong_t)v.floating) << ((Sflong_t)r.floating); */ - { - Sflong_t op1, op2; - op1 = ((Sflong_t) v.floating); - op2 = ((Sflong_t) r.floating); - v.floating = (double) (op1 << op2); - } - break; + { + Sflong_t op1, op2; + op1 = ((Sflong_t) v.floating); + op2 = ((Sflong_t) r.floating); + v.floating = (double) (op1 << op2); + } + return v; case RS: #if _WIN32 - v.floating = - (Sflong_t) (((Sfulong_t) v. - floating) >> ((Sflong_t) r.floating)); + v.floating = (Sflong_t) (((Sfulong_t) v.floating) >> ((Sflong_t) r.floating)); #else /* IBM compilers can't deal with these shift operators on long long. - * v.floating = ((Sfulong_t)v.floating) >> ((Sflong_t)r.floating); + * v.floating = ((Sfulong_t)v.floating) >> ((Sflong_t)r.floating); */ - { - Sflong_t op1, op2; - op1 = ((Sfulong_t) v.floating); - op2 = ((Sflong_t) r.floating); - v.floating = (double) (op1 >> op2); - } + { + Sflong_t op1, op2; + op1 = ((Sfulong_t) v.floating); + op2 = ((Sflong_t) r.floating); + v.floating = (double) (op1 >> op2); + } #endif - break; - default: - goto huh; + + return v; } break; - case INTEGER: - case UNSIGNED: - switch (expr->subop) { - case '+': - v.integer += r.integer; - break; + default: + switch (expr->op) + { + case X2F: + xConvert(ex, expr, FLOATING, v, &tmp); + return tmp.data.constant.value; + case X2I: + xConvert(ex, expr, INTEGER, v, &tmp); + return tmp.data.constant.value; + case X2S: + xConvert(ex, expr, STRING, v, &tmp); + return tmp.data.constant.value; + case X2X: + xConvert(ex, expr, expr->type, v, &tmp); + return tmp.data.constant.value; + case XPRINT: + xPrint(ex, expr, v, &tmp); + return tmp.data.constant.value; + default: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if (x) { + rtmp = *x; + rtmp.data.constant.value = r; + rp = &rtmp; + } else + rp = 0; + if (!(*ex->disc->binaryf) (ex, &tmp, expr, rp, 0, ex->disc)) + return tmp.data.constant.value; + } + goto integer; + case UNSIGNED: + switch (expr->op) + { + case '<': + v.integer = (Sfulong_t)v.integer < (Sfulong_t)r.integer; + return v; + case LE: + v.integer = (Sfulong_t)v.integer <= (Sfulong_t)r.integer; + return v; + case GE: + v.integer = (Sfulong_t)v.integer >= (Sfulong_t)r.integer; + return v; + case '>': + v.integer = (Sfulong_t)v.integer > (Sfulong_t)r.integer; + return v; + } + /*FALLTHROUGH*/ + case INTEGER: + integer: + switch (expr->op) + { + case I2F: +#if _WIN32 + v.floating = v.integer; +#else + if (expr->type == UNSIGNED) + v.floating = (Sfulong_t)v.integer; + else + v.floating = v.integer; +#endif + return v; + case I2S: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if (expr->data.operand.left->op != DYNAMIC && expr->data.operand.left->op != ID) + { + if (expr->data.operand.left->type == UNSIGNED) + sfprintf(ex->tmp, "%I*u", sizeof(v.integer), v.integer); + else + sfprintf(ex->tmp, "%I*d", sizeof(v.integer), v.integer); + tmp.data.constant.value.string = exstash(ex->tmp, ex->ve); + } + else if ((*ex->disc->convertf)(ex, &tmp, STRING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) { + if (expr->data.operand.left->type == UNSIGNED) + sfprintf(ex->tmp, "%I*u", sizeof(v.integer), v.integer); + else + sfprintf(ex->tmp, "%I*d", sizeof(v.integer), v.integer); + tmp.data.constant.value.string = exstash(ex->tmp, ex->ve); + } + tmp.type = STRING; + return tmp.data.constant.value; + case I2X: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if ((*ex->disc->convertf)(ex, &tmp, expr->type, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) + exerror("%s: cannot convert integer value to external", tmp.data.variable.symbol->name); + tmp.type = expr->type; + return tmp.data.constant.value; + case '!': + v.integer = !v.integer; + return v; + case '~': + v.integer = ~v.integer; + return v; case '-': - v.integer -= r.integer; - break; - case '*': - v.integer *= r.integer; - break; - case '/': - if (r.integer == 0) - exerror("integer divide by 0"); - else - v.integer /= r.integer; - break; - case '%': - if (r.integer == 0) - exerror("integer 0 modulus"); - else - v.integer %= r.integer; - break; + if (x) + v.integer -= r.integer; + else + v.integer = -v.integer; + return v; + case '+': + v.integer += r.integer; + return v; case '&': - v.integer &= r.integer; - break; + v.integer &= r.integer; + return v; case '|': - v.integer |= r.integer; - break; + v.integer |= r.integer; + return v; case '^': - v.integer ^= r.integer; - break; + v.integer ^= r.integer; + return v; + case '*': + v.integer *= r.integer; + return v; + case '/': + if (r.integer == 0) + exerror("integer divide by 0"); + else + v.integer /= r.integer; + return v; + case '%': + if (r.integer == 0) + exerror("integer 0 modulus"); + else + v.integer %= r.integer; + return v; + case EQ: + v.integer = v.integer == r.integer; + return v; + case NE: + v.integer = v.integer != r.integer; + return v; case LS: - v.integer <<= r.integer; - break; +/* IBM compilers can't deal with these shift operators on long long. + * v.floating = (Sflong_t)v.floating << (Sflong_t)r.floating; + */ + { + Sflong_t op1, op2; + op1 = ((Sflong_t) v.floating); + op2 = ((Sflong_t) r.floating); + v.floating = (double) (op1 << op2); + } + return v; case RS: - v.integer = (Sfulong_t) v.integer >> r.integer; - break; - default: - goto huh; +/* IBM compilers can't deal with these shift operators on long long. + * v.integer = ((Sfulong_t)v.floating) >> (Sflong_t)r.floating; + */ + { + Sfulong_t op1; + Sflong_t op2; + op1 = ((Sfulong_t) v.floating); + op2 = ((Sflong_t) r.floating); + v.integer = (op1 >> op2); + } + return v; + case '<': + v.integer = v.integer < r.integer; + return v; + case LE: + v.integer = v.integer <= r.integer; + return v; + case GE: + v.integer = v.integer >= r.integer; + return v; + case '>': + v.integer = v.integer > r.integer; + return v; } break; - case STRING: - switch (expr->subop) { + case STRING: + switch (expr->op) + { + case S2B: + v.integer = *v.string != 0; + return v; + case S2F: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if ((*ex->disc->convertf)(ex, &tmp, FLOATING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) + { + tmp.data.constant.value.floating = strtod(v.string, &e); + if (*e) + tmp.data.constant.value.floating = *v.string != 0; + } + tmp.type = FLOATING; + return tmp.data.constant.value; + case S2I: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if ((*ex->disc->convertf)(ex, &tmp, INTEGER, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) + { + if (v.string) { + tmp.data.constant.value.integer = strToL(v.string, &e); + if (*e) + tmp.data.constant.value.integer = *v.string != 0; + } + else + tmp.data.constant.value.integer = 0; + } + tmp.type = INTEGER; + return tmp.data.constant.value; + case S2X: + tmp = *expr->data.operand.left; + tmp.data.constant.value = v; + if ((*ex->disc->convertf)(ex, &tmp, expr->type, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc)) + exerror("%s: cannot convert string value to external", tmp.data.variable.symbol->name); + tmp.type = expr->type; + return tmp.data.constant.value; + case EQ: + case NE: + v.integer = ((v.string && r.string) ? ((ex->disc->version >= 19981111L && ex->disc->matchf) ? (*ex->disc->matchf)(ex, expr->data.operand.left, v.string, expr->data.operand.right, r.string, env, ex->disc) : strmatch(v.string, r.string)) : (v.string == r.string)) == (expr->op == EQ); + return v; case '+': - v.string = str_add(ex, v.string, r.string); - break; + v.string = str_add(ex, v.string, r.string); + return v; case '|': - v.string = str_ior(ex, v.string, r.string); - break; + v.string = str_ior(ex, v.string, r.string); + return v; case '&': - v.string = str_and(ex, v.string, r.string); - break; + v.string = str_and(ex, v.string, r.string); + return v; case '^': - v.string = str_xor(ex, v.string, r.string); - break; + v.string = str_xor(ex, v.string, r.string); + return v; case '%': - v.string = str_mod(ex, v.string, r.string); - break; + v.string = str_mod(ex, v.string, r.string); + return v; case '*': - v.string = str_mpy(ex, v.string, r.string); - break; - default: - goto huh; + v.string = str_mpy(ex, v.string, r.string); + return v; } - break; - default: - goto huh; - } - } else if (x->op == DYNAMIC) - getdyn(ex, x, env, &assoc); - else - assoc = 0; - r = v; - goto set; - case ';': - case ',': - v = eval(ex, x, env); - while ((expr = expr->data.operand.right) - && (expr->op == ';' || expr->op == ',')) { - v = eval(ex, expr->data.operand.left, env); - if (ex->loopcount) - return v; - } - return expr ? eval(ex, expr, env) : v; - case '?': - v = eval(ex, x, env); - return v.integer ? eval(ex, - expr->data.operand.right->data.operand. - left, env) : eval(ex, - expr->data.operand. - right->data.operand. - right, env); - case AND: - v = eval(ex, x, env); - return v.integer ? eval(ex, expr->data.operand.right, env) : v; - case OR: - v = eval(ex, x, env); - return v.integer ? v : eval(ex, expr->data.operand.right, env); - } - v = eval(ex, x, env); - if ((x = expr->data.operand.right)) { - r = eval(ex, x, env); - if (!BUILTIN(x->type) && expr->binary) { - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - rtmp = *x; - rtmp.data.constant.value = r; - if (!(*ex->disc->binaryf) (ex, &tmp, expr, &rtmp, 0, ex->disc)) - return tmp.data.constant.value; - } - } - switch (expr->data.operand.left->type) { - case FLOATING: - switch (expr->op) { - case F2I: - v.integer = v.floating; - return v; - case F2S: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if (expr->data.operand.left->op != DYNAMIC - && expr->data.operand.left->op != ID) { - sfprintf(ex->tmp, "%g", v.floating); - tmp.data.constant.value.string = - vmstrdup(ex->ve, sfstruse(ex->tmp)); - } else - if ((*ex->disc->convertf) (ex, &tmp, STRING, - expr->data.operand. - right ? expr->data.operand. - right->data.variable. - symbol : (Exid_t *) 0, 0, - ex->disc)) { - sfprintf(ex->tmp, "%g", v.floating); - tmp.data.constant.value.string = - vmstrdup(ex->ve, sfstruse(ex->tmp)); - } - tmp.type = STRING; - return tmp.data.constant.value; - case F2X: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if ((*ex->disc->convertf) (ex, &tmp, expr->type, - expr->data.operand.right ? expr-> - data.operand.right->data.variable. - symbol : (Exid_t *) 0, 0, ex->disc)) - exerror("%s: cannot convert floating value to external", - tmp.data.variable.symbol->name); - tmp.type = expr->type; - return tmp.data.constant.value; - case '!': - v.floating = !((Sflong_t) v.floating); - return v; - case '~': - v.floating = ~((Sflong_t) v.floating); - return v; - case '-': - if (x) - v.floating -= r.floating; - else - v.floating = -v.floating; - return v; - case '+': - v.floating += r.floating; - return v; - case '&': - v.floating = (Sflong_t) v.floating & (Sflong_t) r.floating; - return v; - case '|': - v.floating = (Sflong_t) v.floating | (Sflong_t) r.floating; - return v; - case '^': - v.floating = (Sflong_t) v.floating ^ (Sflong_t) r.floating; - return v; - case '*': - v.floating *= r.floating; - return v; - case '/': - if (r.floating == 0.0) - exerror("floating divide by 0"); - else - v.floating /= r.floating; - return v; - case '%': - if ((r.integer = r.floating) == 0) - exerror("floating 0 modulus"); - else - v.floating = (Sflong_t) v.floating % r.integer; - return v; - case '<': - v.integer = v.floating < r.floating; - return v; - case LE: - v.integer = v.floating <= r.floating; - return v; - case EQ: - v.integer = v.floating == r.floating; - return v; - case NE: - v.integer = v.floating != r.floating; - return v; - case GE: - v.integer = v.floating >= r.floating; - return v; - case '>': - v.integer = v.floating > r.floating; - return v; - case LS: -/* IBM compilers can't deal with these shift operators on long long. - * v.floating = (Sflong_t)v.floating << (Sflong_t)r.floating; - */ - { - Sflong_t op1, op2; - op1 = ((Sflong_t) v.floating); - op2 = ((Sflong_t) r.floating); - v.floating = (double) (op1 << op2); - } - return v; - case RS: -/* IBM compilers can't deal with these shift operators on long long. - * v.integer = ((Sfulong_t)v.floating) >> (Sflong_t)r.floating; - */ - { - Sfulong_t op1; - Sflong_t op2; - op1 = ((Sfulong_t) v.floating); - op2 = ((Sflong_t) r.floating); - v.integer = (op1 >> op2); - } - return v; - } - break; - default: - switch (expr->op) { - case X2F: - xConvert(ex, expr, FLOATING, v, &tmp); - return tmp.data.constant.value; - case X2I: - xConvert(ex, expr, INTEGER, v, &tmp); - return tmp.data.constant.value; - case X2S: - xConvert(ex, expr, STRING, v, &tmp); - return tmp.data.constant.value; - case X2X: - xConvert(ex, expr, expr->type, v, &tmp); - return tmp.data.constant.value; - case XPRINT: - xPrint(ex, expr, v, &tmp); - return tmp.data.constant.value; - default: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if (x) { - rtmp = *x; - rtmp.data.constant.value = r; - rp = &rtmp; - } else - rp = 0; - if (!(*ex->disc->binaryf) (ex, &tmp, expr, rp, 0, ex->disc)) - return tmp.data.constant.value; - } - goto integer; - case UNSIGNED: - switch (expr->op) { - case '<': - v.integer = (Sfulong_t) v.integer < (Sfulong_t) r.integer; - return v; - case LE: - v.integer = (Sfulong_t) v.integer <= (Sfulong_t) r.integer; - return v; - case GE: - v.integer = (Sfulong_t) v.integer >= (Sfulong_t) r.integer; - return v; - case '>': - v.integer = (Sfulong_t) v.integer > (Sfulong_t) r.integer; - return v; - } - /*FALLTHROUGH*/ case INTEGER: - integer: - switch (expr->op) { - case I2F: -#if _WIN32 - v.floating = v.integer; -#else - if (expr->type == UNSIGNED) - v.floating = (Sfulong_t) v.integer; - else - v.floating = v.integer; -#endif - return v; - case I2S: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if (expr->data.operand.left->op != DYNAMIC - && expr->data.operand.left->op != ID) { - if (expr->data.operand.left->type == UNSIGNED) - sfprintf(ex->tmp, "%I*u", sizeof(v.integer), - v.integer); - else - sfprintf(ex->tmp, "%I*d", sizeof(v.integer), - v.integer); - tmp.data.constant.value.string = - vmstrdup(ex->ve, sfstruse(ex->tmp)); - } else - if ((*ex->disc->convertf) (ex, &tmp, STRING, - expr->data.operand. - right ? expr->data.operand. - right->data.variable. - symbol : (Exid_t *) 0, 0, - ex->disc)) { - if (expr->data.operand.left->type == UNSIGNED) - sfprintf(ex->tmp, "%I*u", sizeof(v.integer), - v.integer); - else - sfprintf(ex->tmp, "%I*d", sizeof(v.integer), - v.integer); - tmp.data.constant.value.string = - vmstrdup(ex->ve, sfstruse(ex->tmp)); - } - tmp.type = STRING; - return tmp.data.constant.value; - case I2X: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if ((*ex->disc->convertf) (ex, &tmp, expr->type, - expr->data.operand.right ? expr-> - data.operand.right->data.variable. - symbol : (Exid_t *) 0, 0, ex->disc)) - exerror("%s: cannot convert integer value to external", - tmp.data.variable.symbol->name); - tmp.type = expr->type; - return tmp.data.constant.value; - case '!': - v.integer = !v.integer; - return v; - case '~': - v.integer = ~v.integer; - return v; - case '-': - if (x) - v.integer -= r.integer; - else - v.integer = -v.integer; - return v; - case '+': - v.integer += r.integer; - return v; - case '&': - v.integer &= r.integer; - return v; - case '|': - v.integer |= r.integer; - return v; - case '^': - v.integer ^= r.integer; - return v; - case '*': - v.integer *= r.integer; - return v; - case '/': - if (r.integer == 0) - exerror("integer divide by 0"); - else - v.integer /= r.integer; - return v; - case '%': - if (r.integer == 0) - exerror("integer 0 modulus"); - else - v.integer %= r.integer; - return v; - case EQ: - v.integer = v.integer == r.integer; - return v; - case NE: - v.integer = v.integer != r.integer; - return v; - case LS: - v.integer = v.integer << r.integer; - return v; - case RS: - v.integer = ((Sfulong_t) v.integer) >> r.integer; - return v; - case '<': - v.integer = v.integer < r.integer; - return v; - case LE: - v.integer = v.integer <= r.integer; - return v; - case GE: - v.integer = v.integer >= r.integer; - return v; - case '>': - v.integer = v.integer > r.integer; - return v; - } - break; - case STRING: - switch (expr->op) { - case S2B: - v.integer = *v.string != 0; - return v; - case S2F: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if ((*ex->disc->convertf) (ex, &tmp, FLOATING, - expr->data.operand.right ? expr-> - data.operand.right->data.variable. - symbol : (Exid_t *) 0, 0, - ex->disc)) { - tmp.data.constant.value.floating = strtod(v.string, &e); - if (*e) - tmp.data.constant.value.floating = *v.string != 0; - } - tmp.type = FLOATING; - return tmp.data.constant.value; - case S2I: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if ((*ex->disc->convertf) (ex, &tmp, INTEGER, - expr->data.operand.right ? expr-> - data.operand.right->data.variable. - symbol : (Exid_t *) 0, 0, - ex->disc)) { - if (v.string) { - tmp.data.constant.value.integer = strToL(v.string, &e); - if (*e) - tmp.data.constant.value.integer = *v.string != 0; + v.integer = strcoll(v.string, r.string); + switch (expr->op) + { + case '<': + v.integer = v.integer < 0; + return v; + case LE: + v.integer = v.integer <= 0; + return v; + case GE: + v.integer = v.integer >= 0; + return v; + case '>': + v.integer = v.integer > 0; + return v; } - else - tmp.data.constant.value.integer = 0; - } - tmp.type = INTEGER; - return tmp.data.constant.value; - case S2X: - tmp = *expr->data.operand.left; - tmp.data.constant.value = v; - if ((*ex->disc->convertf) (ex, &tmp, expr->type, - expr->data.operand.right ? expr-> - data.operand.right->data.variable. - symbol : (Exid_t *) 0, 0, ex->disc)) - exerror("%s: cannot convert string value to external", - tmp.data.variable.symbol->name); - tmp.type = expr->type; - return tmp.data.constant.value; - case EQ: - case NE: - v.integer = - ((v.string - && r.string) ? ((ex->disc->version >= 19981111L - && ex->disc->matchf) ? (*ex->disc-> - matchf) (ex, - expr-> - data. - operand. - left, - v. - string, - expr-> - data. - operand. - right, - r. - string, - env, - ex-> - disc) : - strmatch(v.string, - r.string)) : (v.string == - r.string)) == - (expr->op == EQ); - return v; - case '+': - v.string = str_add(ex, v.string, r.string); - return v; - case '|': - v.string = str_ior(ex, v.string, r.string); - return v; - case '&': - v.string = str_and(ex, v.string, r.string); - return v; - case '^': - v.string = str_xor(ex, v.string, r.string); - return v; - case '%': - v.string = str_mod(ex, v.string, r.string); - return v; - case '*': - v.string = str_mpy(ex, v.string, r.string); - return v; - } - v.integer = strcoll(v.string, r.string); - switch (expr->op) { - case '<': - v.integer = v.integer < 0; - return v; - case LE: - v.integer = v.integer <= 0; - return v; - case GE: - v.integer = v.integer >= 0; - return v; - case '>': - v.integer = v.integer > 0; - return v; + goto huh; } - goto huh; - } - huh: - if (expr->binary) - exerror("operator %s %s %s not implemented", - lexname(expr->data.operand.left->type, -1), - lexname(expr->op, expr->subop), - expr->data.operand.right ? lexname(expr->data.operand. - right->type, - -1) : "UNARY"); - else - exerror("operator %s %s not implemented", - lexname(expr->op, expr->subop), - lexname(expr->data.operand.left->type, -1)); - return exzero(expr->type); + huh: + if (expr->binary) + exerror("operator %s %s %s not implemented", lexname(expr->data.operand.left->type, -1), lexname(expr->op, expr->subop), expr->data.operand.right ? lexname(expr->data.operand.right->type, -1) : "UNARY"); + else + exerror("operator %s %s not implemented", lexname(expr->op, expr->subop), lexname(expr->data.operand.left->type, -1)); + return exzero(expr->type); } /* * evaluate expression expr */ -Extype_t exeval(Expr_t * ex, Exnode_t * expr, void *env) +Extype_t +exeval(Expr_t* ex, Exnode_t* expr, void* env) { - Extype_t v; - - vmclear(ex->ve); - if (expr->compiled.integer) { - switch (expr->type) { - case FLOATING: - v.floating = (*expr->compiled.floating) (ex->disc->data); - break; - case STRING: - v.string = (*expr->compiled.string) (ex->disc->data); - break; - default: - v.integer = (*expr->compiled.integer) (ex->disc->data); - break; + Extype_t v; + + vmclear(ex->ve); + if (expr->compiled.integer) + { + switch (expr->type) + { + case FLOATING: + v.floating = (*expr->compiled.floating)(ex->disc->data); + break; + case STRING: + v.string = (*expr->compiled.string)(ex->disc->data); + break; + default: + v.integer = (*expr->compiled.integer)(ex->disc->data); + break; + } } - } else { - v = eval(ex, expr, env); - if (ex->loopcount > 0) { - ex->loopcount = 0; - if (ex->loopop == RETURN) - return ex->loopret; + else + { + v = eval(ex, expr, env); + if (ex->loopcount > 0) + { + ex->loopcount = 0; + if (ex->loopop == RETURN) + return ex->loopret; + } } - } - return v; + return v; } /* strToL: @@ -1993,7 +1921,7 @@ Sflong_t strToL(char *s, char **p) */ char *exstring(Expr_t * ex, char *s) { - return vmstrdup(ex->vc, s); + return vmstrdup(ex->ve, s); } /* exstralloc: @@ -2012,3 +1940,4 @@ int exstrfree(Expr_t * ex, void *p) { return vmfree(ex->ve, p); } + diff --git a/lib/expr/exexpr.c b/lib/expr/exexpr.c index 5faf2a1c3..ae7abd57e 100644 --- a/lib/expr/exexpr.c +++ b/lib/expr/exexpr.c @@ -1,5 +1,4 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -24,19 +23,21 @@ * return the expression for name or sym coerced to type */ -Exnode_t *exexpr(Expr_t * ex, const char *name, Exid_t * sym, int type) +Exnode_t* +exexpr(Expr_t* ex, const char* name, Exid_t* sym, int type) { - if (ex) { - if (!sym) - sym = name ? (Exid_t *) dtmatch(ex->symbols, name) : &ex->main; - if (sym && sym->lex == PROCEDURE && sym->value) { - if (type != DELETE_T) - return excast(ex, sym->value->data.procedure.body, type, - NiL, 0); - exfreenode(ex, sym->value); - sym->lex = NAME; - sym->value = 0; + if (ex) + { + if (!sym) + sym = name ? (Exid_t*)dtmatch(ex->symbols, name) : &ex->main; + if (sym && sym->lex == PROCEDURE && sym->value) + { + if (type != DELETE_T) + return excast(ex, sym->value->data.procedure.body, type, NiL, 0); + exfreenode(ex, sym->value); + sym->lex = NAME; + sym->value = 0; + } } - } - return 0; + return 0; } diff --git a/lib/expr/exgram.h b/lib/expr/exgram.h index 018e19e05..9de314082 100644 --- a/lib/expr/exgram.h +++ b/lib/expr/exgram.h @@ -1,5 +1,5 @@ /* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -23,7 +23,7 @@ extern "C" { * sometimes free stuff can cost a lot */ -#if defined(MINTOKEN) && !defined(_EXGRAM_H) +#if !defined(_EXGRAM_H) && ( defined(MINTOKEN) || defined(YYTOKENTYPE) ) #define _EXGRAM_H #if !defined(_EXPARSE_H) @@ -38,26 +38,27 @@ extern "C" { #define ALLOCATE(p,x) (x*)exalloc(p,sizeof(x)) #define QUALIFY(r,s) ((r)&&(expr.program->disc->flags&EX_QUALIFY)?qualify(r,s):(s)) - static int a2t[] = { 0, FLOATING, INTEGER, STRING }; - static Switch_t swstate; +static int a2t[] = { 0, FLOATING, INTEGER, STRING }; +static Switch_t swstate; - Exstate_t expr; +Exstate_t expr; - static int - T(int t) { +static int T(int t) +{ if (expr.program->disc->types) return expr.program->disc->types[t & TMASK]; else return a2t[t & TMASK]; - } +} /* * allocate and initialize a new expression node in the current program */ - Exnode_t *exnewnode(Expr_t * p, int op, int binary, int type, - Exnode_t * left, Exnode_t * right) { - register Exnode_t *x; +Exnode_t* +exnewnode(Expr_t* p, int op, int binary, int type, Exnode_t* left, Exnode_t* right) +{ + register Exnode_t* x; x = ALLOCATE(p, Exnode_t); x->op = op; @@ -68,111 +69,117 @@ extern "C" { x->data.operand.left = left; x->data.operand.right = right; return x; - } +} /* * free node x and its children */ - void - exfreenode(Expr_t * p, register Exnode_t * x) { - register Print_t *pr; - register Exref_t *r; - Print_t *pn; - Exref_t *rn; - int i; - - switch (x->op) { +void +exfreenode(Expr_t* p, register Exnode_t* x) +{ + register Print_t* pr; + register Exref_t* r; + Print_t* pn; + Exref_t* rn; + int i; + + switch (x->op) + { case CALL: - if (x->data.call.args) - exfreenode(p, x->data.call.args); - break; + if (x->data.call.args) + exfreenode(p, x->data.call.args); + break; case CONSTANT: - break; + break; case DEFAULT: - if (x->data.select.next) - exfreenode(p, x->data.select.next); - break; + if (x->data.select.next) + exfreenode(p, x->data.select.next); + break; case DYNAMIC: - if (x->data.variable.index) - exfreenode(p, x->data.variable.index); - if (x->data.variable.symbol->local.pointer) { - dtclose((Dt_t *) x->data.variable.symbol->local.pointer); - x->data.variable.symbol->local.pointer = 0; - } - break; + if (x->data.variable.index) + exfreenode(p, x->data.variable.index); + if (x->data.variable.symbol->local.pointer) + { + dtclose((Dt_t*)x->data.variable.symbol->local.pointer); + x->data.variable.symbol->local.pointer = 0; + } + break; case '#': - if (x->data.variable.symbol->local.pointer) { - dtclose((Dt_t *) x->data.variable.symbol->local.pointer); - x->data.variable.symbol->local.pointer = 0; - } - break; - case IN_OP: + if (x->data.variable.symbol->local.pointer) { + dtclose((Dt_t *) x->data.variable.symbol->local.pointer); + x->data.variable.symbol->local.pointer = 0; + } + break; +// case IN_OP: case UNSET: - if (x->data.variable.index) - exfreenode(p, x->data.variable.index); - if (x->data.variable.symbol->local.pointer) { - dtclose((Dt_t *) x->data.variable.symbol->local.pointer); - x->data.variable.symbol->local.pointer = 0; - } - break; + if (x->data.variable.index) + exfreenode(p, x->data.variable.index); + if (x->data.variable.symbol->local.pointer) { + dtclose((Dt_t *) x->data.variable.symbol->local.pointer); + x->data.variable.symbol->local.pointer = 0; + } + break; case ITERATE: case ITERATER: - if (x->data.generate.statement) - exfreenode(p, x->data.generate.statement); - break; + if (x->data.generate.statement) + exfreenode(p, x->data.generate.statement); + break; case ID: - rn = x->data.variable.reference; - while ((r = rn)) { - rn = r->next; - vmfree(p->vm, r); - } - if (x->data.variable.index) - break; + rn = x->data.variable.reference; + while ((r = rn)) + { + rn = r->next; + vmfree(p->vm, r); + } + if (x->data.variable.index) + exfreenode(p, x->data.variable.index); + break; case GSUB: case SUB: case SUBSTR: - exfreenode(p, x->data.string.base); - exfreenode(p, x->data.string.pat); - if (x->data.string.repl) - exfreenode(p, x->data.string.repl); - break; + exfreenode(p, x->data.string.base); + exfreenode(p, x->data.string.pat); + if (x->data.string.repl) + exfreenode(p, x->data.string.repl); + break; case TOKENS: case SPLIT: - if (x->data.split.seps) - exfreenode(p, x->data.split.seps); - exfreenode(p, x->data.split.string); - if (x->data.split.array->local.pointer) { - dtclose((Dt_t *) x->data.split.array->local.pointer); - x->data.split.array->local.pointer = 0; - } - break; + if (x->data.split.seps) + exfreenode(p, x->data.split.seps); + exfreenode(p, x->data.split.string); + if (x->data.split.array->local.pointer) { + dtclose((Dt_t *) x->data.split.array->local.pointer); + x->data.split.array->local.pointer = 0; + } + break; case PRINT: - exfreenode(p, x->data.operand.left); - break; + exfreenode(p, x->data.operand.left); + break; case PRINTF: case SPRINTF: - if (x->data.print.descriptor) - exfreenode(p, x->data.print.descriptor); - pn = x->data.print.args; - while ((pr = pn)) { - for (i = 0; i < elementsof(pr->param) && pr->param[i]; i++) - exfreenode(p, pr->param[i]); - if (pr->arg) - exfreenode(p, pr->arg); - pn = pr->next; - vmfree(p->vm, pr); - } - break; + if (x->data.print.descriptor) + exfreenode(p, x->data.print.descriptor); + pn = x->data.print.args; + while ((pr = pn)) + { + for (i = 0; i < elementsof(pr->param) && pr->param[i]; i++) + exfreenode(p, pr->param[i]); + if (pr->arg) + exfreenode(p, pr->arg); + pn = pr->next; + vmfree(p->vm, pr); + } + break; default: - if (x->data.operand.left) - exfreenode(p, x->data.operand.left); - if (x->data.operand.right) - exfreenode(p, x->data.operand.right); - break; + if (x->data.operand.left) + exfreenode(p, x->data.operand.left); + if (x->data.operand.right) + exfreenode(p, x->data.operand.right); + break; } vmfree(p->vm, x); - } +} /* extract: * Given an argument list, extract first argument, @@ -180,7 +187,7 @@ extern "C" { * return first argument. * Return 0 on failure. */ - static Exnode_t *extract(Expr_t * p, Exnode_t ** argp, int type) { +static Exnode_t *extract(Expr_t * p, Exnode_t ** argp, int type) { Exnode_t *args = *argp; Exnode_t *left; @@ -191,13 +198,13 @@ extern "C" { args->data.operand.left = args->data.operand.right = 0; exfreenode(p, args); return left; - } +} /* exnewsplit: * Generate split/tokens node. * Fifth argument is optional. */ - static Exnode_t *exnewsplit(Expr_t * p, int op, Exid_t* dyn, Exnode_t * s, Exnode_t* seps) { +static Exnode_t *exnewsplit(Expr_t * p, int op, Exid_t* dyn, Exnode_t * s, Exnode_t* seps) { Exnode_t *ss = 0; if (dyn->local.pointer == 0) @@ -219,13 +226,13 @@ extern "C" { ss->data.split.string = s; ss->data.split.seps = seps; return ss; - } +} /* exnewsub: * Generate sub node. * Third argument is optional. */ - static Exnode_t *exnewsub(Expr_t * p, Exnode_t * args, int op) { +static Exnode_t *exnewsub(Expr_t * p, Exnode_t * args, int op) { Exnode_t *base; Exnode_t *pat; Exnode_t *repl; @@ -250,12 +257,12 @@ extern "C" { ss->data.string.pat = pat; ss->data.string.repl = repl; return ss; - } +} /* exnewsubstr: * Generate substr node. */ - static Exnode_t *exnewsubstr(Expr_t * p, Exnode_t * args) { +static Exnode_t *exnewsubstr(Expr_t * p, Exnode_t * args) { Exnode_t *base; Exnode_t *pat; Exnode_t *repl; @@ -280,13 +287,13 @@ extern "C" { ss->data.string.pat = pat; ss->data.string.repl = repl; return ss; - } +} /* exstringOf: * Cast x to type STRING * Assume x->type != STRING */ - static Exnode_t *exstringOf(Expr_t * p, register Exnode_t * x) { +static Exnode_t *exstringOf(Expr_t * p, register Exnode_t * x) { int type = x->type; int cvt = 0; @@ -337,12 +344,12 @@ extern "C" { } x->type = STRING; return x; - } +} /* exprint: * Generate argument list of strings. */ - static Exnode_t *exprint(Expr_t * p, Exid_t * ex, Exnode_t * args) { +static Exnode_t *exprint(Expr_t * p, Exid_t * ex, Exnode_t * args) { Exnode_t *arg = args; Exnode_t *pr; @@ -354,7 +361,7 @@ extern "C" { } pr = exnewnode(p, ex->index, 1, ex->type, args, NiL); return pr; - } +} /* makeVar: * @@ -364,7 +371,7 @@ extern "C" { * and the prefix gets stored in refs. (This format is used to simplify * the yacc parser.) */ - static Exnode_t *makeVar(Expr_t * prog, Exid_t * s, Exnode_t * idx, +static Exnode_t *makeVar(Expr_t * prog, Exid_t * s, Exnode_t * idx, Exnode_t * dyna, Exref_t * refs) { Exnode_t *nn; int kind; @@ -400,24 +407,26 @@ extern "C" { NiL, EX_SCALAR, prog->disc); return nn; - } +} /* * cast x to type */ - static char *typename[] = { +static char* typename[] = +{ "external", "integer", "unsigned", "char", "float", "string" - }; - - static int typecast[6][6] = { - {X2X, X2I, X2I, X2I, X2F, X2S}, - {I2X, 0, 0, 0, I2F, I2S}, - {I2X, 0, 0, 0, I2F, I2S}, - {I2X, 0, 0, 0, I2F, I2S}, - {F2X, F2I, F2I, F2I, 0, F2S}, - {S2X, S2I, S2I, S2I, S2F, 0} - }; +}; + +static int typecast[6][6] = +{ + {X2X, X2I, X2I, X2I, X2F, X2S}, + {I2X, 0, 0, 0, I2F, I2S}, + {I2X, 0, 0, 0, I2F, I2S}, + {I2X, 0, 0, 0, I2F, I2S}, + {F2X, F2I, F2I, F2I, 0, F2S}, + {S2X, S2I, S2I, S2I, S2F, 0}, +}; #define TYPEINDEX(t) (((t)>=INTEGER&&(t)<=STRING)?((t)-INTEGER+1):0) #define TYPENAME(t) typename[TYPEINDEX(t)] @@ -425,64 +434,64 @@ extern "C" { #define EXTERNAL(t) ((t)>=F2X) - char *extypename(Expr_t * p, int type) { +char *extypename(Expr_t * p, int type) { if (BUILTIN(type)) return TYPENAME(type); return (p->disc->typename) (p, type); - } +} /* exnoncast: * Return first non-cast node. */ - Exnode_t *exnoncast(register Exnode_t * x) { +Exnode_t *exnoncast(register Exnode_t * x) { while (x && (x->op >= F2I) && (x->op <= X2X)) x = x->data.operand.left; return x; - } - - Exnode_t *excast(Expr_t * p, register Exnode_t * x, register int type, - register Exnode_t * xref, int arg) { - register int t2t; - char *s; - char *e; +} - if (x && x->type != type && type && type != VOIDTYPE) { - if (!x->type) { - x->type = type; - return x; - } - if (!(t2t = TYPECAST(x->type, type))) - return x; - if (EXTERNAL(t2t) && !p->disc->convertf) - exerror("cannot convert %s to %s", extypename(p, x->type), - extypename(p, type)); - if (x->op != CONSTANT) { - Exid_t *sym = (xref ? xref->data.variable.symbol : NiL); - if (EXTERNAL(t2t)) { - int a = (arg ? arg : 1); - if ((*p->disc->convertf) (p, x, type, sym, a, - p->disc) < 0) { - if (xref) { - if ((sym->lex == FUNCTION) && arg) - exerror - ("%s: cannot use value of type %s as argument %d in function %s", - sym->name, extypename(p, x->type), - arg, sym->name); - else - exerror("%s: cannot convert %s to %s", - xref->data.variable.symbol->name, - extypename(p, x->type), - extypename(p, type)); - } else { - exerror("cannot convert %s to %s", - extypename(p, x->type), extypename(p, - type)); +Exnode_t* +excast(Expr_t* p, register Exnode_t* x, register int type, register Exnode_t* xref, int arg) +{ + register int t2t; + char* s; + char* e; + + if (x && x->type != type && type && type != VOIDTYPE) + { + if (!x->type) + { + x->type = type; + return x; + } + if (!(t2t = TYPECAST(x->type, type))) + return x; + if (EXTERNAL(t2t) && !p->disc->convertf) + exerror("cannot convert %s to %s", extypename(p, x->type), extypename(p, type)); + if (x->op != CONSTANT) { + Exid_t *sym = (xref ? xref->data.variable.symbol : NiL); + if (EXTERNAL(t2t)) { + int a = (arg ? arg : 1); + if ((*p->disc->convertf) (p, x, type, sym, a, p->disc) < 0) { + if (xref) { + if ((sym->lex == FUNCTION) && arg) + exerror ("%s: cannot use value of type %s as argument %d in function %s", + sym->name, extypename(p, x->type), + arg, sym->name); + else + exerror("%s: cannot convert %s to %s", + xref->data.variable.symbol->name, + extypename(p, x->type), + extypename(p, type)); + } else { + exerror("cannot convert %s to %s", + extypename(p, x->type), extypename(p, type)); + } + } } - } + x = exnewnode(p, t2t, 0, type, x, xref); } - x = exnewnode(p, t2t, 0, type, x, xref); - } else - switch (t2t) { + else switch (t2t) + { case F2X: case I2X: case S2X: @@ -490,99 +499,164 @@ extern "C" { case X2I: case X2S: case X2X: - if (xref && xref->op == ID) { - if ((*p->disc->convertf) (p, x, type, - xref->data.variable. - symbol, 0, p->disc) < 0) - exerror("%s: cannot cast constant %s to %s", - xref->data.variable.symbol->name, - extypename(p, x->type), extypename(p, - type)); - } else - if ((*p->disc->convertf) (p, x, type, NiL, 0, - p->disc) < 0) - exerror("cannot cast constant %s to %s", - extypename(p, x->type), extypename(p, - type)); - break; + if (xref && xref->op == ID) + { + if ((*p->disc->convertf)(p, x, type, xref->data.variable.symbol, arg, p->disc) < 0) + exerror("%s: cannot cast constant %s to %s", xref->data.variable.symbol->name, extypename(p, x->type), extypename(p, type)); + } + else if ((*p->disc->convertf)(p, x, type, NiL, arg, p->disc) < 0) + exerror("cannot cast constant %s to %s", extypename(p, x->type), extypename(p, type)); + break; case F2I: - x->data.constant.value.integer = - x->data.constant.value.floating; - break; + x->data.constant.value.integer = x->data.constant.value.floating; + break; case F2S: - sfprintf(p->tmp, "%g", - x->data.constant.value.floating); - x->data.constant.value.string = - vmstrdup(p->vm, sfstruse(p->tmp)); - break; + sfprintf(p->tmp, "%g", x->data.constant.value.floating); + x->data.constant.value.string = exstash(p->tmp, p->vm); + break; case I2F: - x->data.constant.value.floating = - x->data.constant.value.integer; - break; + x->data.constant.value.floating = x->data.constant.value.integer; + break; case I2S: - sfprintf(p->tmp, "%I*d", - sizeof(x->data.constant.value.integer), - x->data.constant.value.integer); - x->data.constant.value.string = - vmstrdup(p->vm, sfstruse(p->tmp)); - break; + sfprintf(p->tmp, "%I*d", sizeof(x->data.constant.value.integer), x->data.constant.value.integer); + x->data.constant.value.string = exstash(p->tmp, p->vm); + break; case S2F: - s = x->data.constant.value.string; - x->data.constant.value.floating = strtod (s, &e); - if (*e) - x->data.constant.value.floating = (*s != 0); - break; + s = x->data.constant.value.string; + x->data.constant.value.integer = strtod(s, &e); + if (*e) + x->data.constant.value.floating = (*s != 0); + break; case S2I: - s = x->data.constant.value.string; - x->data.constant.value.integer = strToL(s, &e); - if (*e) - x->data.constant.value.integer = (*s != 0); - break; + s = x->data.constant.value.string; + x->data.constant.value.integer = strToL(s, &e); + if (*e) + x->data.constant.value.integer = (*s != 0); + break; default: - exerror("internal error: %d: unknown cast op", t2t); - break; + exerror("internal error: %d: unknown cast op", t2t); + break; } - x->type = type; + x->type = type; } return x; - } +} + +#if 0 + +/* + * convert value v from type from to type to + * string data placed in buf + */ + +Extype_t +exconvert(Expr_t* p, Extype_t v, int from, int to, char* buf, size_t size) +{ + register int t2t; + int n; + Exnode_t tmp; + + if (from && (t2t = TYPECAST(from, to))) + { + if (EXTERNAL(t2t) && !p->disc->convertf) + exerror("cannot cast %s to %s", TYPENAME(from), TYPENAME(to)); + switch (t2t) + { + case F2X: + case I2X: + case S2X: + case X2F: + case X2I: + case X2S: + tmp.type = from; + tmp.name = "*INTERNAL*"; + tmp.data.constant.value = v; + if ((*p->disc->convertf)(p, &tmp, to, NiL, -1, p->disc) < 0) + exerror("cannot convert %s to %s", TYPENAME(from), TYPENAME(to)); + if (t2t == X2S) + { + n = strlen(tmp.data.constant.value.string); + if (n >= size) + n = size - 1; + memcpy(buf, tmp.data.constant.value.string, n); + buf[n] = 0; + vmfree(p->vm, tmp.data.constant.value.string); + tmp.data.constant.value.string = buf; + } + return tmp.data.constant.value; + case F2I: + v.integer = (type == UNSIGNED) ? (Sfulong_t)v.floating : v.floating; + break; + case F2S: + sfsprintf(buf, size, "%g", v.floating); + v.string = buf; + break; + case I2F: + v.floating = (from == UNSIGNED) ? (Sfulong_t)v.integer : v.integer; + break; + case I2S: + sfsprintf(buf, size, "%I*d", sizeof(v.integer), v.integer); + v.string = buf; + break; + case S2F: + v.floating = *v.string != 0; + break; + case S2I: + v.integer = *v.string != 0; + break; + default: + exerror("internal error: %d: unknown conversion op", t2t); + break; + } + } + return v; +} + +#endif /* * force ref . sym qualification */ - static Exid_t *qualify(register Exref_t * ref, register Exid_t * sym) { - register Exid_t *x; - char *s; +static Exid_t* +qualify(register Exref_t* ref, register Exid_t* sym) +{ + register Exid_t* x; + char* s; while (ref->next) - ref = ref->next; + ref = ref->next; sfprintf(expr.program->tmp, "%s.%s", ref->symbol->name, sym->name); - s = sfstruse(expr.program->tmp); - if (!(x = (Exid_t *) dtmatch(expr.program->symbols, s))) { - if ((x = newof(0, Exid_t, 1, strlen(s) - EX_NAMELEN + 1))) { - memcpy(x, sym, sizeof(Exid_t) - EX_NAMELEN); - strcpy(x->name, s); - dtinsert(expr.program->symbols, x); - } else { - exerror("out of space [qualify]"); - x = sym; - } + s = exstash(expr.program->tmp, NiL); + if (!(x = (Exid_t*)dtmatch(expr.program->symbols, s))) + { + if ((x = newof(0, Exid_t, 1, strlen(s) - EX_NAMELEN + 1))) + { + memcpy(x, sym, sizeof(Exid_t) - EX_NAMELEN); + strcpy(x->name, s); + dtinsert(expr.program->symbols, x); + } + else + { + exnospace(); + x = sym; + } } return x; - } +} /* * check function call arg types and count * return function identifier node */ - Exnode_t *call(Exref_t * ref, register Exid_t * fun, - register Exnode_t * args) { - register int t; - register int type; - Exnode_t *x; - int num; +static Exnode_t* +call(Exref_t* ref, register Exid_t* fun, register Exnode_t* args) +{ + register int t; + register int type; + Exnode_t* x; + int num; x = exnewnode(expr.program, ID, 0, 0, NiL, NiL); t = fun->type; @@ -590,425 +664,430 @@ extern "C" { x->data.variable.reference = ref; num = 0; N(t); - while ((type = T(t))) { - if (!args) { - exerror("%s: not enough args", fun->name); - return args; - } - num++; - if (type != args->data.operand.left->type) - args->data.operand.left = - excast(expr.program, args->data.operand.left, type, NiL, - num); - args = args->data.operand.right; - N(t); + while ((type = T(t))) + { + if (!args) + { + exerror("%s: not enough args", fun->name); + return args; + } + num++; + if (type != args->data.operand.left->type) + args->data.operand.left = excast(expr.program, args->data.operand.left, type, NiL, num); + args = args->data.operand.right; + N(t); } if (args) - exerror("%s: too many args", fun->name); + exerror("%s: too many args", fun->name); return x; - } +} /* * precompile a printf/scanf call */ - static Print_t *preprint(register Exnode_t * args) { - register Print_t *x; - register char *s; - register int c; - int t; - int i; - int n; - char *e; - char *f; - Print_t *p = 0; - Print_t *q; +static Print_t* +preprint(register Exnode_t* args) +{ + register Print_t* x; + register char* s; + register int c; + int t; + int i; + int n; + char* e; + char* f; + Print_t* p = 0; + Print_t* q; if (!args || args->data.operand.left->type != STRING) - exerror("format string argument expected"); - if (args->data.operand.left->op != CONSTANT) { - x = ALLOCATE(expr.program, Print_t); - memzero(x, sizeof(*x)); - x->arg = args; - return x; + exerror("format string argument expected"); + if (args->data.operand.left->op != CONSTANT) + { + x = ALLOCATE(expr.program, Print_t); + memzero(x, sizeof(*x)); + x->arg = args; + return x; } f = args->data.operand.left->data.constant.value.string; args = args->data.operand.right; - for (s = f; *s; s++) { - sfputc(expr.program->tmp, *s); - if (*s == '%') { - if (!*++s) - exerror("%s: trailing %% in format", f); - if (*s != '%') - break; - if (args) - sfputc(expr.program->tmp, '%'); - } + for (s = f; *s; s++) + { + sfputc(expr.program->tmp, *s); + if (*s == '%') + { + if (!*++s) + exerror("%s: trailing %% in format", f); + if (*s != '%') + break; + if (args) + sfputc(expr.program->tmp, '%'); + } } x = 0; - for (;;) { - q = ALLOCATE(expr.program, Print_t); - if (x) - x->next = q; - else - p = q; - x = q; - memzero(x, sizeof(*x)); - if (*s) { - i = 0; - t = INTEGER; - for (;;) { - switch (c = *s++) { - case 0: - exerror("unterminated %%... in format"); - goto done; - case '*': - if (i >= elementsof(x->param)) { - *s = 0; - exerror("format %s has too many * arguments", - f); - goto done; - } - if (!args) { - *s = 0; - exerror("format %s * argument expected", f); - goto done; + for (;;) + { + q = ALLOCATE(expr.program, Print_t); + if (x) + x->next = q; + else + p = q; + x = q; + memzero(x, sizeof(*x)); + if (*s) + { + i = 0; + t = INTEGER; + for (;;) + { + switch (c = *s++) + { + case 0: + exerror("unterminated %%... in format"); + goto done; + case '*': + if (i >= elementsof(x->param)) + { + *s = 0; + exerror("format %s has too many * arguments", f); + goto done; + } + if (!args) + { + *s = 0; + exerror("format %s * argument expected", f); + goto done; + } + x->param[i++] = args->data.operand.left; + args = args->data.operand.right; + break; + case '(': + n = 1; + for (;;) + { + sfputc(expr.program->tmp, c); + switch (c = *s++) + { + case 0: + s--; + break; + case '(': + n++; + continue; + case ')': + if (--n <= 0) + break; + continue; + default: + continue; + } + break; + } + break; + case 'c': + case 'd': + goto specified; + case 'e': + case 'f': + case 'g': + t = FLOATING; + goto specified; + case 'h': + exerror("short formats not supported"); + goto done; + case 'l': + t = INTEGER; + break; + case 'o': + case 'u': + case 'x': + case 'T': + t = UNSIGNED; + goto specified; + case 's': + case 'S': + t = STRING; + goto specified; + default: + if (isalpha(c)) + goto specified; + break; + } + sfputc(expr.program->tmp, c); } - x->param[i++] = args->data.operand.left; - args = args->data.operand.right; - break; - case '(': - n = 1; - for (;;) { - sfputc(expr.program->tmp, c); - switch (c = *s++) { - case 0: - s--; - break; - case '(': - n++; - continue; - case ')': - if (--n <= 0) - break; - continue; - default: - continue; - } - break; + specified: + sfputc(expr.program->tmp, c); + for (e = s; *s; s++) + { + if (*s == '%') + { + if (!*++s) + { + *e = 0; + exerror("%s: trailing %% in format", f); + goto done; + } + if (*s != '%') + { + s--; + break; + } + } + sfputc(expr.program->tmp, *s); } - break; - case 'c': - case 'd': - goto specified; - case 'e': - case 'f': - case 'g': - t = FLOATING; - goto specified; - case 'h': - exerror("short formats not supported"); - goto done; - case 'l': - t = INTEGER; - break; - case 'o': - case 'u': - case 'x': - case 'T': - t = UNSIGNED; - goto specified; - case 's': - case 'S': - t = STRING; - goto specified; - default: - if (isalpha(c)) - goto specified; - break; - } - sfputc(expr.program->tmp, c); - } - specified: - sfputc(expr.program->tmp, c); - for (e = s; *s; s++) { - if (*s == '%') { - if (!*++s) { - *e = 0; - exerror("%s: trailing %% in format", f); - goto done; + if (!args) + { + *e = 0; + exerror("%s format argument expected", f); + goto done; } - if (*s != '%') { - s--; - break; + x->arg = args->data.operand.left; + switch (t) + { + case FLOATING: + if (x->arg->type != FLOATING) + x->arg = exnewnode(expr.program, x->arg->type == STRING ? S2F : INTEGRAL(x->arg->type) ? I2F : X2F, 0, FLOATING, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0); + break; + case INTEGER: + case UNSIGNED: + if (!INTEGRAL(x->arg->type)) + x->arg = exnewnode(expr.program, x->arg->type == STRING ? S2I : x->arg->type == FLOATING ? F2I : X2I, 0, INTEGER, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0); + x->arg->type = t; + break; + case STRING: + if (x->arg->type != STRING) + { + if (x->arg->op == CONSTANT && x->arg->data.constant.reference && expr.program->disc->convertf) + { + if ((*expr.program->disc->convertf)(expr.program, x->arg, STRING, x->arg->data.constant.reference, 0, expr.program->disc) < 0) + exerror("cannot convert string format argument"); + else x->arg->data.constant.value.string = vmstrdup(expr.program->vm, x->arg->data.constant.value.string); + } + else if (!expr.program->disc->convertf || (x->arg->op != ID && x->arg->op != DYNAMIC && x->arg->op != F2X && x->arg->op != I2X && x->arg->op != S2X)) + exerror("string format argument expected"); + else + x->arg = exnewnode(expr.program, x->arg->type == FLOATING ? F2S : INTEGRAL(x->arg->type) ? I2S : X2S, 0, STRING, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0); + } + break; } - } - sfputc(expr.program->tmp, *s); - } - if (!args) { - *e = 0; - exerror("%s format argument expected", f); - goto done; - } - x->arg = args->data.operand.left; - switch (t) { - case FLOATING: - if (x->arg->type != FLOATING) - x->arg = - exnewnode(expr.program, - x->arg->type == - STRING ? S2F : INTEGRAL(x->arg-> - type) ? I2F : - X2F, 0, FLOATING, x->arg, - x->arg->op == - ID ? x->arg : (Exnode_t *) 0); - break; - case INTEGER: - case UNSIGNED: - if (!INTEGRAL(x->arg->type)) - x->arg = - exnewnode(expr.program, - x->arg->type == - STRING ? S2I : x->arg->type == - FLOATING ? F2I : X2I, 0, INTEGER, - x->arg, - x->arg->op == - ID ? x->arg : (Exnode_t *) 0); - x->arg->type = t; - break; - case STRING: - if (x->arg->type != STRING) { - if (x->arg->op == CONSTANT - && x->arg->data.constant.reference - && expr.program->disc->convertf) { - if ((*expr.program->disc->convertf) (expr. - program, - x->arg, - STRING, - x->arg-> - data. - constant. - reference, - 0, - expr. - program-> - disc) < 0) - exerror - ("cannot convert string format argument"); - else - x->arg->data.constant.value.string = - vmstrdup(expr.program->vm, - x->arg->data.constant.value. - string); - } else if (!expr.program->disc->convertf - || (x->arg->op != ID - && x->arg->op != DYNAMIC - && x->arg->op != F2X - && x->arg->op != I2X - && x->arg->op != S2X)) - exerror("string format argument expected"); - else - x->arg = - exnewnode(expr.program, - x->arg->type == - FLOATING ? F2S : INTEGRAL(x-> - arg-> - type) ? - I2S : X2S, 0, STRING, x->arg, - x->arg->op == - ID ? x->arg : (Exnode_t *) 0); - } - break; + args = args->data.operand.right; } - args = args->data.operand.right; - } - x->format = - vmstrdup(expr.program->vm, sfstruse(expr.program->tmp)); - if (!*s) - break; - f = s; + x->format = exstash(expr.program->tmp, expr.program->vm); + if (!*s) + break; + f = s; } if (args) - exerror("too many format arguments"); - done: - sfstrset(expr.program->tmp, 0); + exerror("too many format arguments"); + done: + sfstrseek(expr.program->tmp, 0, SEEK_SET); return p; - } +} /* * push a new input stream and program */ - int - expush(Expr_t * p, const char *name, int line, const char *sp, - Sfio_t * fp) { - register Exinput_t *in; - register char *s; - char buf[PATH_MAX]; +int +expush(Expr_t* p, const char* name, int line, const char* sp, Sfio_t* fp) +{ + register Exinput_t* in; + register char* s; + char buf[PATH_MAX]; - if (!(in = newof(0, Exinput_t, 1, 0))) { - exerror("out of space [push]"); - return -1; + if (!(in = newof(0, Exinput_t, 1, 0))) + { + exnospace(); + return -1; } if (!p->input) - p->input = &expr.null; - if (!(in->bp = in->sp = (char *) sp)) { - if ((in->fp = fp)) - in->close = 0; - else if (name) { - if (! - (s = - pathfind(name, p->disc->lib, p->disc->type, buf, - sizeof(buf))) - || !(in->fp = sfopen(NiL, s, "r"))) { - exerror("%s: file not found", name); - in->bp = in->sp = ""; - } else { - name = (const char *) vmstrdup(p->vm, s); - in->close = 1; + p->input = &expr.null; + if (!(in->bp = in->sp = (char*)sp)) + { + if ((in->fp = fp)) + in->close = 0; + else if (name) + { + if (!(s = pathfind(name, p->disc->lib, p->disc->type, buf, sizeof(buf))) || !(in->fp = sfopen(NiL, s, "r"))) + { + exerror("%s: file not found", name); + in->bp = in->sp = ""; + } + else + { + name = (const char*)vmstrdup(p->vm, s); + in->close = 1; + } } - } - } else - in->fp = 0; - if (!(in->next = p->input)->next) { - p->errors = 0; - if (!(p->disc->flags & EX_INTERACTIVE)) { - if (line >= 0) - error_info.line = line; - } else if (!error_info.line) - error_info.line = 1; - } else if (line >= 0) - error_info.line = line; + } + else in->fp = 0; + if (!(in->next = p->input)->next) + { + p->errors = 0; + if (!(p->disc->flags & EX_INTERACTIVE)) + { + if (line >= 0) + error_info.line = line; + } + else if (!error_info.line) + error_info.line = 1; + } + else if (line >= 0) + error_info.line = line; setcontext(p); p->eof = 0; p->input = in; in->file = error_info.file; if (line >= 0) - error_info.file = (char *) name; + error_info.file = (char*)name; in->line = error_info.line; in->nesting = 0; in->unit = !name && !line; p->program = expr.program; expr.program = p; return 0; - } +} /* * pop the current input stream */ - int - expop(register Expr_t * p) { - register int c; - register Exinput_t *in; +int +expop(register Expr_t* p) +{ + register int c; + register Exinput_t* in; if (!(in = p->input) || !in->next || in->unit) - return -1; + return -1; if (in->nesting) - exerror("unbalanced quote or nesting construct"); + exerror("unbalanced quote or nesting construct"); error_info.file = in->file; if (in->next->next) - error_info.line = in->line; - else { - if (p->errors && in->fp && p->linep != p->line) - while ((c = sfgetc(in->fp)) != EOF) - if (c == '\n') { - error_info.line++; - break; - } - if (!(p->disc->flags & EX_INTERACTIVE)) error_info.line = in->line; + else + { + if (p->errors && in->fp && p->linep != p->line) + while ((c = sfgetc(in->fp)) != EOF) + if (c == '\n') + { + error_info.line++; + break; + } + if (!(p->disc->flags & EX_INTERACTIVE)) + error_info.line = in->line; } if (in->fp && in->close) - sfclose(in->fp); + sfclose(in->fp); if (in->pushback) - free(in->pushback); + free(in->pushback); p->input = in->next; free(in); setcontext(p); if (p->program) - expr.program = p->program; + expr.program = p->program; return 0; - } +} /* * clear global state of stale pointers */ - void - exinit(void) { +void exinit(void) { memset (&expr, 0, sizeof(Exstate_t)); - } +} + /* * compile the expression in [sf]p */ - int - excomp(register Expr_t * p, const char *name, int line, - const char *sp, Sfio_t * fp) { - int eof; +int +excomp(register Expr_t* p, const char* name, int line, const char* sp, Sfio_t* fp) +{ + Exid_t* v; + int eof; p->more = 0; eof = p->eof; - if (!sp && !fp) { - if (!p->input) + if (!sp && !fp) + { + if (!p->input) + return -1; + } + else if (expush(p, name, line, sp, fp)) return -1; - } else if (expush(p, name, line, sp, fp)) - return -1; else - p->input->unit = line >= 0; + p->input->unit = line >= 0; exparse(); p->input->unit = 0; expop(p); p->eof = eof; + if (expr.statics) + { + for (v = (Exid_t*)dtfirst(p->symbols); v; v = (Exid_t*)dtnext(p->symbols, v)) + if (v->isstatic) + { + dtdelete(p->symbols, v); + if (!--expr.statics) + break; + } + expr.statics = 0; + } return 0; - } +} /* * free the program p */ - void - exclose(register Expr_t * p, int all) { - register int i; - register Exinput_t *in; - - if (p) { - if (all) { - for (i = 3; i < elementsof(p->file); i++) - if (p->file[i]) - sfclose(p->file[i]); - if (p->vm) - vmclose(p->vm); - if (p->ve) - vmclose(p->ve); - if (p->symbols) - dtclose(p->symbols); - if (p->tmp) - sfclose(p->tmp); - while ((in = p->input)) { - if (in->pushback) - free(in->pushback); - if (in->fp && in->close) - sfclose(in->fp); - if ((p->input = in->next)) - free(in); +void +exclose(register Expr_t* p, int all) +{ + register int i; + register Exinput_t* in; + + if (p) + { + if (all) + { + for (i = 3; i < elementsof(p->file); i++) + if (p->file[i]) + sfclose(p->file[i]); + if (p->vm) + vmclose(p->vm); + if (p->ve) + vmclose(p->ve); + if (p->symbols) + dtclose(p->symbols); + if (p->tmp) + sfclose(p->tmp); + while ((in = p->input)) + { + if (in->pushback) + free(in->pushback); + if (in->fp && in->close) + sfclose(in->fp); + if ((p->input = in->next)) + free(in); + } + free(p); + } + else + { + vmclear(p->ve); + p->main.value = 0; } - free(p); - } else { - vmclear(p->ve); - p->main.value = 0; - } } - } +} /* checkBinary: * See if application wants to allow the given expression * combination. l and r give the operands; the operator * is given by ex. r may be NULL. */ - static void - checkBinary(Expr_t * p, Exnode_t * l, Exnode_t * ex, Exnode_t * r) { +static void +checkBinary(Expr_t * p, Exnode_t * l, Exnode_t * ex, Exnode_t * r) +{ if ((*p->disc->binaryf) (p, l, ex, r, 1, p->disc) < 0) { if (r) exerror @@ -1020,15 +1099,15 @@ extern "C" { ("cannot apply operator %s to expression of type %s", exopname(ex->op), extypename(p, l->type)); } - } +} /* checkName: * We allow parser to accept any name in a declaration, in * order to check that the name is undeclared and give a better * error message if it isn't. */ - static void - checkName(Exid_t * id) { +static void checkName(Exid_t * id) +{ switch (id->lex) { case DYNAMIC: exerror("Variable \"%s\" already declared", id->name); @@ -1046,22 +1125,24 @@ extern "C" { "Unexpected token \"%s\" as name in dcl_item", id->name); break; } - } +} - static int - cmpKey(Dt_t * d, Extype_t * key1, Extype_t * key2, Dtdisc_t * disc) { +static int +cmpKey(Dt_t * d, Extype_t * key1, Extype_t * key2, Dtdisc_t * disc) +{ if (key1->integer < key2->integer) return -1; else if (key1->integer > key2->integer) return 1; else return 0; - } +} - int - exisAssign(Exnode_t * n) { +int +exisAssign(Exnode_t * n) +{ return ((n->op == '=') && (n->subop == '=')); - } +} #endif diff --git a/lib/expr/exlexname.c b/lib/expr/exlexname.c index c3e98808e..1cb2092e7 100644 --- a/lib/expr/exlexname.c +++ b/lib/expr/exlexname.c @@ -1,5 +1,4 @@ -/* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -24,28 +23,29 @@ #define TOTNAME 3 #define MAXNAME 16 -char *exlexname(int op, int subop) +char* +exlexname(int op, int subop) { - register char *b; + register char* b; - static int n; - static char buf[TOTNAME][MAXNAME]; + static int n; + static char buf[TOTNAME][MAXNAME]; - if (op > MINTOKEN && op < MAXTOKEN) - return (char *) exop[op - MINTOKEN]; - if (++n > TOTNAME) - n = 0; - b = buf[n]; - if (op == '=') { - if (subop > MINTOKEN && subop < MAXTOKEN) - sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); - else if (subop > ' ' && subop <= '~') - sfsprintf(b, MAXNAME, "%c=", subop); - else - sfsprintf(b, MAXNAME, "(%d)=", subop); - } else if (op > ' ' && op <= '~') - sfsprintf(b, MAXNAME, "%c", op); - else - sfsprintf(b, MAXNAME, "(%d)", op); - return b; + if (op > MINTOKEN && op < MAXTOKEN) + return (char*)exop[op - MINTOKEN]; + if (++n > TOTNAME) + n = 0; + b = buf[n]; + if (op == '=') + { + if (subop > MINTOKEN && subop < MAXTOKEN) + sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); + else if (subop > ' ' && subop <= '~') + sfsprintf(b, MAXNAME, "%c=", subop); + else sfsprintf(b, MAXNAME, "(%d)=", subop); + } + else if (op > ' ' && op <= '~') + sfsprintf(b, MAXNAME, "%c", op); + else sfsprintf(b, MAXNAME, "(%d)", op); + return b; } diff --git a/lib/expr/exlib.h b/lib/expr/exlib.h index 953f113d5..6fe96e5b8 100644 --- a/lib/expr/exlib.h +++ b/lib/expr/exlib.h @@ -28,27 +28,36 @@ extern "C" { #include #include - typedef struct Exinput_s { /* input stack */ - struct Exinput_s *next; /* next in stack */ - int close; /* close fp on pop */ - char *file; /* previous file */ - Sfio_t *fp; /* expression file pointer */ - int line; /* previous line */ - int nesting; /* expression nesting level */ - int peek; /* 1 char peek */ - int unit; /* first frame in parse unit */ - char *pushback; /* pushback buffer */ - char *bp; /* expression string base */ - char *pp; /* pushback pointer */ - char *sp; /* expression string pointer */ - } Exinput_t; - - typedef struct Print_s { /* compiled printf arg node */ - struct Print_s *next; /* next arg */ - char *format; /* printf format for arg */ - struct Exnode_s *param[3]; /* 0:width 1:precision 2:base */ - struct Exnode_s *arg; /* arg to format */ - } Print_t; +#define sfstrseek(f,p,m) \ + ( \ + (((p) < 0 || (p) > (f)->size) ? (char*)0 : \ + (char*)((f)->next = (f)->data+(p)) ) \ + ) + + +typedef struct Exinput_s /* input stack */ +{ + struct Exinput_s*next; /* next in stack */ + int close; /* close fp on pop */ + char* file; /* previous file */ + Sfio_t* fp; /* expression file pointer */ + int line; /* previous line */ + int nesting; /* expression nesting level */ + int peek; /* 1 char peek */ + int unit; /* first frame in parse unit */ + char* pushback; /* pushback buffer */ + char* bp; /* expression string base */ + char* pp; /* pushback pointer */ + char* sp; /* expression string pointer */ +} Exinput_t; + +typedef struct Print_s /* compiled printf arg node */ +{ + struct Print_s* next; /* next arg */ + char* format; /* printf format for arg */ + struct Exnode_s*param[3]; /* 0:width 1:precision 2:base */ + struct Exnode_s*arg; /* arg to format */ +} Print_t; #define _EX_DATA_PRIVATE_ \ Exnode_t* next; /* free list link */ \ @@ -69,7 +78,7 @@ extern "C" { Exid_t* array; /* array */ \ Exnode_t* string; /* string */ \ Exnode_t* seps; /* optional separators */ \ - } split; /* string split */ \ + } split; /* string split */ \ struct \ { \ Exnode_t* descriptor; /* Expr_t.file index */ \ @@ -93,15 +102,14 @@ extern "C" { Exnode_t* descriptor; /* Expr_t.file index */ \ Exnode_t* format; /* format arg */ \ Exnode_t* args; /* actual args */ \ - } scan; /* printf */ + } scan; /* printf */ #define _EX_NODE_PRIVATE_ \ Exshort_t subop; /* operator qualifier */ \ - Exshort_t pad_2; /* padding */ + Exshort_t pad_2; /* padding */ #define _EX_PROG_PRIVATE_ \ Vmalloc_t* ve; /* eval tmp region */ \ - Vmalloc_t* vc; /* str_* region */ \ Dt_t* frame; /* frame symbol table */ \ Dtdisc_t symdisc; /* Expr_t.symbols discipline */ \ Exdisc_t* disc; /* user discipline */ \ @@ -118,7 +126,7 @@ extern "C" { int linewrap; /* linep wrapped around line[] */ \ int loopcount; /* break|continue|return count */ \ int loopop; /* break|continue|return op */ \ - int nesting; /* exstatement() nesting */ + int nesting; /* exstatement() nesting */ #include #include @@ -132,44 +140,50 @@ extern "C" { #define putcontext(p,c) (((p)->linep>=&(p)->line[sizeof((p)->line)]?(p)->linep=(p)->line,(p)->linewrap=1:0),*(p)->linep++=(c)) #define setcontext(p) ((p)->linep=(p)->line,(p)->linewrap=0) - typedef struct Switch_s { /* switch parse state */ - struct Switch_s *prev; /* previous switch state */ - Exnode_t *firstcase; /* first case block */ - Exnode_t *lastcase; /* last case block */ - Exnode_t *defcase; /* default case block */ - Extype_t **base; /* label base pointer */ - Extype_t **cur; /* current label pointer */ - Extype_t **last; /* last label pointer */ - int def; /* default label hit */ - int type; /* switch test type */ - } Switch_t; - - typedef struct { /* associative array bucket */ - Dtlink_t link; /* table link */ - Extype_t key; /* key */ - Extype_t value; /* value */ - char name[1]; /* key name */ - } Exassoc_t; - - typedef struct { /* ex global state */ - Exid_t *id; /* current declaration id */ - int declare; /* current declaration type */ - Exref_t *lastref; /* last in . reference list */ - int nolabel; /* ':' not a label */ - Exinput_t null; /* null input */ - Expr_t *program; /* current program */ - Exnode_t *procedure; /* current procedure */ - Exref_t *refs; /* . reference list */ - Switch_t *swstate; /* switch parse state */ - char nullstring[1]; /* "" */ - } Exstate_t; - - extern Exid_t exbuiltin[]; - extern const char *exversion; - extern Exstate_t expr; - - extern int exparse(void); /* yacc should do this */ - extern Sflong_t strToL(char *, char **); +typedef struct Switch_s /* switch parse state */ +{ + struct Switch_s*prev; /* previous switch state */ + Exnode_t* firstcase; /* first case block */ + Exnode_t* lastcase; /* last case block */ + Exnode_t* defcase; /* default case block */ + Extype_t** base; /* label base pointer */ + Extype_t** cur; /* current label pointer */ + Extype_t** last; /* last label pointer */ + int def; /* default label hit */ + int type; /* switch test type */ +} Switch_t; + +typedef struct Exassoc_s /* associative array bucket */ +{ + Dtlink_t link; /* table link */ + Extype_t key; /* key */ + Extype_t value; /* value */ + char name[1]; /* index name */ +} Exassoc_t; + +typedef struct Exstate_s /* ex global state */ +{ + Exid_t* id; /* current declaration id */ + int declare; /* current declaration type */ + Exref_t* lastref; /* last in . reference list */ + int nolabel; /* ':' not a label */ + Exinput_t null; /* null input */ + Expr_t* program; /* current program */ + Exnode_t* procedure; /* current procedure */ + Exref_t* refs; /* . reference list */ + int assigned; /* declaration assignment */ + int instatic; /* static declaration */ + int statics; /* static used */ + Switch_t* swstate; /* switch parse state */ + char nullstring[1]; /* "" */ +} Exstate_t; + +extern Exid_t exbuiltin[]; +extern const char* exversion; +extern Exstate_t expr; + +extern int exparse(void); /* yacc should do this */ +extern Sflong_t strToL(char *, char **); #endif diff --git a/lib/expr/exopen.c b/lib/expr/exopen.c index bf62276ec..5fdbccd0c 100644 --- a/lib/expr/exopen.c +++ b/lib/expr/exopen.c @@ -33,43 +33,40 @@ * allocate a new expression program environment */ -Expr_t *exopen(register Exdisc_t * disc) +Expr_t* +exopen(register Exdisc_t* disc) { - register Expr_t *program; - register Exid_t *sym; - int debug; + register Expr_t* program; + register Exid_t* sym; + int debug; - if (!(program = newof(0, Expr_t, 1, 0))) - return 0; - program->symdisc.key = offsetof(Exid_t, name); - debug = getenv("VMDEBUG") != 0; - if (!(program->symbols = dtopen(&program->symdisc, Dtset)) || - !(program->tmp = sfstropen()) || - !(program->vm = - (debug ? vmopen(Vmdcsbrk, Vmdebug, VM_DBCHECK | VM_DBABORT) : - vmopen(Vmdcheap, Vmbest, 0))) - || !(program->ve = - (debug ? vmopen(Vmdcsbrk, Vmdebug, VM_DBCHECK | VM_DBABORT) : - vmopen(Vmdcheap, Vmbest, 0)))) { - exclose(program, 1); - return 0; - } - program->vc = program->ve; - program->id = "libexpr:expr"; - program->disc = disc; - setcontext(program); - program->file[0] = sfstdin; - program->file[1] = sfstdout; - program->file[2] = sfstderr; - strcpy(program->main.name, "main"); - program->main.lex = PROCEDURE; - program->main.index = PROCEDURE; - dtinsert(program->symbols, &program->main); - if (!(disc->flags & EX_PURE)) - for (sym = exbuiltin; *sym->name; sym++) - dtinsert(program->symbols, sym); - if ((sym = disc->symbols)) - for (; *sym->name; sym++) - dtinsert(program->symbols, sym); - return program; + if (!(program = newof(0, Expr_t, 1, 0))) + return 0; + program->symdisc.key = offsetof(Exid_t, name); + debug = getenv("VMDEBUG") != 0; + if (!(program->symbols = dtopen(&program->symdisc, Dtset)) || + !(program->tmp = sfstropen()) || + !(program->vm = (debug ? vmopen(Vmdcsbrk, Vmdebug, VM_DBCHECK|VM_DBABORT) : vmopen(Vmdcheap, Vmbest, 0))) || + !(program->ve = (debug ? vmopen(Vmdcsbrk, Vmdebug, VM_DBCHECK|VM_DBABORT) : vmopen(Vmdcheap, Vmbest, 0)))) + { + exclose(program, 1); + return 0; + } + program->id = "libexpr:expr"; + program->disc = disc; + setcontext(program); + program->file[0] = sfstdin; + program->file[1] = sfstdout; + program->file[2] = sfstderr; + strcpy(program->main.name, "main"); + program->main.lex = PROCEDURE; + program->main.index = PROCEDURE; + dtinsert(program->symbols, &program->main); + if (!(disc->flags & EX_PURE)) + for (sym = exbuiltin; *sym->name; sym++) + dtinsert(program->symbols, sym); + if ((sym = disc->symbols)) + for (; *sym->name; sym++) + dtinsert(program->symbols, sym); + return program; } diff --git a/lib/expr/exparse.y b/lib/expr/exparse.y index 14a581408..4421f6748 100644 --- a/lib/expr/exparse.y +++ b/lib/expr/exparse.y @@ -1,5 +1,5 @@ /* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -13,14 +13,11 @@ %{ - /* * Glenn Fowler * AT&T Research * * expression library grammar and compiler - * - * NOTE: procedure arguments not implemented yet */ #ifdef WIN32 @@ -55,14 +52,15 @@ %token MINTOKEN +%token CHARACTER %token INTEGER %token UNSIGNED -%token CHARACTER %token FLOATING %token STRING %token VOIDTYPE +%token STATIC -%token ADDRESS +%token ADDRESS %token ARRAY %token BREAK %token CALL @@ -133,11 +131,11 @@ %binary EQ NE %binary '<' '>' LE GE %left LS RS -%left '+' '-' IN_OP +%left '+' '-' IN_OP %left '*' '/' '%' %right '!' '~' '#' UNARY %right INC DEC -%right CAST +%right CAST %left '(' %type statement statement_list arg_list @@ -151,15 +149,16 @@ %type CONSTANT ARRAY FUNCTION DECLARE %type EXIT PRINT PRINTF QUERY %type RAND SRAND -%type SPRINTF GSUB SUB +%type SPRINTF PROCEDURE name dcl_name +%type GSUB SUB SUBSTR %type SPLIT TOKENS splitop -%type SUBSTR PROCEDURE name dcl_name %type IF WHILE FOR ITERATER %type BREAK CONTINUE print member %type RETURN DYNAMIC SWITCH UNSET %type SCANF SSCANF scan %type FLOATING %type INTEGER UNSIGNED array +%type static %type STRING %token MAXTOKEN @@ -206,11 +205,14 @@ action : LABEL ':' { expr.procedure = $1->value = exnewnode(expr.program, PROCEDURE, 1, $1->type, NiL, NiL); expr.procedure->type = INTEGER; if (!(disc = newof(0, Dtdisc_t, 1, 0))) - exerror("out of space [frame discipline]"); + exnospace(); disc->key = offsetof(Exid_t, name); - if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols)) - exerror("out of space [frame table]"); - expr.program->symbols = expr.program->frame = expr.procedure->data.procedure.frame; + if (expr.assigned && !streq($1->name, "begin")) + { + if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols)) + exnospace(); + expr.program->symbols = expr.program->frame = expr.procedure->data.procedure.frame; + } } statement_list { expr.procedure = 0; @@ -218,6 +220,7 @@ action : LABEL ':' { { expr.program->symbols = expr.program->frame->view; dtview(expr.program->frame, NiL); + expr.program->frame = 0; } if ($4 && $4->op == S2B) { @@ -247,7 +250,16 @@ statement_list : /* empty */ exfreenode(expr.program, $1); $$ = $2; } - else $$ = exnewnode(expr.program, ';', 1, $2->type, $1, $2); + else if ($1->op == ';') + { + $$ = $1; + $1->data.operand.last = $1->data.operand.last->data.operand.right = exnewnode(expr.program, ';', 1, $2->type, $2, NiL); + } + else + { + $$ = exnewnode(expr.program, ';', 1, $1->type, $1, NiL); + $$->data.operand.last = $$->data.operand.right = exnewnode(expr.program, ';', 1, $2->type, $2, NiL); + } } ; @@ -259,9 +271,10 @@ statement : '{' statement_list '}' { $$ = ($1 && $1->type == STRING) ? exnewnode(expr.program, S2B, 1, INTEGER, $1, NiL) : $1; } - | DECLARE {expr.declare=$1->type;} dcl_list ';' + | static {expr.instatic=$1;} DECLARE {expr.declare=$3->type;} dcl_list ';' { - $$ = $3; + $$ = $5; + expr.declare = 0; } | IF '(' expr ')' statement else_opt { @@ -353,6 +366,7 @@ statement : '{' statement_list '}' free(sw->base); if (sw != &swstate) free(sw); + expr.declare = 0; } | BREAK expr_opt ';' { @@ -391,12 +405,13 @@ switch_list : /* empty */ { if (!(sw = newof(0, Switch_t, 1, 0))) { - exerror("out of space [switch]"); + exnospace(); sw = &swstate; } sw->prev = expr.swstate; } - else sw = &swstate; + else + sw = &swstate; expr.swstate = sw; sw->type = expr.declare; sw->firstcase = 0; @@ -406,7 +421,7 @@ switch_list : /* empty */ n = 8; if (!(sw->base = newof(0, Extype_t*, n, 0))) { - exerror("out of space [case]"); + exnospace(); n = 0; } sw->cur = sw->base; @@ -425,7 +440,8 @@ switch_item : case_list statement_list { if (sw->lastcase) sw->lastcase->data.select.next = $$; - else sw->firstcase = $$; + else + sw->firstcase = $$; sw->lastcase = $$; n = sw->cur - sw->base; sw->cur = sw->base; @@ -433,13 +449,15 @@ switch_item : case_list statement_list memcpy($$->data.select.constant, sw->base, n * sizeof(Extype_t*)); $$->data.select.constant[n] = 0; } - else $$->data.select.constant = 0; + else + $$->data.select.constant = 0; if (sw->def) { sw->def = 0; if (sw->defcase) exerror("duplicate default in switch"); - else sw->defcase = $2; + else + sw->defcase = $2; } } ; @@ -475,6 +493,16 @@ case_item : CASE constant ':' } ; +static : /* empty */ + { + $$ = 0; + } + | STATIC + { + $$ = 1; + } + ; + dcl_list : dcl_item | dcl_list ',' dcl_item { @@ -486,7 +514,8 @@ dcl_list : dcl_item dcl_item : dcl_name {checkName ($1); expr.id=$1;} array initialize { $$ = 0; - $1->type = expr.declare; + if (!$1->type || expr.declare) + $1->type = expr.declare; if ($4 && $4->op == PROCEDURE) { $1->lex = PROCEDURE; @@ -502,15 +531,14 @@ dcl_item : dcl_name {checkName ($1); expr.id=$1;} array initialize Dtdisc_t* disc; if (!(disc = newof(0, Dtdisc_t, 1, 0))) - exerror("out of space [associative array]"); + exnospace(); if ($3 == INTEGER) { disc->key = offsetof(Exassoc_t, key); disc->size = sizeof(Extype_t); disc->comparf = (Dtcompar_f)cmpKey; } - else { + else disc->key = offsetof(Exassoc_t, name); - } if (!($1->local.pointer = (char*)dtopen(disc, Dtoset))) exerror("%s: cannot initialize associative array", $1->name); $1->index_type = $3; /* -1 indicates no typechecking */ @@ -525,6 +553,11 @@ dcl_item : dcl_name {checkName ($1); expr.id=$1;} array initialize $4->data.operand.left = exnewnode(expr.program, DYNAMIC, 0, $1->type, NiL, NiL); $4->data.operand.left->data.variable.symbol = $1; $$ = $4; + if (!expr.program->frame && !expr.program->errors) + { + expr.assigned++; + exeval(expr.program, $$, NiL); + } } else if (!$3) $1->value->data.value = exzero($1->type); @@ -532,7 +565,7 @@ dcl_item : dcl_name {checkName ($1); expr.id=$1;} array initialize } ; -dcl_name : NAME +dcl_name : NAME | DYNAMIC | ID | FUNCTION @@ -581,9 +614,11 @@ expr : '(' expr ')' { if (!$3->type) $1->type = $3->type = rel ? STRING : INTEGER; - else $1->type = $3->type; + else + $1->type = $3->type; } - else if (!$3->type) $3->type = $1->type; + else if (!$3->type) + $3->type = $1->type; if ($1->type != $3->type) { if ($1->type == STRING) @@ -600,9 +635,7 @@ expr : '(' expr ')' $$ = exnewnode(expr.program, $2, 1, rel, $1, $3); if (!expr.program->errors && $1->op == CONSTANT && $3->op == CONSTANT) { - expr.program->vc = expr.program->vm; $$->data.constant.value = exeval(expr.program, $$, NiL); - expr.program->vc = expr.program->ve; $$->binary = 0; $$->op = CONSTANT; exfreenode(expr.program, $1); @@ -696,7 +729,8 @@ expr : '(' expr ')' exfreenode(expr.program, $1); $$ = $3; } - else $$ = exnewnode(expr.program, ',', 1, $3->type, $1, $3); + else + $$ = exnewnode(expr.program, ',', 1, $3->type, $1, $3); } | expr '?' {expr.nolabel=1;} expr ':' {expr.nolabel=0;} expr { @@ -704,7 +738,8 @@ expr : '(' expr ')' { if (!$7->type) $4->type = $7->type = INTEGER; - else $4->type = $7->type; + else + $4->type = $7->type; } else if (!$7->type) $7->type = $4->type; @@ -735,7 +770,8 @@ expr : '(' expr ')' } exfreenode(expr.program, $1); } - else $$ = exnewnode(expr.program, '?', 1, $4->type, $1, exnewnode(expr.program, ':', 1, $4->type, $4, $7)); + else + $$ = exnewnode(expr.program, '?', 1, $4->type, $1, exnewnode(expr.program, ':', 1, $4->type, $4, $7)); } | '!' expr { @@ -787,6 +823,10 @@ expr : '(' expr ')' | FUNCTION '(' args ')' { $$ = exnewnode(expr.program, FUNCTION, 1, T($1->type), call(0, $1, $3), $3); + if (!expr.program->disc->getf) + exerror("%s: function references not supported", $$->data.operand.left->data.variable.symbol->name); + else if (expr.program->disc->reff) + (*expr.program->disc->reff)(expr.program, $$->data.operand.left, $$->data.operand.left->data.variable.symbol, 0, NiL, EX_CALL, expr.program->disc); } | GSUB '(' args ')' { @@ -845,20 +885,21 @@ expr : '(' expr ')' $$->data.print.descriptor = $3->data.operand.left; $3 = $3->data.operand.right; } - else switch ($1->index) - { - case QUERY: - $$->data.print.descriptor = exnewnode(expr.program, CONSTANT, 0, INTEGER, NiL, NiL); - $$->data.print.descriptor->data.constant.value.integer = 2; - break; - case PRINTF: - $$->data.print.descriptor = exnewnode(expr.program, CONSTANT, 0, INTEGER, NiL, NiL); - $$->data.print.descriptor->data.constant.value.integer = 1; - break; - case SPRINTF: - $$->data.print.descriptor = 0; - break; - } + else + switch ($1->index) + { + case QUERY: + $$->data.print.descriptor = exnewnode(expr.program, CONSTANT, 0, INTEGER, NiL, NiL); + $$->data.print.descriptor->data.constant.value.integer = 2; + break; + case PRINTF: + $$->data.print.descriptor = exnewnode(expr.program, CONSTANT, 0, INTEGER, NiL, NiL); + $$->data.print.descriptor->data.constant.value.integer = 1; + break; + case SPRINTF: + $$->data.print.descriptor = 0; + break; + } $$->data.print.args = preprint($3); } | scan '(' args ')' @@ -871,29 +912,30 @@ expr : '(' expr ')' $$->data.scan.descriptor = $3->data.operand.left; $3 = $3->data.operand.right; } - else switch ($1->index) - { - case SCANF: - $$->data.scan.descriptor = 0; - break; - case SSCANF: - if ($3 && $3->data.operand.left->type == STRING) + else + switch ($1->index) { - $$->data.scan.descriptor = $3->data.operand.left; - $3 = $3->data.operand.right; + case SCANF: + $$->data.scan.descriptor = 0; + break; + case SSCANF: + if ($3 && $3->data.operand.left->type == STRING) + { + $$->data.scan.descriptor = $3->data.operand.left; + $3 = $3->data.operand.right; + } + else + exerror("%s: string argument expected", $1->name); + break; } - else - exerror("%s: string argument expected", $1->name); - break; - } if (!$3 || !$3->data.operand.left || $3->data.operand.left->type != STRING) exerror("%s: format argument expected", $1->name); $$->data.scan.format = $3->data.operand.left; for (x = $$->data.scan.args = $3->data.operand.right; x; x = x->data.operand.right) { - if (x->data.operand.left->op != ADDRESS) - exerror("%s: address argument expected", $1->name); - x->data.operand.left = x->data.operand.left->data.operand.left; + if (x->data.operand.left->op != ADDRESS) + exerror("%s: address argument expected", $1->name); + x->data.operand.left = x->data.operand.left->data.operand.left; } } | variable assign @@ -966,7 +1008,8 @@ constant : CONSTANT $$ = exnewnode(expr.program, CONSTANT, 0, $1->type, NiL, NiL); if (!expr.program->disc->reff) exerror("%s: identifier references not supported", $1->name); - else $$->data.constant.value = (*expr.program->disc->reff)(expr.program, $$, $1, NiL, NiL, EX_SCALAR, expr.program->disc); + else + $$->data.constant.value = (*expr.program->disc->reff)(expr.program, $$, $1, NiL, NiL, EX_SCALAR, expr.program->disc); } | FLOATING { @@ -1005,23 +1048,23 @@ variable : ID members } | DYNAMIC index members { - Exnode_t* n; + Exnode_t* n; - n = exnewnode(expr.program, DYNAMIC, 0, $1->type, NiL, NiL); - n->data.variable.symbol = $1; - n->data.variable.reference = 0; - if (((n->data.variable.index = $2) == 0) != ($1->local.pointer == 0)) - exerror("%s: is%s an array", $1->name, $1->local.pointer ? "" : " not"); + n = exnewnode(expr.program, DYNAMIC, 0, $1->type, NiL, NiL); + n->data.variable.symbol = $1; + n->data.variable.reference = 0; + if (((n->data.variable.index = $2) == 0) != ($1->local.pointer == 0)) + exerror("%s: is%s an array", $1->name, $1->local.pointer ? "" : " not"); if ($1->local.pointer && ($1->index_type > 0)) { if ($2->type != $1->index_type) - exerror("%s: indices must have type %s, not %s", + exerror("%s: indices must have type %s, not %s", $1->name, extypename(expr.program, $1->index_type),extypename(expr.program, $2->type)); } if ($3) { - n->data.variable.dyna =exnewnode(expr.program, 0, 0, 0, NiL, NiL); - $$ = makeVar(expr.program, $1, $2, n, $3); - } - else $$ = n; + n->data.variable.dyna =exnewnode(expr.program, 0, 0, 0, NiL, NiL); + $$ = makeVar(expr.program, $1, $2, n, $3); + } + else $$ = n; } | NAME { @@ -1125,6 +1168,7 @@ formal_item : DECLARE {expr.declare=$1->type;} name $3->type = $1->type; $3->value = exnewnode(expr.program, 0, 0, 0, NiL, NiL); expr.procedure->data.procedure.arity++; + expr.declare = 0; } ; @@ -1145,7 +1189,7 @@ members : /* empty */ $$ = expr.refs; } | '.' ID member - { + { Exref_t* r; Exref_t* l; @@ -1160,7 +1204,7 @@ members : /* empty */ expr.refs = l; expr.lastref = r; $$ = expr.refs; - } + } ; member : '.' ID @@ -1172,7 +1216,6 @@ member : '.' ID $$ = $2; } ; - assign : /* empty */ { $$ = 0; @@ -1189,19 +1232,24 @@ initialize : assign register Dtdisc_t* disc; if (expr.procedure) - exerror("no nested function definitions"); + exerror("%s: nested function definitions not supported", expr.id->name); expr.procedure = exnewnode(expr.program, PROCEDURE, 1, expr.declare, NiL, NiL); if (!(disc = newof(0, Dtdisc_t, 1, 0))) - exerror("out of space [frame discipline]"); + exnospace(); disc->key = offsetof(Exid_t, name); - if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols)) - exerror("out of space [frame table]"); - expr.program->symbols = expr.program->frame = expr.procedure->data.procedure.frame; - expr.program->formals = 1; + if (!streq(expr.id->name, "begin")) + { + if (!(expr.procedure->data.procedure.frame = dtopen(disc, Dtset)) || !dtview(expr.procedure->data.procedure.frame, expr.program->symbols)) + exnospace(); + expr.program->symbols = expr.program->frame = expr.procedure->data.procedure.frame; + expr.program->formals = 1; + } + expr.declare = 0; } formals { - expr.program->formals = 0; expr.id->lex = PROCEDURE; - expr.id->type = expr.declare; + expr.id->type = expr.procedure->type; + expr.program->formals = 0; + expr.declare = 0; } ')' '{' statement_list '}' { $$ = expr.procedure; @@ -1210,6 +1258,7 @@ initialize : assign { expr.program->symbols = expr.program->frame->view; dtview(expr.program->frame, NiL); + expr.program->frame = 0; } $$->data.operand.left = $3; $$->data.operand.right = excast(expr.program, $7, $$->type, NiL, 0); diff --git a/lib/expr/expr.h b/lib/expr/expr.h index 7fe5ffdb6..35b24a75a 100644 --- a/lib/expr/expr.h +++ b/lib/expr/expr.h @@ -27,23 +27,34 @@ extern "C" { #include -#undef RS /* hp.pa grabs this!! */ +#undef RS /* hp.pa grabs this!! */ -#ifndef __CYGWIN__ #if _BLD_expr && defined(__EXPORT__) #define extern __EXPORT__ #endif #if !_BLD_expr && defined(__IMPORT__) #define extern extern __IMPORT__ #endif + +/* + * bison -pPREFIX misses YYSTYPE + */ + +#if defined(YYSTYPE) || defined(YYBISON) +#define EXSTYPE YYSTYPE +#else +#include +#if defined(YYSTYPE) || defined(yystype) +#define EXSTYPE YYSTYPE +#endif #endif #include "exparse.h" #undef extern -#include "cdt.h" -#include "vmalloc.h" +#include +#include #define EX_VERSION 20000101L @@ -51,31 +62,31 @@ extern "C" { * flags */ -#define EX_CHARSTRING (1<<0) /* '...' same as "..." */ -#define EX_CONSTANT (1<<1) /* compile to constant expr */ -#define EX_FATAL (1<<2) /* errors are fatal */ -#define EX_INTERACTIVE (1<<3) /* interactive input */ -#define EX_PURE (1<<4) /* no default symbols/keywords */ -#define EX_QUALIFY (1<<5) /* '.' refs qualified in id tab */ -#define EX_RETAIN (1<<6) /* retain expressions on redef */ -#define EX_SIZED (1<<7) /* strings are sized buffers */ -#define EX_STRICT (1<<8) /* don't override null label */ -#define EX_UNDECLARED (1<<9) /* allow undeclared identifiers */ +#define EX_CHARSTRING (1<<0) /* '...' same as "..." */ +#define EX_CONSTANT (1<<1) /* compile to constant expr */ +#define EX_FATAL (1<<2) /* errors are fatal */ +#define EX_INTERACTIVE (1<<3) /* interactive input */ +#define EX_PURE (1<<4) /* no default symbols/keywords */ +#define EX_QUALIFY (1<<5) /* '.' refs qualified in id tab */ +#define EX_RETAIN (1<<6) /* retain expressions on redef */ +#define EX_SIZED (1<<7) /* strings are sized buffers */ +#define EX_STRICT (1<<8) /* don't override null label */ +#define EX_UNDECLARED (1<<9) /* allow undeclared identifiers */ -#define EX_ARRAY (-3) /* getval() array elt */ -#define EX_CALL (-2) /* getval() function call elt */ -#define EX_SCALAR (-1) /* getval() scalar elt */ +#define EX_ARRAY (-3) /* getval() array elt */ +#define EX_CALL (-2) /* getval() function call elt */ +#define EX_SCALAR (-1) /* getval() scalar elt */ -#define EX_NAMELEN 32 /* default Exid_t.name length */ +#define EX_NAMELEN 32 /* default Exid_t.name length */ #define EX_INTARRAY 1 /* integer-index array */ /* previously known as EXID, but EXID is also defined by bison in y.tab.h */ -#define EX_ID(n,l,i,t,f) {{0},(l),(i),(t),0,(f),0,{0},n} +#define EX_ID(n,l,i,t,f) {{0},(l),(i),(t),0,(f),0,{0},0,n} -#define DELETE_T BREAK /* exexpr() delete `type' */ +#define DELETE_T MINTOKEN /* exexpr() delete `type' */ -#define INTEGRAL(t) ((t)>=INTEGER&&(t)<=CHARACTER) +#define INTEGRAL(t) ((t)>=CHARACTER&&(t)<=UNSIGNED) #define BUILTIN(t) ((t) > MINTOKEN) /* function type mechanism @@ -88,12 +99,12 @@ extern "C" { * arg 0 is the return value type */ -#define F 01 /* FLOATING */ -#define I 02 /* INTEGER */ -#define S 03 /* STRING */ +#define F 01 /* FLOATING */ +#define I 02 /* INTEGER */ +#define S 03 /* STRING */ -#define TBITS 4 -#define TMASK ((1<>=TBITS) /* shift for next arg */ @@ -103,216 +114,220 @@ extern "C" { #define exstrdup(p,s) vmstrdup((p)->vm,s) #if LONG_MAX > INT_MAX - typedef int Exshort_t; +typedef int Exshort_t; #else - typedef short Exshort_t; +typedef short Exshort_t; #endif - typedef EXSTYPE Extype_t; - - union Exdata_u; - typedef union Exdata_u Exdata_t; - struct Exdisc_s; - typedef struct Exdisc_s Exdisc_t; - struct Exnode_s; - typedef struct Exnode_s Exnode_t; - struct Expr_s; - typedef struct Expr_s Expr_t; - struct Exref_s; - typedef struct Exref_s Exref_t; - - typedef int (*Exerror_f) (Expr_t *, Exdisc_t *, int, const char *, - ...); - typedef void (*Exexit_f) (Expr_t *, Exdisc_t *, int); - - typedef struct { /* user defined member type */ - Sflong_t number; - char *pointer; - } Exlocal_t; - - typedef struct Exid_s { /* id symbol table info */ - Dtlink_t link; /* symbol table link */ - long lex; /* lex class */ - long index; /* user defined index */ - long type; /* symbol and arg types */ - long index_type; /* index type for arrays */ - long flags; /* user defined flags */ - Exnode_t *value; /* value */ - Exlocal_t local; /* user defined local stuff */ - char name[EX_NAMELEN]; /* symbol name */ - } Exid_t; - - struct Exref_s { /* . reference list */ - Exref_t *next; /* next in list */ - Exid_t *symbol; /* reference id symbol */ - Exnode_t *index; /* optional reference index */ - }; - - typedef struct { /* sized buffer */ - unsigned long size; /* buffer size */ - char *data; /* buffer data */ - } Exbuf_t; - - union Exdata_u { - - struct { - Extype_t value; /* constant value */ - Exid_t *reference; /* conversion reference symbol */ - } constant; /* variable reference */ - - struct { - Exnode_t *left; /* left operand */ - Exnode_t *right; /* right operand */ - } operand; /* operands */ - - struct { - Exnode_t *statement; /* case label statement(s) */ - Exnode_t *next; /* next case item */ - Extype_t **constant; /* case label constant array */ - } select; /* case item */ - - struct { - Exid_t *symbol; /* id symbol table entry */ - Exref_t *reference; /* . reference list */ - Exnode_t *index; /* array index expression */ - Exnode_t *dyna; /* dynamic expression */ - } variable; /* variable reference */ +typedef EXSTYPE Extype_t; + +union Exdata_u; typedef union Exdata_u Exdata_t; +struct Exdisc_s; typedef struct Exdisc_s Exdisc_t; +struct Exnode_s; typedef struct Exnode_s Exnode_t; +struct Expr_s; typedef struct Expr_s Expr_t; +struct Exref_s; typedef struct Exref_s Exref_t; + +typedef int (*Exerror_f) (Expr_t *, Exdisc_t *, int, const char *, ...); +typedef void (*Exexit_f) (Expr_t *, Exdisc_t *, int); + +typedef struct Exlocal_s /* user defined member type */ +{ + Sflong_t number; + char* pointer; +} Exlocal_t; + +typedef struct Exid_s /* id symbol table info */ +{ + Dtlink_t link; /* symbol table link */ + long lex; /* lex class */ + long index; /* user defined index */ + long type; /* symbol and arg types */ + long index_type; /* index type for arrays */ + long flags; /* user defined flags */ + Exnode_t* value; /* value */ + Exlocal_t local; /* user defined local stuff */ + long isstatic; /* static */ + char name[EX_NAMELEN];/* symbol name */ +} Exid_t; + +struct Exref_s /* . reference list */ +{ + Exref_t* next; /* next in list */ + Exid_t* symbol; /* reference id symbol */ + Exnode_t* index; /* optional reference index */ +}; + +typedef struct Exbuf_s /* sized buffer */ +{ + unsigned long size; /* buffer size */ + char* data; /* buffer data */ +} Exbuf_t; + +union Exdata_u +{ + + struct + { + Extype_t value; /* constant value */ + Exid_t* reference; /* conversion reference symbol */ + } constant; /* variable reference */ + + struct + { + Exnode_t* left; /* left operand */ + Exnode_t* right; /* right operand */ + Exnode_t* last; /* for cons */ + } operand; /* operands */ + + struct + { + Exnode_t* statement; /* case label statement(s) */ + Exnode_t* next; /* next case item */ + Extype_t** constant; /* case label constant array */ + } select; /* case item */ + + struct + { + Exid_t* symbol; /* id symbol table entry */ + Exref_t* reference; /* . reference list */ + Exnode_t* index; /* array index expression */ + Exnode_t* dyna; /* dynamic expression */ + } variable; /* variable reference */ #ifdef _EX_DATA_PRIVATE_ - _EX_DATA_PRIVATE_ + _EX_DATA_PRIVATE_ #endif - }; - - struct Exnode_s { /* expression tree node */ - Exshort_t type; /* value type */ - Exshort_t op; /* operator */ - Exshort_t binary; /* data.operand.{left,right} ok */ - Exshort_t pad_1; /* padding to help cc */ - Exlocal_t local; /* user defined local stuff */ - union { - double (*floating) (char **); /* FLOATING return value */ - Sflong_t(*integer) (char **); /* INTEGER|UNSIGNED return value */ - char *(*string) (char **); /* STRING return value */ - } compiled; /* compiled function pointer */ - Exdata_t data; /* node data */ + +}; + +struct Exnode_s /* expression tree node */ +{ + Exshort_t type; /* value type */ + Exshort_t op; /* operator */ + Exshort_t binary; /* data.operand.{left,right} ok */ + Exshort_t pad_1; /* padding to help cc */ + Exlocal_t local; /* user defined local stuff */ + union + { + double (*floating)(char**); /* FLOATING return value */ + Sflong_t(*integer)(char**); /* INTEGER|UNSIGNED return value*/ + char* (*string)(char**); /* STRING return value */ + } compiled; /* compiled function pointer */ + Exdata_t data; /* node data */ #ifdef _EX_NODE_PRIVATE_ - _EX_NODE_PRIVATE_ + _EX_NODE_PRIVATE_ #endif - }; - - struct Exdisc_s { /* discipline */ - unsigned long version; /* EX_VERSION */ - unsigned long flags; /* EX_* flags */ - Exid_t *symbols; /* static symbols */ - char **data; /* compiled function arg data */ - char *lib; /* pathfind() lib */ - char *type; /* pathfind() type */ - int (*castf) (Expr_t *, Exnode_t *, const char *, int, Exid_t *, - int, Exdisc_t *); - /* unknown cast function */ - int (*convertf) (Expr_t *, Exnode_t *, int, Exid_t *, int, - Exdisc_t *); - /* type conversion function */ - int (*binaryf) (Expr_t *, Exnode_t *, Exnode_t *, Exnode_t *, int, - Exdisc_t *); - /* binary operator function */ - char *(*typename) (Expr_t *, int); - /* application type names */ - int (*stringof) (Expr_t *, Exnode_t *, int, Exdisc_t *); - /* value to string conversion */ - Extype_t(*keyf) (Expr_t *, Extype_t, int, Exdisc_t *); - /* dictionary key for external type objects */ - Exerror_f errorf; /* error function */ - Extype_t(*getf) (Expr_t *, Exnode_t *, Exid_t *, Exref_t *, - void *, int, Exdisc_t *); - /* get value function */ - Extype_t(*reff) (Expr_t *, Exnode_t *, Exid_t *, Exref_t *, - char *, int, Exdisc_t *); - /* reference value function */ - int (*setf) (Expr_t *, Exnode_t *, Exid_t *, Exref_t *, void *, - int, Extype_t, Exdisc_t *); - /* set value function */ - int (*matchf) (Expr_t *, Exnode_t *, const char *, Exnode_t *, - const char *, void *, Exdisc_t *); + +}; + +struct Exdisc_s /* discipline */ +{ + unsigned long version; /* EX_VERSION */ + unsigned long flags; /* EX_* flags */ + Exid_t* symbols; /* static symbols */ + char** data; /* compiled function arg data */ + char* lib; /* pathfind() lib */ + char* type; /* pathfind() type */ + int (*castf)(Expr_t*, Exnode_t*, const char*, int, Exid_t*, int, Exdisc_t*); + /* unknown cast function */ + int (*convertf)(Expr_t*, Exnode_t*, int, Exid_t*, int, Exdisc_t*); + /* type conversion function */ + int (*binaryf) (Expr_t *, Exnode_t *, Exnode_t *, Exnode_t *, int, Exdisc_t *); + /* binary operator function */ + char* (*typename) (Expr_t *, int); + /* application type names */ + int (*stringof) (Expr_t *, Exnode_t *, int, Exdisc_t *); + /* value to string conversion */ + Extype_t (*keyf) (Expr_t *, Extype_t, int, Exdisc_t *); + /* dictionary key for external type objects */ + Exerror_f errorf; /* error function */ + Extype_t (*getf)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*, void*, int, Exdisc_t*); + /* get value function */ + Extype_t (*reff)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*, char*, int, Exdisc_t*); + /* reference value function */ + int (*setf)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*, void*, int, Extype_t, Exdisc_t*); + /* set value function */ + int (*matchf)(Expr_t*, Exnode_t*, const char*, Exnode_t*, const char*, void*, Exdisc_t*); /* exit function */ - Exexit_f exitf; - int *types; - void *user; - }; - - struct Expr_s { /* ex program state */ - const char *id; /* library id */ - Dt_t *symbols; /* symbol table */ - const char *more; /* more after %% (sp or != 0) */ - Sfio_t *file[10]; /* io streams */ - Vmalloc_t *vm; /* program store */ + Exexit_f exitf; + int* types; + void* user; +}; + +struct Expr_s /* ex program state */ +{ + const char* id; /* library id */ + Dt_t* symbols; /* symbol table */ + const char* more; /* more after %% (sp or != 0) */ + Sfio_t* file[10]; /* io streams */ + Vmalloc_t* vm; /* program store */ #ifdef _EX_PROG_PRIVATE_ - _EX_PROG_PRIVATE_ + _EX_PROG_PRIVATE_ #endif - }; - - struct Excc_s; - typedef struct Excc_s Excc_t; - struct Exccdisc_s; - typedef struct Exccdisc_s Exccdisc_t; - - struct Exccdisc_s { /* excc() discipline */ - Sfio_t *text; /* text output stream */ - char *id; /* symbol prefix */ - unsigned long flags; /* EXCC_* flags */ - int (*ccf) (Excc_t *, Exnode_t *, Exid_t *, Exref_t *, Exnode_t *, - Exccdisc_t *); - /* program generator function */ - }; - - struct Excc_s { /* excc() state */ - Expr_t *expr; /* exopen() state */ - Exdisc_t *disc; /* exopen() discipline */ + +}; + +struct Excc_s; typedef struct Excc_s Excc_t; +struct Exccdisc_s; typedef struct Exccdisc_s Exccdisc_t; + +struct Exccdisc_s /* excc() discipline */ +{ + Sfio_t* text; /* text output stream */ + char* id; /* symbol prefix */ + unsigned long flags; /* EXCC_* flags */ + int (*ccf)(Excc_t*, Exnode_t*, Exid_t*, Exref_t*, Exnode_t*, Exccdisc_t*); + /* program generator function */ +}; + +struct Excc_s /* excc() state */ +{ + Expr_t* expr; /* exopen() state */ + Exdisc_t* disc; /* exopen() discipline */ #ifdef _EX_CC_PRIVATE_ - _EX_CC_PRIVATE_ + _EX_CC_PRIVATE_ #endif - }; -#ifndef __CYGWIN__ +}; + #if _BLD_expr && defined(__EXPORT__) #define extern __EXPORT__ -#endif #endif - extern Exnode_t *excast(Expr_t *, Exnode_t *, int, Exnode_t *, int); - extern Exnode_t *exnoncast(Exnode_t *); - extern int excc(Excc_t *, const char *, Exid_t *, int); - extern int exccclose(Excc_t *); - extern Excc_t *exccopen(Expr_t *, Exccdisc_t *); - extern void exclose(Expr_t *, int); - extern int excomp(Expr_t *, const char *, int, const char *, Sfio_t *); - extern char *excontext(Expr_t *, char *, int); - extern int exdump(Expr_t *, Exnode_t *, Sfio_t *); - extern void exerror(const char *, ...); - extern void exwarn(const char *, ...); - extern Extype_t exeval(Expr_t *, Exnode_t *, void *); - extern Exnode_t *exexpr(Expr_t *, const char *, Exid_t *, int); - extern void exfreenode(Expr_t *, Exnode_t *); - extern Exnode_t *exnewnode(Expr_t *, int, int, int, Exnode_t *, - Exnode_t *); - extern Expr_t *exopen(Exdisc_t *); - extern int expop(Expr_t *); - extern int expush(Expr_t *, const char *, int, const char *, Sfio_t *); - extern int exrewind(Expr_t *); - extern void exstatement(Expr_t *); - extern int extoken_fn(Expr_t *); - extern char *exstring(Expr_t *, char *); - extern void *exstralloc(Expr_t *, void *, size_t); - extern int exstrfree(Expr_t *, void *); - extern char *extype(int); - extern Extype_t exzero(int); - extern char *exopname(int); - extern void exinit(void); - extern char *extypename(Expr_t * p, int); - extern int exisAssign(Exnode_t *); +extern Exnode_t* excast(Expr_t*, Exnode_t*, int, Exnode_t*, int); +extern Exnode_t* exnoncast(Exnode_t *); +extern int excc(Excc_t*, const char*, Exid_t*, int); +extern int exccclose(Excc_t*); +extern Excc_t* exccopen(Expr_t*, Exccdisc_t*); +extern void exclose(Expr_t*, int); +extern int excomp(Expr_t*, const char*, int, const char*, Sfio_t*); +extern char* excontext(Expr_t*, char*, int); +extern int exdump(Expr_t*, Exnode_t*, Sfio_t*); +extern void exerror(const char*, ...); +extern void exwarn(const char *, ...); +extern Extype_t exeval(Expr_t*, Exnode_t*, void*); +extern Exnode_t* exexpr(Expr_t*, const char*, Exid_t*, int); +extern void exfreenode(Expr_t*, Exnode_t*); +extern Exnode_t* exnewnode(Expr_t*, int, int, int, Exnode_t*, Exnode_t*); +extern char* exnospace(void); +extern Expr_t* exopen(Exdisc_t*); +extern int expop(Expr_t*); +extern int expush(Expr_t*, const char*, int, const char*, Sfio_t*); +extern int exrewind(Expr_t*); +extern char* exstash(Sfio_t*, Vmalloc_t*); +extern void exstatement(Expr_t*); +extern int extoken_fn(Expr_t*); +extern char* exstring(Expr_t *, char *); +extern void* exstralloc(Expr_t *, void *, size_t); +extern int exstrfree(Expr_t *, void *); +extern char* extype(int); +extern Extype_t exzero(int); +extern char* exopname(int); +extern void exinit(void); +extern char* extypename(Expr_t * p, int); +extern int exisAssign(Exnode_t *); #undef extern diff --git a/lib/expr/exrewind.c b/lib/expr/exrewind.c index e71356d70..326d4c767 100644 --- a/lib/expr/exrewind.c +++ b/lib/expr/exrewind.c @@ -21,35 +21,39 @@ #include "exlib.h" #include -int exrewind(Expr_t * ex) +int +exrewind(Expr_t* ex) { - register int n; + register int n; - if (ex->linewrap) { - exerror("too much pushback"); - return -1; - } - if (!ex->input->pushback - && !(ex->input->pushback = oldof(0, char, sizeof(ex->line), 3))) { - exerror("out of space [rewind]"); - return -1; - } - if ((n = ex->linep - ex->line)) - memcpy(ex->input->pushback, ex->line, n); - if (ex->input->peek) { - ex->input->pushback[n++] = ex->input->peek; - ex->input->peek = 0; - } - ex->input->pushback[n++] = ' '; - ex->input->pushback[n] = 0; - ex->input->pp = ex->input->pushback; - ex->input->nesting = ex->nesting; - setcontext(ex); - return 0; + if (ex->linewrap) + { + exerror("too much pushback"); + return -1; + } + if (!ex->input->pushback && !(ex->input->pushback = oldof(0, char, sizeof(ex->line), 3))) + { + exnospace(); + return -1; + } + if ((n = ex->linep - ex->line)) + memcpy(ex->input->pushback, ex->line, n); + if (ex->input->peek) + { + ex->input->pushback[n++] = ex->input->peek; + ex->input->peek = 0; + } + ex->input->pushback[n++] = ' '; + ex->input->pushback[n] = 0; + ex->input->pp = ex->input->pushback; + ex->input->nesting = ex->nesting; + setcontext(ex); + return 0; } -void exstatement(Expr_t * ex) +void +exstatement(Expr_t* ex) { - ex->nesting = ex->input->nesting; - setcontext(ex); + ex->nesting = ex->input->nesting; + setcontext(ex); } diff --git a/lib/expr/extoken.c b/lib/expr/extoken.c index e86ffcc26..c0bf271b3 100644 --- a/lib/expr/extoken.c +++ b/lib/expr/extoken.c @@ -1,5 +1,5 @@ /* $Id$ $Revision$ */ -/* vim:set shiftwidth=4 ts=8: */ +/* vim:set shiftwidth=4 ts=4: */ /************************************************************************* * Copyright (c) 2011 AT&T Intellectual Property @@ -29,239 +29,224 @@ #define TRACE_lex -10 #endif - -#define TRACE_lex -10 #if TRACE_lex -int traceLex; /* * trace c for op */ -static void trace(Expr_t * ex, int lev, char *op, int c) +static void +trace(Expr_t* ex, int lev, char* op, int c) { - char *s = 0; - char *t; - char buf[16]; - void *x = 0; - - if (!traceLex) - return; - t = ""; - switch (c) { - case 0: - s = " EOF"; - break; - case '=': - s = t = buf; - *t++ = ' '; - if (!lev && exlval.op != c) - *t++ = exlval.op; - *t++ = c; - *t = 0; - break; - case AND: - s = " AND "; - t = "&&"; - break; - case DEC: - s = " DEC "; - t = "--"; - break; - case FUNCTION: - s = " FUNCTION "; - t = exlval.id->name; - break; - case DECLARE: - s = " DECLARE "; - t = exlval.id->name; - break; - case PROCEDURE: - s = " PROCEDURE "; - t = exlval.id->name; - break; - case DYNAMIC: - s = " DYNAMIC "; - t = exlval.id->name; - x = (void *) (exlval.id); - break; - case EQ: - s = " EQ "; - t = "=="; - break; - case FLOATING: - s = " FLOATING "; - sfsprintf(t = buf, sizeof(buf), "%f", exlval.floating); - break; - case GE: - s = " GE "; - t = ">="; - break; - case ID: - s = " ID "; - t = exlval.id->name; - break; - case INC: - s = "INC "; - t = "++"; - break; - case INTEGER: - s = " INTEGER "; - sfsprintf(t = - buf, sizeof(buf), "%I*d", sizeof(exlval.integer), - exlval.integer); - break; - case LABEL: - s = " LABEL "; - t = exlval.id->name; - break; - case LE: - s = " LE "; - t = "<="; - break; - case LS: - s = " LS "; - t = "<<"; - break; - case NAME: - s = " NAME "; - t = exlval.id->name; - x = (void *) (exlval.id); - break; - case NE: - s = " NE "; - t = "!="; - break; - case OR: - s = " OR "; - t = "||"; - break; - case RS: - s = " RS "; - t = ">>"; - break; - case STRING: - s = " STRING "; - t = fmtesc(exlval.string); - break; - case UNSIGNED: - s = " UNSIGNED "; - sfsprintf(t = - buf, sizeof(buf), "%I*u", sizeof(exlval.integer), - exlval.integer); - break; - case BREAK: - s = " break"; - break; - case CASE: - s = " case"; - break; - case CONTINUE: - s = " continue"; - break; - case DEFAULT: - s = " default"; - break; - case ELSE: - s = " else"; - break; - case EXIT: - s = " exit"; - break; - case FOR: - s = " for"; - break; - case ITERATER: - s = " forr"; - break; - case GSUB: - s = " gsub"; - break; - case IF: - s = " if"; - break; - case IN_OP: - s = " in"; - break; - case PRAGMA: - s = " pragma"; - break; - case PRINT: - s = " print"; - break; - case PRINTF: - s = " printf"; - break; - case QUERY: - s = " query"; - break; - case RAND: - s = " rand"; - break; - case RETURN: - s = " return"; - break; - case SPLIT: - s = " split"; - break; - case SPRINTF: - s = " sprintf"; - break; - case SRAND: - s = " srand"; - break; - case SUB: - s = " sub"; - break; - case SUBSTR: - s = " substr"; - break; - case SWITCH: - s = " switch"; - break; - case TOKENS: - s = " tokens"; - break; - case UNSET: - s = " unset"; - break; - case WHILE: - s = " while"; - break; - default: - if (c < 0177) { - s = buf; - *s++ = c; - *s = 0; - t = fmtesc(buf); - s = " "; + char* s = 0; + char* t; + char buf[16]; + void* x = 0; + + t = ""; + switch (c) + { + case 0: + s = " EOF"; + break; + case '=': + s = t = buf; + *t++ = ' '; + if (!lev && exlval.op != c) + *t++ = exlval.op; + *t++ = c; + *t = 0; + break; + case AND: + s = " AND "; + t = "&&"; + break; + case DEC: + s = " DEC "; + t = "--"; + break; + case DECLARE: + s = " DECLARE "; + t = exlval.id->name; + break; + case DYNAMIC: + s = " DYNAMIC "; + t = exlval.id->name; + x = (void *) (exlval.id); + break; + case EQ: + s = " EQ "; + t = "=="; + break; + case FLOATING: + s = " FLOATING "; + sfsprintf(t = buf, sizeof(buf), "%f", exlval.floating); + break; + case GE: + s = " GE "; + t = ">="; + break; + case ID: + s = " ID "; + t = exlval.id->name; + break; + case INC: + s = "INC "; + t = "++"; + break; + case INTEGER: + s = " INTEGER "; + sfsprintf(t = buf, sizeof(buf), "%I*d", sizeof(exlval.integer), exlval.integer); + break; + case LABEL: + s = " LABEL "; + t = exlval.id->name; + break; + case LE: + s = " LE "; + t = "<="; + break; + case LS: + s = " LS "; + t = "<<"; + break; + case NAME: + s = " NAME "; + t = exlval.id->name; + x = (void *) (exlval.id); + break; + case NE: + s = " NE "; + t = "!="; + break; + case OR: + s = " OR "; + t = "||"; + break; + case RS: + s = " RS "; + t = ">>"; + break; + case STRING: + s = " STRING "; + t = fmtesc(exlval.string); + break; + case UNSIGNED: + s = " UNSIGNED "; + sfsprintf(t = buf, sizeof(buf), "%I*u", sizeof(exlval.integer), exlval.integer); + break; + case BREAK: + s = " break"; + break; + case CASE: + s = " case"; + break; + case CONTINUE: + s = " continue"; + break; + case DEFAULT: + s = " default"; + break; + case ELSE: + s = " else"; + break; + case EXIT: + s = " exit"; + break; + case FOR: + s = " for"; + break; + case ITERATER: + s = " forf"; + break; + case GSUB: + s = " gsub"; + break; + case IF: + s = " if"; + break; + case IN_OP: + s = " in"; + break; + case PRAGMA: + s = " pragma"; + break; + case PRINT: + s = " print"; + break; + case PRINTF: + s = " printf"; + break; + case QUERY: + s = " query"; + break; + case RAND: + s = " rand"; + break; + case RETURN: + s = " return"; + break; + case SPLIT: + s = " split"; + break; + case SPRINTF: + s = " sprintf"; + break; + case SRAND: + s = " srand"; + break; + case SUB: + s = " sub"; + break; + case SUBSTR: + s = " substr"; + break; + case SWITCH: + s = " switch"; + break; + case TOKENS: + s = " tokens"; + break; + case UNSET: + s = " unset"; + break; + case WHILE: + s = " while"; + break; + default: + if (c < 0177) + { + s = buf; + *s++ = c; + *s = 0; + t = fmtesc(buf); + s = " "; + } + break; } - break; - } - if (x) - error(TRACE_lex + lev, "%s: [%d] %04d%s%s (%x)", - op, ex->input->nesting, c, s, t, x); - else - error(TRACE_lex + lev, "%s: [%d] %04d%s%s", - op, ex->input->nesting, c, s, t); + if (x) + error(TRACE_lex + lev, "%s: [%d] %04d%s%s (%x)", op, ex->input->nesting, c, s, t, x); + + else + error(TRACE_lex + lev, "%s: [%d] %04d%s%s", op, ex->input->nesting, c, s, t); } /* - * trace wrapper for extoken_fn() + * trace wrapper for extoken() */ +extern int _extoken_fn_(Expr_t*); -int _extoken_fn_(register Expr_t * ex); - -int extoken_fn(Expr_t * ex) +int +extoken_fn(Expr_t* ex) { - int c; + int c; #define extoken_fn _extoken_fn_ - c = extoken_fn(ex); - trace(ex, 0, "exlex", c); - return c; + c = extoken_fn(ex); + trace(ex, 0, "exlex", c); + return c; } #else @@ -270,575 +255,633 @@ int extoken_fn(Expr_t * ex) #endif -#ifdef OLD - -#define BUMP(l) if (l) l++; else l = 2 - -#else - -#define BUMP(l) l++ - -#endif /* * get the next expression char */ -static int lex(register Expr_t * ex) +static int +lex(register Expr_t* ex) { - register int c; - - for (;;) { - if ((c = ex->input->peek)) - ex->input->peek = 0; - else if (ex->input->pp) { - if (!(c = *ex->input->pp++)) { - ex->input->pp = 0; - continue; - } - } else if (ex->input->sp) { - if (!(c = *ex->input->sp++)) { - if (!expop(ex)) - continue; - else - trace(ex, -1, "expop sp FAIL", 0); - ex->input->sp--; - } - } else if (ex->input->fp) { - if ((c = sfgetc(ex->input->fp)) == EOF) { - if (!expop(ex)) - continue; - else - trace(ex, -1, "expop fp FAIL", 0); - c = 0; - } else if ((ex->disc->flags & EX_INTERACTIVE) && c == '\n' - && ex->input->next && !ex->input->next->next - && ex->input->nesting <= 0) { - error_info.line++; - expop(ex); - trace(ex, -1, "expop sp FORCE", 0); - c = 0; - } - } else - c = 0; - if (c == '\n') - setcontext(ex); - else if (c) - putcontext(ex, c); - /* trace(ex, -3, "ex--lex", c); */ - return c; - } + register int c; + + for (;;) + { + if ((c = ex->input->peek)) + ex->input->peek = 0; + else if (ex->input->pp) + { + if (!(c = *ex->input->pp++)) + { + ex->input->pp = 0; + continue; + } + } + else if (ex->input->sp) + { + if (!(c = *ex->input->sp++)) + { + if (!expop(ex)) + continue; + else trace(ex, -1, "expop sp FAIL", 0); + ex->input->sp--; + } + } + else if (ex->input->fp) + { + if ((c = sfgetc(ex->input->fp)) == EOF) + { + if (!expop(ex)) + continue; + else trace(ex, -1, "expop fp FAIL", 0); + c = 0; + } + else if ((ex->disc->flags & EX_INTERACTIVE) && c == '\n' && ex->input->next && !ex->input->next->next && ex->input->nesting <= 0) + { + error_info.line++; + expop(ex); + trace(ex, -1, "expop sp FORCE", 0); + c = 0; + } + } + else c = 0; + if (c == '\n') + setcontext(ex); + else if (c) + putcontext(ex, c); + trace(ex, -3, "ex--lex", c); + return c; + } } /* * get the next expression token */ -int extoken_fn(register Expr_t * ex) +int +extoken_fn(register Expr_t* ex) { - register int c; - register char *s; - register int q; - char *e; - - if (ex->eof || ex->errors) - return 0; - again: - for (;;) - switch (c = lex(ex)) { - case 0: - goto eof; - case '/': - switch (q = lex(ex)) { - case '*': - for (;;) - switch (lex(ex)) { - case '\n': - BUMP(error_info.line); - continue; - case '*': - switch (lex(ex)) { - case 0: - goto eof; - case '\n': - BUMP(error_info.line); - break; + register int c; + register char* s; + register int q; + int b; + char* e; + Dt_t* v; + + if (ex->eof || ex->errors) + return 0; + again: + for (;;) + switch (c = lex(ex)) + { + case 0: + goto eof; + case '/': + switch (q = lex(ex)) + { case '*': - exunlex(ex, '*'); - break; + for (;;) switch (lex(ex)) + { + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; + continue; + case '*': + switch (lex(ex)) + { + case 0: + goto eof; + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; + break; + case '*': + exunlex(ex, '*'); + break; + case '/': + goto again; + } + break; + } + break; case '/': - goto again; + while ((c = lex(ex)) != '\n') + if (!c) + goto eof; + break; + default: + goto opeq; } + /*FALLTHROUGH*/ + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; + /*FALLTHROUGH*/ + case ' ': + case '\t': break; - } - break; - case '/': - while ((c = lex(ex)) != '\n') - if (!c) - goto eof; - break; - default: - goto opeq; - } - /*FALLTHROUGH*/ case '\n': - BUMP(error_info.line); - /*FALLTHROUGH*/ case ' ': - case '\t': - break; - case '(': - case '{': - case '[': - ex->input->nesting++; - return exlval.op = c; - case ')': - case '}': - case ']': - ex->input->nesting--; - return exlval.op = c; - case '+': - case '-': - if ((q = lex(ex)) == c) - return exlval.op = c == '+' ? INC : DEC; - goto opeq; - case '*': - case '%': - case '^': - q = lex(ex); - opeq: - exlval.op = c; - if (q == '=') - c = '='; - else if (q == '%' && c == '%') { - if (ex->input->fp) - ex->more = (const char *) ex->input->fp; - else - ex->more = ex->input->sp; - goto eof; - } else - exunlex(ex, q); - return c; - case '&': - case '|': - if ((q = lex(ex)) == '=') { - exlval.op = c; - return '='; - } - if (q == c) - c = c == '&' ? AND : OR; - else - exunlex(ex, q); - return exlval.op = c; - case '<': - case '>': - if ((q = lex(ex)) == c) { - exlval.op = c = c == '<' ? LS : RS; - if ((q = lex(ex)) == '=') - c = '='; - else - exunlex(ex, q); - return c; - } - goto relational; - case '=': - case '!': - q = lex(ex); - relational: - if (q == '=') - switch (c) { + case '(': + case '{': + case '[': + ex->input->nesting++; + return exlval.op = c; + case ')': + case '}': + case ']': + ex->input->nesting--; + return exlval.op = c; + case '+': + case '-': + if ((q = lex(ex)) == c) + return exlval.op = c == '+' ? INC : DEC; + goto opeq; + case '*': + case '%': + case '^': + q = lex(ex); + opeq: + exlval.op = c; + if (q == '=') + c = '='; + else if (q == '%' && c == '%') + { + if (ex->input->fp) + ex->more = (const char*)ex->input->fp; + else ex->more = ex->input->sp; + goto eof; + } + else exunlex(ex, q); + return c; + case '&': + case '|': + if ((q = lex(ex)) == '=') + { + exlval.op = c; + return '='; + } + if (q == c) + c = c == '&' ? AND : OR; + else exunlex(ex, q); + return exlval.op = c; case '<': - c = LE; - break; case '>': - c = GE; - break; + if ((q = lex(ex)) == c) + { + exlval.op = c = c == '<' ? LS : RS; + if ((q = lex(ex)) == '=') + c = '='; + else exunlex(ex, q); + return c; + } + goto relational; case '=': - c = EQ; - break; case '!': - c = NE; - break; - } else - exunlex(ex, q); - return exlval.op = c; - case '#': - if (!ex->linewrap && !(ex->disc->flags & EX_PURE)) { - s = ex->linep - 1; - while (s > ex->line && isspace(*(s - 1))) - s--; - if (s == ex->line) { - switch (extoken_fn(ex)) { - case DYNAMIC: - case ID: - case NAME: - s = exlval.id->name; - break; - default: - s = ""; - break; - } - if (streq(s, "include")) { - if (extoken_fn(ex) != STRING) - exerror("#%s: string argument expected", s); - else if (!expush(ex, exlval.string, 1, NiL, NiL)) { - setcontext(ex); - goto again; + q = lex(ex); + relational: + if (q == '=') switch (c) + { + case '<': + c = LE; + break; + case '>': + c = GE; + break; + case '=': + c = EQ; + break; + case '!': + c = NE; + break; } - } else - exerror("unknown directive"); - } - } - return exlval.op = c; - case '\'': - case '"': - q = c; - sfstrset(ex->tmp, 0); - ex->input->nesting++; - while ((c = lex(ex)) != q) { - if (c == '\\') { - sfputc(ex->tmp, c); - c = lex(ex); - } - if (!c) { - exerror("unterminated %c string", q); - goto eof; - } - if (c == '\n') { - BUMP(error_info.line); - } - sfputc(ex->tmp, c); - } - ex->input->nesting--; - s = sfstruse(ex->tmp); - if (q == '"' || (ex->disc->flags & EX_CHARSTRING)) { - if (!(exlval.string = vmstrdup(ex->vm, s))) - goto eof; - stresc(exlval.string); - return STRING; - } - exlval.integer = chrtoi(s); - return INTEGER; - case '.': - if (isdigit(c = lex(ex))) { - sfstrset(ex->tmp, 0); - sfputc(ex->tmp, '0'); - sfputc(ex->tmp, '.'); - goto floating; - } - exunlex(ex, c); - return exlval.op = '.'; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - sfstrset(ex->tmp, 0); - sfputc(ex->tmp, c); - q = INTEGER; - if ((c = lex(ex)) == 'x' || c == 'X') { - sfputc(ex->tmp, c); - for (;;) { - switch (c = lex(ex)) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - sfputc(ex->tmp, c); - continue; - } - break; - } - } else { - while (isdigit(c)) { - sfputc(ex->tmp, c); - c = lex(ex); - } - if (c == '#') { - sfputc(ex->tmp, c); - /* s = sfstruse(ex->tmp); */ - /* b = strtol(s, NiL, 10); */ - do { - sfputc(ex->tmp, c); - } while (isalnum(c = lex(ex))); - } else { - if (c == '.') { - floating: - q = FLOATING; - sfputc(ex->tmp, c); - while (isdigit(c = lex(ex))) - sfputc(ex->tmp, c); - } - if (c == 'e' || c == 'E') { - q = FLOATING; + else exunlex(ex, q); + return exlval.op = c; + case '#': + if (!ex->linewrap && !(ex->disc->flags & EX_PURE)) + { + s = ex->linep - 1; + while (s > ex->line && isspace(*(s - 1))) + s--; + if (s == ex->line) + { + switch (extoken_fn(ex)) + { + case DYNAMIC: + case ID: + case NAME: + s = exlval.id->name; + break; + default: + s = ""; + break; + } + if (streq(s, "include")) + { + if (extoken_fn(ex) != STRING) + exerror("#%s: string argument expected", s); + else if (!expush(ex, exlval.string, 1, NiL, NiL)) + { + setcontext(ex); + goto again; + } + } + else exerror("unknown directive"); + } + } + return exlval.op = c; + case '\'': + case '"': + q = c; + sfstrseek(ex->tmp, 0, SEEK_SET); + ex->input->nesting++; + while ((c = lex(ex)) != q) + { + if (c == '\\') + { + sfputc(ex->tmp, c); + c = lex(ex); + } + if (!c) + { + exerror("unterminated %c string", q); + goto eof; + } + if (c == '\n') + { + if (error_info.line) + error_info.line++; + else error_info.line = 2; + } + sfputc(ex->tmp, c); + } + ex->input->nesting--; + s = exstash(ex->tmp, NiL); + if (q == '"' || (ex->disc->flags & EX_CHARSTRING)) + { + if (!(exlval.string = vmstrdup(ex->vm, s))) + goto eof; + stresc(exlval.string); + return STRING; + } + exlval.integer = chrtoi(s); + return INTEGER; + case '.': + if (isdigit(c = lex(ex))) + { + sfstrseek(ex->tmp, 0, SEEK_SET); + sfputc(ex->tmp, '0'); + sfputc(ex->tmp, '.'); + goto floating; + } + exunlex(ex, c); + return exlval.op = '.'; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + sfstrseek(ex->tmp, 0, SEEK_SET); sfputc(ex->tmp, c); - if ((c = lex(ex)) == '-' || c == '+') { - sfputc(ex->tmp, c); - c = lex(ex); + q = INTEGER; + b = 0; + if ((c = lex(ex)) == 'x' || c == 'X') + { + b = 16; + sfputc(ex->tmp, c); + for (;;) + { + switch (c = lex(ex)) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + sfputc(ex->tmp, c); + continue; + } + break; + } } - while (isdigit(c)) { - sfputc(ex->tmp, c); - c = lex(ex); + else + { + while (isdigit(c)) + { + sfputc(ex->tmp, c); + c = lex(ex); + } + if (c == '#') + { + sfputc(ex->tmp, c); + /* s = exstash(ex->tmp, NiL); */ + /* b = strtol(s, NiL, 10); */ + do + { + sfputc(ex->tmp, c); + } while (isalnum(c = lex(ex))); + } + else + { + if (c == '.') + { + floating: + q = FLOATING; + sfputc(ex->tmp, c); + while (isdigit(c = lex(ex))) + sfputc(ex->tmp, c); + } + if (c == 'e' || c == 'E') + { + q = FLOATING; + sfputc(ex->tmp, c); + if ((c = lex(ex)) == '-' || c == '+') + { + sfputc(ex->tmp, c); + c = lex(ex); + } + while (isdigit(c)) + { + sfputc(ex->tmp, c); + c = lex(ex); + } + } + } } - } - } - } - s = sfstruse(ex->tmp); - if (q == FLOATING) - exlval.floating = strtod(s, &e); - else { - if (c == 'u' || c == 'U') { - q = UNSIGNED; - c = lex(ex); - exlval.integer = strToL(s, &e); - } else - exlval.integer = strToL(s, &e); - if (*e) { - *--e = 1; - exlval.integer *= strton(e, &e, NiL, 0); - } - } - exunlex(ex, c); - if (*e || isalpha(c) || c == '_' || c == '$') { - exerror("%s: invalid numeric constant", s); - goto eof; - } - return q; - default: - if (isalpha(c) || c == '_' || c == '$') { - sfstrset(ex->tmp, 0); - sfputc(ex->tmp, c); - while (isalnum(c = lex(ex)) || c == '_' || c == '$') - sfputc(ex->tmp, c); - exunlex(ex, c); - s = sfstruse(ex->tmp); - if (!(exlval.id = (Exid_t *) dtmatch(ex->symbols, s))) { - if (! - (exlval.id = - newof(0, Exid_t, 1, - strlen(s) - EX_NAMELEN + 1))) { - exerror("out of space"); - goto eof; - } - strcpy(exlval.id->name, s); - exlval.id->lex = NAME; - dtinsert((ex->formals - || !ex->symbols->view) ? ex->symbols : ex-> - symbols->view, exlval.id); - } - - /* - * lexical analyzer state controlled by the grammar - */ - - switch (exlval.id->lex) { - case DECLARE: - if (exlval.id->index == CHARACTER) { - /* - * `char*' === `string' - * the * must immediately follow char - */ - - if (c == '*') { - lex(ex); - exlval.id = id_string; + s = exstash(ex->tmp, NiL); + if (q == FLOATING) + exlval.floating = strtod(s, &e); + else + { + if (c == 'u' || c == 'U') + { + q = UNSIGNED; + c = lex(ex); + exlval.integer = strtoull(s, &e, b); + } + else + exlval.integer = strtoll(s, &e, b); + if (*e) + { + *--e = 1; + exlval.integer *= strton(e, &e, NiL, 0); + } } - } - break; - case NAME: - /* - * action labels are disambiguated from ?: - * through the expr.nolabel grammar hook - * the : must immediately follow labels - */ - - if (c == ':' && !expr.nolabel) - return LABEL; - break; - case PRAGMA: - /* - * user specific statement stripped and - * passed as string - */ - - { - int b; - int n; - int pc = 0; - int po; - int t; - - /*UNDENT... */ - sfstrset(ex->tmp, 0); - b = 1; - n = 0; - po = 0; - t = 0; - for (c = t = lex(ex);; c = lex(ex)) { - switch (c) { - case 0: + exunlex(ex, c); + if (*e || isalpha(c) || c == '_' || c == '$') + { + exerror("%s: invalid numeric constant", s); goto eof; - case '/': - switch (q = lex(ex)) { - case '*': - for (;;) { - switch (lex(ex)) { - case '\n': - BUMP(error_info.line); - continue; - case '*': - switch (lex(ex)) { - case 0: + } + return q; + default: + if (isalpha(c) || c == '_' || c == '$') + { + sfstrseek(ex->tmp, 0, SEEK_SET); + sfputc(ex->tmp, c); + while (isalnum(c = lex(ex)) || c == '_' || c == '$') + sfputc(ex->tmp, c); + exunlex(ex, c); + s = exstash(ex->tmp, NiL); + v = expr.declare ? dtview(ex->symbols, NiL) : (Dt_t*)0; + exlval.id = (Exid_t*)dtmatch(ex->symbols, s); + if (v) + dtview(ex->symbols, v); + if (!exlval.id) + { + if (!(exlval.id = newof(0, Exid_t, 1, strlen(s) - EX_NAMELEN + 1))) + { + exnospace(); goto eof; - case '\n': - BUMP(error_info.line); - continue; - case '*': - exunlex(ex, '*'); - continue; - case '/': + } + strcpy(exlval.id->name, s); + exlval.id->lex = NAME; + expr.statics += exlval.id->isstatic = expr.instatic; + + /* + * LABELs are in the parent scope! + */ + + if (c == ':' && !expr.nolabel && ex->frame && ex->frame->view) + dtinsert(ex->frame->view, exlval.id); + else + dtinsert(ex->symbols, exlval.id); + } + + /* + * lexical analyzer state controlled by the grammar + */ + + switch (exlval.id->lex) + { + case DECLARE: + if (exlval.id->index == CHARACTER) + { + /* + * `char*' === `string' + * the * must immediately follow char + */ + + if (c == '*') + { + lex(ex); + exlval.id = id_string; + } + } + break; + case NAME: + /* + * action labels are disambiguated from ?: + * through the expr.nolabel grammar hook + * the : must immediately follow labels + */ + + if (c == ':' && !expr.nolabel) + return LABEL; + break; + case PRAGMA: + /* + * user specific statement stripped and + * passed as string + */ + + { + int b; + int n; + int pc; + int po; + int t; + + /*UNDENT...*/ + sfstrseek(ex->tmp, 0, SEEK_SET); + b = 1; + n = 0; + po = 0; + t = 0; + for (c = t = lex(ex);; c = lex(ex)) + { + switch (c) + { + case 0: + goto eof; + case '/': + switch (q = lex(ex)) + { + case '*': + for (;;) + { + switch (lex(ex)) + { + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; + continue; + case '*': + switch (lex(ex)) + { + case 0: + goto eof; + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; + continue; + case '*': + exunlex(ex, '*'); + continue; + case '/': + break; + default: + continue; + } + break; + } + if (!b++) + goto eof; + sfputc(ex->tmp, ' '); break; - default: - continue; - } - break; } - if (!b++) - goto eof; - sfputc(ex->tmp, ' '); break; - } - break; case '/': - while ((c = lex(ex)) != '\n') - if (!c) - goto eof; - BUMP(error_info.line); - b = 1; - sfputc(ex->tmp, '\n'); - break; + while ((c = lex(ex)) != '\n') + if (!c) + goto eof; + if (error_info.line) + error_info.line++; + else error_info.line = 2; + b = 1; + sfputc(ex->tmp, '\n'); + break; default: - b = 0; - sfputc(ex->tmp, c); - sfputc(ex->tmp, q); - break; + b = 0; + sfputc(ex->tmp, c); + sfputc(ex->tmp, q); + break; } continue; - case '\n': - BUMP(error_info.line); + case '\n': + if (error_info.line) + error_info.line++; + else error_info.line = 2; b = 1; sfputc(ex->tmp, '\n'); continue; - case ' ': - case '\t': + case ' ': + case '\t': if (!b++) - goto eof; + goto eof; sfputc(ex->tmp, ' '); continue; - case '(': - case '{': - case '[': + case '(': + case '{': + case '[': b = 0; - if (!po) { - switch (po = c) { - case '(': - pc = ')'; - break; - case '{': - pc = '}'; - break; - case '[': - pc = ']'; - break; - } - n++; - } else if (c == po) - n++; + if (!po) + { + switch (po = c) + { + case '(': + pc = ')'; + break; + case '{': + pc = '}'; + break; + case '[': + pc = ']'; + break; + } + n++; + } + else if (c == po) + n++; sfputc(ex->tmp, c); continue; - case ')': - case '}': - case ']': + case ')': + case '}': + case ']': b = 0; - if (!po) { - exunlex(ex, c); - break; + if (!po) + { + exunlex(ex, c); + break; } sfputc(ex->tmp, c); - if (c == pc && --n <= 0) { - if (t == po) - break; - po = 0; + if (c == pc && --n <= 0) + { + if (t == po) + break; + po = 0; } continue; - case ';': + case ';': b = 0; if (!n) - break; + break; sfputc(ex->tmp, c); continue; - case '\'': - case '"': + case '\'': + case '"': b = 0; sfputc(ex->tmp, c); ex->input->nesting++; q = c; - while ((c = lex(ex)) != q) { - if (c == '\\') { + while ((c = lex(ex)) != q) + { + if (c == '\\') + { + sfputc(ex->tmp, c); + c = lex(ex); + } + if (!c) + { + exerror("unterminated %c string", q); + goto eof; + } + if (c == '\n') + { + if (error_info.line) + error_info.line++; + else error_info.line = 2; + } sfputc(ex->tmp, c); - c = lex(ex); - } - if (!c) { - exerror("unterminated %c string", - q); - goto eof; - } - if (c == '\n') { - BUMP(error_info.line); - } - sfputc(ex->tmp, c); } ex->input->nesting--; continue; - default: + default: b = 0; sfputc(ex->tmp, c); continue; - } - break; } - (*ex->disc->reff) (ex, NiL, exlval.id, NiL, - sfstruse(ex->tmp), 0, ex->disc); + break; + } + (*ex->disc->reff)(ex, NiL, exlval.id, NiL, exstash(ex->tmp, NiL), 0, ex->disc); - /*..INDENT */ - } - goto again; + /*..INDENT*/ + } + goto again; + } + return exlval.id->lex; + } + return exlval.op = c; } - return exlval.id->lex; - } - return exlval.op = c; - } - eof: - ex->eof = 1; - return exlval.op = ';'; + eof: + ex->eof = 1; + return exlval.op = ';'; } diff --git a/lib/expr/extype.c b/lib/expr/extype.c index f751ed639..5e8f6a651 100644 --- a/lib/expr/extype.c +++ b/lib/expr/extype.c @@ -27,15 +27,17 @@ * return C type name for type */ -char *extype(int type) +char* +extype(int type) { - switch (type) { - case FLOATING: - return "double"; - case STRING: - return "char*"; - case UNSIGNED: - return xstr(unsigned _ast_intmax_t); - } - return xstr(_ast_intmax_t); + switch (type) + { + case FLOATING: + return "double"; + case STRING: + return "char*"; + case UNSIGNED: + return xstr(uintmax_t); + } + return xstr(intmax_t); } diff --git a/lib/expr/exzero.c b/lib/expr/exzero.c index 1aff9085e..9024565d0 100644 --- a/lib/expr/exzero.c +++ b/lib/expr/exzero.c @@ -24,24 +24,23 @@ * return 0 value for type */ -Extype_t exzero(int type) +Extype_t +exzero(int type) { - Extype_t v; + Extype_t v; - switch (type) { - case FLOATING: - v.floating = 0.0; - break; - case INTEGER: - case UNSIGNED: - v.integer = 0; - break; - case STRING: - v.string = expr.nullstring; - break; - default: - v.integer = 0; - break; - } - return v; + switch (type) + { + case FLOATING: + v.floating = 0.0; + break; + case INTEGER: + case UNSIGNED: + v.integer = 0; + break; + case STRING: + v.string = expr.nullstring; + break; + } + return v; } -- 2.40.0