reverted back to Glenn's format so that future diffs and updates will be easier.
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 \
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
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 <string.h>
#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;
}
/*
*/
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 <ast.h>\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 <ast.h>\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);
}
-/* $Id$ $Revision$ */
/* vim:set shiftwidth=4 ts=8: */
/*************************************************************************
* 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;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* 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 <exlib.h>
-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)
};
-/* $Id$ $Revision$ */
/* vim:set shiftwidth=4 ts=8: */
/*************************************************************************
* 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);
- }
+ }
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
#define drand48 rand
#endif
+#ifdef OLD
+#include <tm.h>
+#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:
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;
}
/*
*/
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;
}
/*
* 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:
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)))
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:
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:
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:
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:
*/
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:
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:
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;
}
/*
*/
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:
*/
char *exstring(Expr_t * ex, char *s)
{
- return vmstrdup(ex->vc, s);
+ return vmstrdup(ex->ve, s);
}
/* exstralloc:
{
return vmfree(ex->ve, p);
}
+
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* 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;
}
/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* 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)
#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;
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,
* 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;
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)
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;
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;
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;
}
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;
}
pr = exnewnode(p, ex->index, 1, ex->type, args, NiL);
return pr;
- }
+}
/* makeVar:
*
* 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;
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)]
#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:
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;
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
("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);
"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
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
#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;
}
#include <align.h>
#include <ast.h>
- 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 */ \
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 */ \
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 */ \
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 <expr.h>
#include <ctype.h>
#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; /* <id>':' 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; /* <id>':' 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
* 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;
}
/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
%{
-
/*
* Glenn Fowler
* AT&T Research
*
* expression library grammar and compiler
- *
- * NOTE: procedure arguments not implemented yet
*/
#ifdef WIN32
%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
%binary <op> EQ NE
%binary <op> '<' '>' LE GE
%left <op> LS RS
-%left <op> '+' '-' IN_OP
+%left <op> '+' '-' IN_OP
%left <op> '*' '/' '%'
%right <op> '!' '~' '#' UNARY
%right <op> INC DEC
-%right <op> CAST
+%right <op> CAST
%left <op> '('
%type <expr> statement statement_list arg_list
%type <id> CONSTANT ARRAY FUNCTION DECLARE
%type <id> EXIT PRINT PRINTF QUERY
%type <id> RAND SRAND
-%type <id> SPRINTF GSUB SUB
+%type <id> SPRINTF PROCEDURE name dcl_name
+%type <id> GSUB SUB SUBSTR
%type <id> SPLIT TOKENS splitop
-%type <id> SUBSTR PROCEDURE name dcl_name
%type <id> IF WHILE FOR ITERATER
%type <id> BREAK CONTINUE print member
%type <id> RETURN DYNAMIC SWITCH UNSET
%type <id> SCANF SSCANF scan
%type <floating> FLOATING
%type <integer> INTEGER UNSIGNED array
+%type <integer> static
%type <string> STRING
%token MAXTOKEN
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;
{
expr.program->symbols = expr.program->frame->view;
dtview(expr.program->frame, NiL);
+ expr.program->frame = 0;
}
if ($4 && $4->op == S2B)
{
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);
+ }
}
;
{
$$ = ($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
{
free(sw->base);
if (sw != &swstate)
free(sw);
+ expr.declare = 0;
}
| BREAK expr_opt ';'
{
{
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;
n = 8;
if (!(sw->base = newof(0, Extype_t*, n, 0)))
{
- exerror("out of space [case]");
+ exnospace();
n = 0;
}
sw->cur = sw->base;
{
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;
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;
}
}
;
}
;
+static : /* empty */
+ {
+ $$ = 0;
+ }
+ | STATIC
+ {
+ $$ = 1;
+ }
+ ;
+
dcl_list : dcl_item
| 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;
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 */
$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);
}
;
-dcl_name : NAME
+dcl_name : NAME
| DYNAMIC
| ID
| FUNCTION
{
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)
$$ = 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);
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
{
{
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;
}
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
{
| 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 ')'
{
$$->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 ')'
$$->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
$$ = 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
{
}
| 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
{
$3->type = $1->type;
$3->value = exnewnode(expr.program, 0, 0, 0, NiL, NiL);
expr.procedure->data.procedure.arity++;
+ expr.declare = 0;
}
;
$$ = expr.refs;
}
| '.' ID member
- {
+ {
Exref_t* r;
Exref_t* l;
expr.refs = l;
expr.lastref = r;
$$ = expr.refs;
- }
+ }
;
member : '.' ID
$$ = $2;
}
;
-
assign : /* empty */
{
$$ = 0;
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;
{
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);
#include <ast.h>
-#undef RS /* hp.pa <signal.h> grabs this!! */
+#undef RS /* hp.pa <signal.h> 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 <exparse.h>
+#if defined(YYSTYPE) || defined(yystype)
+#define EXSTYPE YYSTYPE
+#endif
#endif
#include "exparse.h"
#undef extern
-#include "cdt.h"
-#include "vmalloc.h"
+#include <cdt.h>
+#include <vmalloc.h>
#define EX_VERSION 20000101L
* 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
* 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)-1)
+#define TBITS 4
+#define TMASK ((1<<TBITS)-1)
#define A(n,t) ((t)<<((n)*TBITS)) /* function arg n is type t */
#define N(t) ((t)>>=TBITS) /* shift for next arg */
#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
#include "exlib.h"
#include <string.h>
-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);
}
/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+/* vim:set shiftwidth=4 ts=4: */
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
#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
#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 = ';';
}
* 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);
}
* 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;
}