21 static int next_token(
void);
22 static int chk_funcs(
void);
23 static void skip_double(
void);
24 static int compile(
int prec);
25 static int execute(
double *result);
26 static int parse_fieldname(
char name[],
int len);
83 static int precedence[] = { 0, 5, 5, 6, 6, 2, 1, 4, 4, 3, 3, 4, 4 };
120 static int parens_nest;
121 static char *err_msg;
122 static char *cexpr, *lcexpr;
139 if (compile(0) ==
ERR)
141 (void)sprintf(err_msg + strlen(err_msg),
" near `%.10s'", lcexpr);
146 (void)sprintf(err_msg,
"Null program");
162 return (execute(vp));
172 for (i = 0; i < nvars; i++)
174 if (strcmp(name, vars[i].name) == 0)
190 for (i = 0; i < nvars; i++)
203 *ops = (
char **)malloc(nvars *
sizeof(
char *));
205 for (i = 0; i < nvars; i++)
206 (*ops)[i] = vars[i].
name;
218 *ops = (
char **)malloc(nvars *
sizeof(
char *));
220 for (n = i = 0; i < nvars; i++)
222 (*ops)[n++] = vars[i].
name;
234 *ops = (
char **)malloc(nvars *
sizeof(
char *));
236 for (n = i = 0; i < nvars; i++)
238 (*ops)[n++] = vars[i].
name;
251 for (
Var *vp = vars; vp < &vars[nvars]; vp++)
252 if (strcmp(vp->name, name) == 0)
260 static int next_token()
262 static const char toomv[] =
"More than %d variables";
263 static const char toomc[] =
"More than %d constants";
264 static const char badop[] =
"Illegal operator";
268 while (isspace(c = *cexpr))
299 if (--parens_nest < 0)
301 (void)sprintf(err_msg,
"Too many right parens");
315 (void)strcpy(err_msg, badop);
327 (void)strcpy(err_msg, badop);
339 (void)strcpy(err_msg, badop);
378 if (isdigit(c) || c ==
'.')
385 (void)sprintf(err_msg, toomc,
MAX_OPX);
388 consts[nconsts] = atof(lcexpr);
398 (void)sprintf(err_msg,
"Bad function");
407 (void)sprintf(err_msg, toomv,
MAX_OPX);
410 if (parse_fieldname(vars[nvars].name,
MAXFLDLEN) < 0)
412 (void)sprintf(err_msg,
"Bad field");
423 (void)sprintf(err_msg,
"Syntax error");
430 static int chk_funcs()
440 {
"abs",
ABS }, {
"floor",
FLOOR }, {
"acos",
ACOS }, {
"asin",
ASIN }, {
"atan2",
ATAN2 },
441 {
"atan",
ATAN }, {
"cos",
COS }, {
"degrad",
DEGRAD }, {
"exp",
EXP }, {
"log10",
LOG10 },
442 {
"log",
LOG }, {
"pi",
PITOK }, {
"pow",
POW }, {
"raddeg",
RADDEG }, {
"sin",
SIN },
443 {
"sqrt",
SQRT }, {
"tan",
TAN },
445 for (
int i = 0; i < (int)(
sizeof(symtab) /
sizeof(symtab[0])); i++)
447 int l = strlen(symtab[i].st_name);
449 if (strncmp(lcexpr, symtab[i].st_name, l) == 0)
452 return (symtab[i].st_tok);
465 static void skip_double()
472 if (isdigit(c) || c ==
'.' || (sawe && (c ==
'-' || c ==
'+')))
493 static int compile(prec)
int prec;
495 int expect_binop = 0;
499 int tok = next_token();
509 (void)sprintf(err_msg,
"Program is too long");
527 (void)sprintf(err_msg,
"Term expected after unary +");
538 (void)sprintf(err_msg,
"Term expected after unary -");
549 (void)sprintf(err_msg,
"Term expected after unary !");
571 if (next_token() !=
LPAREN)
573 (void)sprintf(err_msg,
"expecting '(' after function");
577 if (compile(0) !=
RPAREN || oldpc == pc)
579 (void)sprintf(err_msg,
"1-arg function arglist error");
590 if (next_token() !=
LPAREN)
592 (void)sprintf(err_msg,
"Saw a built-in function: expecting (");
596 if (compile(0) !=
COMMA || oldpc == pc)
598 (void)sprintf(err_msg,
"1st of 2-arg function arglist error");
602 if (compile(0) !=
RPAREN || oldpc == pc)
604 (void)sprintf(err_msg,
"2nd of 2-arg function arglist error");
623 (void)sprintf(err_msg,
"Unmatched left paren");
628 (void)sprintf(err_msg,
"Null expression");
639 if (tok < ADD || tok >
LE)
641 printf(
"Bug! Bogus token: %d\n", tok);
654 (void)strcpy(err_msg,
"Term or factor expected");
670 static int execute(result)
double *result;
685 sp[1] = sp[1] + sp[0];
689 sp[1] = sp[1] - sp[0];
693 sp[1] = sp[1] * sp[0];
697 sp[1] = sp[1] / sp[0];
701 sp[1] = sp[1] && sp[0] ? 1 : 0;
705 sp[1] = sp[1] || sp[0] ? 1 : 0;
709 sp[1] = sp[1] > sp[0] ? 1 : 0;
713 sp[1] = sp[1] >= sp[0] ? 1 : 0;
717 sp[1] = sp[1] == sp[0] ? 1 : 0;
721 sp[1] = sp[1] != sp[0] ? 1 : 0;
725 sp[1] = sp[1] < sp[0] ? 1 : 0;
729 sp[1] = sp[1] <= sp[0] ? 1 : 0;
736 *sp = (double)(*sp == 0);
745 *--sp = 4.0 * atan(1.0);
772 *sp *= atan(1.0) / 45.0;
775 *sp *= 45.0 / atan(1.0);
790 sp[1] = pow(sp[1], sp[0]);
794 sp[1] = atan2(sp[1], sp[0]);
798 (void)sprintf(err_msg,
"Bug! bad opcode: 0x%x", instr);
803 (void)sprintf(err_msg,
"Runtime stack overflow");
808 (void)sprintf(err_msg,
"Bug! runtime stack underflow");
811 }
while (instr !=
HALT);
816 (void)sprintf(err_msg,
"Bug! stack has %ld items", (
long int)(
MAX_STACK - (sp - stack)));
829 static int parse_fieldname(name, len)
char name[];
836 while (--len > 0 && (c = *cexpr++) !=
'"' && c)
841 if (len == 0 || c !=
'"' || ndots != 2)
int getAllOperands(char ***ops)
int evalExpr(double *vp, char *errbuf)
int compileExpr(char *exp, char *errbuf)
int getSetOperands(char ***ops)
int getUnsetOperands(char ***ops)
void compiler_log(char *name, double value)
int setOperand(char *name, double valu)