Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libexpr/exeval.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1989-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* expression library evaluator
26
*/
27
28
#include "exlib.h"
29
#include "exop.h"
30
31
#include <tm.h>
32
33
static Extype_t eval(Expr_t*, Exnode_t*, void*);
34
35
#define TOTNAME 4
36
#define MAXNAME 16
37
#define FRAME 64
38
39
static char*
40
lexname(int op, int subop)
41
{
42
register char* b;
43
44
static int n;
45
static char buf[TOTNAME][MAXNAME];
46
47
if (op > MINTOKEN && op < MAXTOKEN)
48
return (char*)exop[op - MINTOKEN];
49
if (++n >= TOTNAME)
50
n = 0;
51
b = buf[n];
52
if (op == '=')
53
{
54
if (subop > MINTOKEN && subop < MAXTOKEN)
55
sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]);
56
else if (subop > ' ' && subop <= '~')
57
sfsprintf(b, MAXNAME, "%c=", subop);
58
else
59
sfsprintf(b, MAXNAME, "(%d)=", subop);
60
}
61
else if (subop < 0)
62
sfsprintf(b, MAXNAME, "(EXTERNAL:%d)", op);
63
else if (op > ' ' && op <= '~')
64
sfsprintf(b, MAXNAME, "%c", op);
65
else
66
sfsprintf(b, MAXNAME, "(%d)", op);
67
return b;
68
}
69
70
/*
71
* return dynamic (associative array) variable value
72
* assoc will point to the associative array bucket
73
*/
74
75
static Extype_t
76
getdyn(Expr_t* ex, register Exnode_t* expr, void* env, Exassoc_t** assoc)
77
{
78
Exassoc_t* b;
79
Extype_t v;
80
81
if (expr->data.variable.index)
82
{
83
char buf[9];
84
85
v = eval(ex, expr->data.variable.index, env);
86
if (expr->data.variable.index->type != STRING)
87
{
88
sfsprintf(buf, sizeof(buf), "%I*x", sizeof(v.integer), v.integer);
89
v.string = buf;
90
}
91
if (!(b = (Exassoc_t*)dtmatch((Dt_t*)expr->data.variable.symbol->local.pointer, v.string)))
92
{
93
if (!(b = newof(0, Exassoc_t, 1, strlen(v.string))))
94
exnospace();
95
strcpy(b->name, v.string);
96
dtinsert((Dt_t*)expr->data.variable.symbol->local.pointer, b);
97
}
98
*assoc = b;
99
if (b)
100
{
101
if (expr->data.variable.symbol->type == STRING && !b->value.string)
102
b->value = exzero(expr->data.variable.symbol->type);
103
return b->value;
104
}
105
v = exzero(expr->data.variable.symbol->type);
106
return v;
107
}
108
*assoc = 0;
109
return expr->data.variable.symbol->value->data.constant.value;
110
}
111
112
typedef struct
113
{
114
Sffmt_t fmt;
115
Expr_t* expr;
116
void* env;
117
Print_t* args;
118
Extype_t value;
119
Exnode_t* actuals;
120
Sfio_t* tmp;
121
} Fmt_t;
122
123
/*
124
* printf %! extension function
125
*/
126
127
static int
128
prformat(Sfio_t* sp, void* vp, Sffmt_t* dp)
129
{
130
register Fmt_t* fmt = (Fmt_t*)dp;
131
register Exnode_t* node;
132
register char* s;
133
register char* txt;
134
int n;
135
int from;
136
int to;
137
time_t tm;
138
139
dp->flags |= SFFMT_VALUE;
140
if (fmt->args)
141
{
142
if (node = (dp->fmt == '*') ? fmt->args->param[dp->size] : fmt->args->arg)
143
fmt->value = exeval(fmt->expr, node, fmt->env);
144
else
145
fmt->value.integer = 0;
146
to = fmt->args->arg->type;
147
}
148
else if (!(fmt->actuals = fmt->actuals->data.operand.right))
149
exerror("printf: not enough arguments");
150
else
151
{
152
node = fmt->actuals->data.operand.left;
153
from = node->type;
154
switch (dp->fmt)
155
{
156
case 'f':
157
case 'g':
158
to = FLOATING;
159
break;
160
case 's':
161
case '[':
162
to = STRING;
163
break;
164
default:
165
switch (from)
166
{
167
case INTEGER:
168
case UNSIGNED:
169
to = from;
170
break;
171
default:
172
to = INTEGER;
173
break;
174
}
175
break;
176
}
177
if (to == from)
178
fmt->value = exeval(fmt->expr, node, fmt->env);
179
else
180
{
181
node = excast(fmt->expr, node, to, NiL, 0);
182
fmt->value = exeval(fmt->expr, node, fmt->env);
183
node->data.operand.left = 0;
184
exfree(fmt->expr, node);
185
if (to == STRING)
186
{
187
if (fmt->value.string)
188
{
189
n = strlen(fmt->value.string);
190
if (s = fmtbuf(n + 1))
191
memcpy(s, fmt->value.string, n + 1);
192
vmfree(fmt->expr->vm, fmt->value.string);
193
fmt->value.string = s;
194
}
195
if (!fmt->value.string)
196
fmt->value.string = "";
197
}
198
}
199
}
200
switch (to)
201
{
202
case STRING:
203
*((char**)vp) = fmt->value.string;
204
fmt->fmt.size = -1;
205
break;
206
case FLOATING:
207
*((double*)vp) = fmt->value.floating;
208
fmt->fmt.size = sizeof(double);
209
break;
210
default:
211
*((Sflong_t*)vp) = fmt->value.integer;
212
dp->size = sizeof(Sflong_t);
213
break;
214
}
215
if (dp->n_str > 0)
216
{
217
if (!fmt->tmp && !(fmt->tmp = sfstropen()))
218
txt = exnospace();
219
else
220
{
221
sfprintf(fmt->tmp, "%.*s", dp->n_str, dp->t_str);
222
txt = exstash(fmt->tmp, NiL);
223
}
224
}
225
else
226
txt = 0;
227
switch (dp->fmt)
228
{
229
case 'q':
230
case 'Q':
231
s = *((char**)vp);
232
*((char**)vp) = fmtquote(s, "$'", "'", strlen(s), 0);
233
dp->fmt = 's';
234
dp->size = -1;
235
break;
236
case 'S':
237
dp->flags &= ~SFFMT_LONG;
238
s = *((char**)vp);
239
if (txt)
240
{
241
if (streq(txt, "identifier"))
242
{
243
if (*s && !isalpha(*s))
244
*s++ = '_';
245
for (; *s; s++)
246
if (!isalnum(*s))
247
*s = '_';
248
}
249
else if (streq(txt, "invert"))
250
{
251
for (; *s; s++)
252
if (isupper(*s))
253
*s = tolower(*s);
254
else if (islower(*s))
255
*s = toupper(*s);
256
}
257
else if (streq(txt, "lower"))
258
{
259
for (; *s; s++)
260
if (isupper(*s))
261
*s = tolower(*s);
262
}
263
else if (streq(txt, "upper"))
264
{
265
for (; *s; s++)
266
if (islower(*s))
267
*s = toupper(*s);
268
}
269
else if (streq(txt, "variable"))
270
{
271
for (; *s; s++)
272
if (!isalnum(*s) && *s != '_')
273
*s = '.';
274
}
275
}
276
dp->fmt = 's';
277
dp->size = -1;
278
break;
279
case 't':
280
case 'T':
281
if ((tm = *((Sflong_t*)vp)) == -1)
282
tm = time(NiL);
283
*((char**)vp) = fmttime(txt ? txt : "%?%K", tm);
284
dp->fmt = 's';
285
dp->size = -1;
286
break;
287
}
288
return 0;
289
}
290
291
/*
292
* do printf
293
*/
294
295
static int
296
print(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp)
297
{
298
register Print_t* x;
299
Extype_t v;
300
Fmt_t fmt;
301
302
if (!sp)
303
{
304
v = eval(ex, expr->data.print.descriptor, env);
305
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)))
306
{
307
exerror("printf: %d: invalid descriptor", v.integer);
308
return 0;
309
}
310
}
311
memset(&fmt, 0, sizeof(fmt));
312
fmt.fmt.version = SFIO_VERSION;
313
fmt.fmt.extf = prformat;
314
fmt.expr = ex;
315
fmt.env = env;
316
x = expr->data.print.args;
317
if (x->format)
318
do
319
{
320
if (x->arg)
321
{
322
fmt.fmt.form = x->format;
323
fmt.args = x;
324
sfprintf(sp, "%!", &fmt);
325
}
326
else
327
sfputr(sp, x->format, -1);
328
} while (x = x->next);
329
else
330
{
331
v = eval(ex, x->arg->data.operand.left, env);
332
fmt.fmt.form = v.string;
333
fmt.actuals = x->arg;
334
sfprintf(sp, "%!", &fmt);
335
if (fmt.actuals->data.operand.right)
336
exerror("printf: \"%s\": too many arguments", fmt.fmt.form);
337
}
338
if (fmt.tmp)
339
sfstrclose(fmt.tmp);
340
return 1;
341
}
342
343
/*
344
* scanf %! extension function
345
*/
346
347
static int
348
scformat(Sfio_t* sp, void* vp, Sffmt_t* dp)
349
{
350
register Fmt_t* fmt = (Fmt_t*)dp;
351
register Exnode_t* node;
352
353
if (!fmt->actuals)
354
{
355
exerror("scanf: not enough arguments");
356
return -1;
357
}
358
node = fmt->actuals->data.operand.left;
359
switch (dp->fmt)
360
{
361
case 'f':
362
case 'g':
363
if (node->type != FLOATING)
364
{
365
exerror("scanf: %s: floating variable address argument expected", node->data.variable.symbol->name);
366
return -1;
367
}
368
fmt->fmt.size = sizeof(double);
369
*((void**)vp) = &node->data.variable.symbol->value->data.constant.value;
370
break;
371
case 's':
372
if (node->type != STRING)
373
{
374
exerror("scanf: %s: string variable address argument expected", node->data.variable.symbol->name);
375
return -1;
376
}
377
if (node->data.variable.symbol->value->data.constant.value.string == expr.nullstring)
378
node->data.variable.symbol->value->data.constant.value.string = 0;
379
fmt->fmt.size = 1024;
380
*((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);
381
break;
382
default:
383
if (node->type != INTEGER && node->type != UNSIGNED)
384
{
385
exerror("scanf: %s: integer variable address argument expected", node->data.variable.symbol->name);
386
return -1;
387
}
388
dp->size = sizeof(Sflong_t);
389
*((void**)vp) = &node->data.variable.symbol->value->data.constant.value;
390
break;
391
}
392
fmt->actuals = fmt->actuals->data.operand.right;
393
dp->flags |= SFFMT_VALUE;
394
return 0;
395
}
396
397
/*
398
* do scanf
399
*/
400
401
static int
402
scan(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp)
403
{
404
Extype_t v;
405
Extype_t u;
406
Fmt_t fmt;
407
int n;
408
409
if (!sp)
410
{
411
if (expr->data.scan.descriptor)
412
{
413
v = eval(ex, expr->data.scan.descriptor, env);
414
if (expr->data.scan.descriptor->type == STRING)
415
goto get;
416
}
417
else
418
v.integer = 0;
419
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)))
420
{
421
exerror("scanf: %d: invalid descriptor", v.integer);
422
return 0;
423
}
424
}
425
get:
426
memset(&fmt, 0, sizeof(fmt));
427
fmt.fmt.version = SFIO_VERSION;
428
fmt.fmt.extf = scformat;
429
fmt.expr = ex;
430
fmt.env = env;
431
u = eval(ex, expr->data.scan.format, env);
432
fmt.fmt.form = u.string;
433
fmt.actuals = expr->data.scan.args;
434
n = sp ? sfscanf(sp, "%!", &fmt) : sfsscanf(v.string, "%!", &fmt);
435
if (fmt.actuals && !*fmt.fmt.form)
436
exerror("scanf: %s: too many arguments", fmt.actuals->data.operand.left->data.variable.symbol->name);
437
return n;
438
}
439
440
/*
441
* string add
442
*/
443
444
static char*
445
str_add(Expr_t* ex, register char* l, register char* r)
446
{
447
sfprintf(ex->tmp, "%s%s", l, r);
448
return exstash(ex->tmp, ex->ve);
449
}
450
451
/*
452
* string ior
453
*/
454
455
static char*
456
str_ior(Expr_t* ex, register char* l, register char* r)
457
{
458
register int c;
459
register char* s = l;
460
461
while (c = *s++)
462
if (!strchr(s, c))
463
sfputc(ex->tmp, c);
464
while (c = *r++)
465
if (!strchr(l, c) && !strchr(r, c))
466
sfputc(ex->tmp, c);
467
return exstash(ex->tmp, ex->ve);
468
}
469
470
/*
471
* string and
472
*/
473
474
static char*
475
str_and(Expr_t* ex, register char* l, register char* r)
476
{
477
register int c;
478
479
while (c = *l++)
480
if (strchr(r, c) && !strchr(l, c))
481
sfputc(ex->tmp, c);
482
return exstash(ex->tmp, ex->ve);
483
}
484
485
/*
486
* string xor
487
*/
488
489
static char*
490
str_xor(Expr_t* ex, register char* l, register char* r)
491
{
492
register int c;
493
register char* s = l;
494
495
while (c = *s++)
496
if (!strchr(r, c) && !strchr(s, c))
497
sfputc(ex->tmp, c);
498
while (c = *r++)
499
if (!strchr(l, c) && !strchr(r, c))
500
sfputc(ex->tmp, c);
501
return exstash(ex->tmp, ex->ve);
502
}
503
504
/*
505
* string mod
506
*/
507
508
static char*
509
str_mod(Expr_t* ex, register char* l, register char* r)
510
{
511
register int c;
512
513
while (c = *l++)
514
if (!strchr(r, c) && !strchr(l, c))
515
sfputc(ex->tmp, c);
516
return exstash(ex->tmp, ex->ve);
517
}
518
519
/*
520
* string mpy
521
*/
522
523
static char*
524
str_mpy(Expr_t* ex, register char* l, register char* r)
525
{
526
register int lc;
527
register int rc;
528
529
while ((lc = *l++) && (rc = *r++))
530
sfputc(ex->tmp, lc == rc ? lc : ' ');
531
return exstash(ex->tmp, ex->ve);
532
}
533
534
/*
535
* internal exeval
536
*/
537
538
static Extype_t
539
eval(Expr_t* ex, register Exnode_t* expr, void* env)
540
{
541
register Exnode_t* x;
542
register Exnode_t* a;
543
register Extype_t** t;
544
register int n;
545
Extype_t v;
546
Extype_t r;
547
Extype_t i;
548
char* e;
549
Exnode_t tmp;
550
Exassoc_t* assoc;
551
Extype_t args[FRAME+1];
552
Extype_t save[FRAME];
553
554
if (!expr || ex->loopcount)
555
{
556
v.integer = 1;
557
return v;
558
}
559
x = expr->data.operand.left;
560
switch (expr->op)
561
{
562
case BREAK:
563
case CONTINUE:
564
v = eval(ex, x, env);
565
ex->loopcount = v.integer;
566
ex->loopop = expr->op;
567
return v;
568
case CONSTANT:
569
return expr->data.constant.value;
570
case DEC:
571
n = -1;
572
add:
573
if (x->op == DYNAMIC)
574
r = getdyn(ex, x, env, &assoc);
575
else
576
{
577
if (x->data.variable.index)
578
i = eval(ex, x->data.variable.index, env);
579
else
580
i.integer = EX_SCALAR;
581
r = (*ex->disc->getf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)i.integer, ex->disc);
582
}
583
v = r;
584
switch (x->type)
585
{
586
case FLOATING:
587
v.floating += n;
588
break;
589
case INTEGER:
590
case UNSIGNED:
591
v.integer += n;
592
break;
593
default:
594
goto huh;
595
}
596
set:
597
if (x->op == DYNAMIC)
598
{
599
if (x->type == STRING)
600
{
601
v.string = vmstrdup(ex->vm, v.string);
602
if (e = assoc ? assoc->value.string : x->data.variable.symbol->value->data.constant.value.string)
603
vmfree(ex->vm, e);
604
}
605
if (assoc)
606
assoc->value = v;
607
else
608
x->data.variable.symbol->value->data.constant.value = v;
609
}
610
else
611
{
612
if (x->data.variable.index)
613
i = eval(ex, x->data.variable.index, env);
614
else
615
i.integer = EX_SCALAR;
616
if ((*ex->disc->setf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)i.integer, v, ex->disc) < 0)
617
exerror("%s: cannot set value", x->data.variable.symbol->name);
618
}
619
if (expr->subop == PRE)
620
r = v;
621
return r;
622
case DYNAMIC:
623
return getdyn(ex, expr, env, &assoc);
624
case EXIT:
625
v = eval(ex, x, env);
626
exit((int)v.integer);
627
/*NOTREACHED*/
628
v.integer = -1;
629
return v;
630
case IF:
631
v = eval(ex, x, env);
632
if (v.integer)
633
eval(ex, expr->data.operand.right->data.operand.left, env);
634
else
635
eval(ex, expr->data.operand.right->data.operand.right, env);
636
v.integer = 1;
637
return v;
638
case FOR:
639
case WHILE:
640
expr = expr->data.operand.right;
641
for (;;)
642
{
643
r = eval(ex, x, env);
644
if (!r.integer)
645
{
646
v.integer = 1;
647
return v;
648
}
649
if (expr->data.operand.right)
650
{
651
eval(ex, expr->data.operand.right, env);
652
if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE))
653
{
654
v.integer = 0;
655
return v;
656
}
657
}
658
if (expr->data.operand.left)
659
eval(ex, expr->data.operand.left, env);
660
}
661
/*NOTREACHED*/
662
case SWITCH:
663
v = eval(ex, x, env);
664
i.integer = x->type;
665
r.integer = 0;
666
x = expr->data.operand.right;
667
a = x->data.select.statement;
668
n = 0;
669
while (x = x->data.select.next)
670
{
671
if (!(t = x->data.select.constant))
672
n = 1;
673
else
674
for (; *t; t++)
675
{
676
switch ((int)i.integer)
677
{
678
case INTEGER:
679
case UNSIGNED:
680
if ((*t)->integer == v.integer)
681
break;
682
continue;
683
case STRING:
684
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))
685
break;
686
continue;
687
case FLOATING:
688
if ((*t)->floating == v.floating)
689
break;
690
continue;
691
}
692
n = 1;
693
break;
694
}
695
if (n)
696
{
697
if (!x->data.select.statement)
698
{
699
r.integer = 1;
700
break;
701
}
702
r = eval(ex, x->data.select.statement, env);
703
if (ex->loopcount > 0)
704
{
705
ex->loopcount--;
706
break;
707
}
708
}
709
}
710
if (!n && a)
711
{
712
r = eval(ex, a, env);
713
if (ex->loopcount > 0)
714
ex->loopcount--;
715
}
716
return r;
717
case ITERATE:
718
v.integer = 0;
719
if (expr->data.generate.array->op == DYNAMIC)
720
{
721
n = expr->data.generate.index->type == STRING;
722
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))
723
{
724
v.integer++;
725
if (n)
726
expr->data.generate.index->value->data.constant.value.string = assoc->name;
727
else
728
expr->data.generate.index->value->data.constant.value.integer = strtol(assoc->name, NiL, 0);
729
eval(ex, expr->data.generate.statement, env);
730
if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE))
731
{
732
v.integer = 0;
733
break;
734
}
735
}
736
}
737
else
738
{
739
r = (*ex->disc->getf)(ex, expr, expr->data.generate.array->data.variable.symbol, expr->data.generate.array->data.variable.reference, env, 0, ex->disc);
740
for (v.integer = 0; v.integer < r.integer; v.integer++)
741
{
742
expr->data.generate.index->value->data.constant.value.integer = v.integer;
743
eval(ex, expr->data.generate.statement, env);
744
if (ex->loopcount > 0 && (--ex->loopcount > 0 || ex->loopop != CONTINUE))
745
{
746
v.integer = 0;
747
break;
748
}
749
}
750
}
751
return v;
752
case CALL:
753
x = expr->data.call.args;
754
for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && x; a = a->data.operand.right)
755
{
756
if (n < elementsof(args))
757
{
758
save[n] = a->data.operand.left->data.variable.symbol->value->data.constant.value;
759
args[n++] = eval(ex, x->data.operand.left, env);
760
}
761
else
762
a->data.operand.left->data.variable.symbol->value->data.constant.value = eval(ex, x->data.operand.left, env);
763
x = x->data.operand.right;
764
}
765
for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && n < elementsof(save); a = a->data.operand.right)
766
a->data.operand.left->data.variable.symbol->value->data.constant.value = args[n++];
767
if (x)
768
exerror("too many actual args");
769
else if (a)
770
exerror("not enough actual args");
771
v = exeval(ex, expr->data.call.procedure->value->data.procedure.body, env);
772
for (n = 0, a = expr->data.call.procedure->value->data.procedure.args; a && n < elementsof(save); a = a->data.operand.right)
773
a->data.operand.left->data.variable.symbol->value->data.constant.value = save[n++];
774
return v;
775
case FUNCTION:
776
n = 0;
777
args[n++].string = (char*)env;
778
for (x = expr->data.operand.right; x && n < elementsof(args); x = x->data.operand.right)
779
args[n++] = eval(ex, x->data.operand.left, env);
780
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);
781
case ID:
782
if (expr->data.variable.index)
783
i = eval(ex, expr->data.variable.index, env);
784
else
785
i.integer = EX_SCALAR;
786
return (*ex->disc->getf)(ex, expr, expr->data.variable.symbol, expr->data.variable.reference, env, (int)i.integer, ex->disc);
787
case INC:
788
n = 1;
789
goto add;
790
case PRINTF:
791
v.integer = print(ex, expr, env, NiL);
792
return v;
793
case QUERY:
794
print(ex, expr, env, sfstderr);
795
v.integer = !astquery(2, "");
796
return v;
797
case RETURN:
798
ex->loopret = eval(ex, x, env);
799
ex->loopcount = 32767;
800
ex->loopop = expr->op;
801
return ex->loopret;
802
case SCANF:
803
case SSCANF:
804
v.integer = scan(ex, expr, env, NiL);
805
return v;
806
case SPRINTF:
807
print(ex, expr, env, ex->tmp);
808
v.string = exstash(ex->tmp, ex->ve);
809
return v;
810
case '=':
811
v = eval(ex, expr->data.operand.right, env);
812
if (expr->subop != '=')
813
{
814
r = v;
815
if (x->op == DYNAMIC)
816
v = getdyn(ex, x, env, &assoc);
817
else
818
{
819
if (x->data.variable.index)
820
v = eval(ex, x->data.variable.index, env);
821
else
822
v.integer = EX_SCALAR;
823
v = (*ex->disc->getf)(ex, x, x->data.variable.symbol, x->data.variable.reference, env, (int)v.integer, ex->disc);
824
}
825
switch (x->type)
826
{
827
case FLOATING:
828
switch (expr->subop)
829
{
830
case '+':
831
v.floating += r.floating;
832
break;
833
case '-':
834
v.floating -= r.floating;
835
break;
836
case '*':
837
v.floating *= r.floating;
838
break;
839
case '/':
840
if (r.floating == 0.0)
841
exerror("floating divide by 0");
842
else
843
v.floating /= r.floating;
844
break;
845
case '%':
846
if ((r.integer = r.floating) == 0)
847
exerror("floating 0 modulus");
848
else
849
v.floating = ((Sflong_t)v.floating) % r.integer;
850
break;
851
case '&':
852
v.floating = ((Sflong_t)v.floating) & ((Sflong_t)r.floating);
853
break;
854
case '|':
855
v.floating = ((Sflong_t)v.floating) | ((Sflong_t)r.floating);
856
break;
857
case '^':
858
v.floating = ((Sflong_t)v.floating) ^ ((Sflong_t)r.floating);
859
break;
860
case LS:
861
v.floating = ((Sflong_t)v.floating) << ((Sflong_t)r.floating);
862
break;
863
case RS:
864
#if _WIN32
865
v.floating = (Sflong_t)(((Sfulong_t)v.floating) >> ((Sflong_t)r.floating));
866
#else
867
v.floating = ((Sfulong_t)v.floating) >> ((Sflong_t)r.floating);
868
#endif
869
break;
870
default:
871
goto huh;
872
}
873
break;
874
case INTEGER:
875
case UNSIGNED:
876
switch (expr->subop)
877
{
878
case '+':
879
v.integer += r.integer;
880
break;
881
case '-':
882
v.integer -= r.integer;
883
break;
884
case '*':
885
v.integer *= r.integer;
886
break;
887
case '/':
888
if (r.integer == 0)
889
exerror("integer divide by 0");
890
else
891
v.integer /= r.integer;
892
break;
893
case '%':
894
if (r.integer == 0)
895
exerror("integer 0 modulus");
896
else
897
v.integer %= r.integer;
898
break;
899
case '&':
900
v.integer &= r.integer;
901
break;
902
case '|':
903
v.integer |= r.integer;
904
break;
905
case '^':
906
v.integer ^= r.integer;
907
break;
908
case LS:
909
v.integer <<= r.integer;
910
break;
911
case RS:
912
v.integer = (Sfulong_t)v.integer >> r.integer;
913
break;
914
default:
915
goto huh;
916
}
917
break;
918
case STRING:
919
switch (expr->subop)
920
{
921
case '+':
922
v.string = str_add(ex, v.string, r.string);
923
break;
924
case '|':
925
v.string = str_ior(ex, v.string, r.string);
926
break;
927
case '&':
928
v.string = str_and(ex, v.string, r.string);
929
break;
930
case '^':
931
v.string = str_xor(ex, v.string, r.string);
932
break;
933
case '%':
934
v.string = str_mod(ex, v.string, r.string);
935
break;
936
case '*':
937
v.string = str_mpy(ex, v.string, r.string);
938
break;
939
default:
940
goto huh;
941
}
942
break;
943
default:
944
goto huh;
945
}
946
}
947
else if (x->op == DYNAMIC)
948
getdyn(ex, x, env, &assoc);
949
else
950
assoc = 0;
951
r = v;
952
goto set;
953
case ';':
954
case ',':
955
v = eval(ex, x, env);
956
while ((expr = expr->data.operand.right) && (expr->op == ';' || expr->op == ','))
957
{
958
v = eval(ex, expr->data.operand.left, env);
959
if (ex->loopcount)
960
return v;
961
}
962
return expr ? eval(ex, expr, env) : v;
963
case '?':
964
v = eval(ex, x, env);
965
return v.integer ? eval(ex, expr->data.operand.right->data.operand.left, env) : eval(ex, expr->data.operand.right->data.operand.right, env);
966
case AND:
967
v = eval(ex, x, env);
968
return v.integer ? eval(ex, expr->data.operand.right, env) : v;
969
case OR:
970
v = eval(ex, x, env);
971
return v.integer ? v : eval(ex, expr->data.operand.right, env);
972
}
973
v = eval(ex, x, env);
974
if (x = expr->data.operand.right)
975
r = eval(ex, x, env);
976
switch (expr->data.operand.left->type)
977
{
978
case FLOATING:
979
switch (expr->op)
980
{
981
case F2I:
982
v.integer = v.floating;
983
return v;
984
case F2S:
985
tmp = *expr->data.operand.left;
986
tmp.data.constant.value = v;
987
if (expr->data.operand.left->op != DYNAMIC && expr->data.operand.left->op != ID)
988
{
989
sfprintf(ex->tmp, "%g", v.floating);
990
tmp.data.constant.value.string = exstash(ex->tmp, ex->ve);
991
}
992
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))
993
exerror("%s: cannot convert value to string", expr->data.operand.left->data.variable.symbol->name);
994
tmp.type = STRING;
995
return tmp.data.constant.value;
996
case F2X:
997
tmp = *expr->data.operand.left;
998
tmp.data.constant.value = v;
999
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))
1000
exerror("%s: cannot convert floating value to external", tmp.data.variable.symbol->name);
1001
tmp.type = expr->type;
1002
return tmp.data.constant.value;
1003
case '!':
1004
v.floating = !((Sflong_t)v.floating);
1005
return v;
1006
case '~':
1007
v.floating = ~((Sflong_t)v.floating);
1008
return v;
1009
case '-':
1010
if (x)
1011
v.floating -= r.floating;
1012
else
1013
v.floating = -v.floating;
1014
return v;
1015
case '+':
1016
v.floating += r.floating;
1017
return v;
1018
case '&':
1019
v.floating = (Sflong_t)v.floating & (Sflong_t)r.floating;
1020
return v;
1021
case '|':
1022
v.floating = (Sflong_t)v.floating | (Sflong_t)r.floating;
1023
return v;
1024
case '^':
1025
v.floating = (Sflong_t)v.floating ^ (Sflong_t)r.floating;
1026
return v;
1027
case '*':
1028
v.floating *= r.floating;
1029
return v;
1030
case '/':
1031
if (r.floating == 0.0)
1032
exerror("floating divide by 0");
1033
else
1034
v.floating /= r.floating;
1035
return v;
1036
case '%':
1037
if ((r.integer = r.floating) == 0)
1038
exerror("floating 0 modulus");
1039
else
1040
v.floating = (Sflong_t)v.floating % r.integer;
1041
return v;
1042
case '<':
1043
v.integer = v.floating < r.floating;
1044
return v;
1045
case LE:
1046
v.integer = v.floating <= r.floating;
1047
return v;
1048
case EQ:
1049
v.integer = v.floating == r.floating;
1050
return v;
1051
case NE:
1052
v.integer = v.floating != r.floating;
1053
return v;
1054
case GE:
1055
v.integer = v.floating >= r.floating;
1056
return v;
1057
case '>':
1058
v.integer = v.floating > r.floating;
1059
return v;
1060
case LS:
1061
v.floating = (Sflong_t)v.floating << (Sflong_t)r.floating;
1062
return v;
1063
case RS:
1064
v.integer = ((Sfulong_t)v.floating) >> (Sflong_t)r.floating;
1065
return v;
1066
}
1067
break;
1068
default:
1069
switch (expr->op)
1070
{
1071
case X2F:
1072
tmp = *expr->data.operand.left;
1073
tmp.data.constant.value = v;
1074
if ((*ex->disc->convertf)(ex, &tmp, FLOATING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc))
1075
exerror("%s: cannot convert value to floating", expr->data.operand.left->data.variable.symbol->name);
1076
tmp.type = FLOATING;
1077
return tmp.data.constant.value;
1078
case X2I:
1079
tmp = *expr->data.operand.left;
1080
tmp.data.constant.value = v;
1081
if ((*ex->disc->convertf)(ex, &tmp, INTEGER, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc))
1082
exerror("%s: cannot convert value to integer", expr->data.operand.left->data.variable.symbol->name);
1083
tmp.type = INTEGER;
1084
return tmp.data.constant.value;
1085
case X2S:
1086
tmp = *expr->data.operand.left;
1087
tmp.data.constant.value = v;
1088
if ((*ex->disc->convertf)(ex, &tmp, STRING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc))
1089
exerror("%s: cannot convert value to string", expr->data.operand.left->data.variable.symbol->name);
1090
tmp.type = STRING;
1091
return tmp.data.constant.value;
1092
}
1093
goto integer;
1094
case UNSIGNED:
1095
switch (expr->op)
1096
{
1097
case '<':
1098
v.integer = (Sfulong_t)v.integer < (Sfulong_t)r.integer;
1099
return v;
1100
case LE:
1101
v.integer = (Sfulong_t)v.integer <= (Sfulong_t)r.integer;
1102
return v;
1103
case GE:
1104
v.integer = (Sfulong_t)v.integer >= (Sfulong_t)r.integer;
1105
return v;
1106
case '>':
1107
v.integer = (Sfulong_t)v.integer > (Sfulong_t)r.integer;
1108
return v;
1109
}
1110
/*FALLTHROUGH*/
1111
case INTEGER:
1112
integer:
1113
switch (expr->op)
1114
{
1115
case I2F:
1116
#if _WIN32
1117
v.floating = v.integer;
1118
#else
1119
if (expr->type == UNSIGNED)
1120
v.floating = (Sfulong_t)v.integer;
1121
else
1122
v.floating = v.integer;
1123
#endif
1124
return v;
1125
case I2S:
1126
tmp = *expr->data.operand.left;
1127
tmp.data.constant.value = v;
1128
if (expr->data.operand.left->op != DYNAMIC && expr->data.operand.left->op != ID)
1129
{
1130
if (expr->data.operand.left->type == UNSIGNED)
1131
sfprintf(ex->tmp, "%I*u", sizeof(v.integer), v.integer);
1132
else
1133
sfprintf(ex->tmp, "%I*d", sizeof(v.integer), v.integer);
1134
tmp.data.constant.value.string = exstash(ex->tmp, ex->ve);
1135
}
1136
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))
1137
exerror("%s: cannot convert value to string", expr->data.operand.left->data.variable.symbol->name);
1138
tmp.type = STRING;
1139
return tmp.data.constant.value;
1140
case I2X:
1141
tmp = *expr->data.operand.left;
1142
tmp.data.constant.value = v;
1143
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))
1144
exerror("%s: cannot convert integer value to external", tmp.data.variable.symbol->name);
1145
tmp.type = expr->type;
1146
return tmp.data.constant.value;
1147
case '!':
1148
v.integer = !v.integer;
1149
return v;
1150
case '~':
1151
v.integer = ~v.integer;
1152
return v;
1153
case '-':
1154
if (x)
1155
v.integer -= r.integer;
1156
else
1157
v.integer = -v.integer;
1158
return v;
1159
case '+':
1160
v.integer += r.integer;
1161
return v;
1162
case '&':
1163
v.integer &= r.integer;
1164
return v;
1165
case '|':
1166
v.integer |= r.integer;
1167
return v;
1168
case '^':
1169
v.integer ^= r.integer;
1170
return v;
1171
case '*':
1172
v.integer *= r.integer;
1173
return v;
1174
case '/':
1175
if (r.integer == 0)
1176
exerror("integer divide by 0");
1177
else
1178
v.integer /= r.integer;
1179
return v;
1180
case '%':
1181
if (r.integer == 0)
1182
exerror("integer 0 modulus");
1183
else
1184
v.integer %= r.integer;
1185
return v;
1186
case EQ:
1187
v.integer = v.integer == r.integer;
1188
return v;
1189
case NE:
1190
v.integer = v.integer != r.integer;
1191
return v;
1192
case LS:
1193
v.integer = v.integer << r.integer;
1194
return v;
1195
case RS:
1196
v.integer = ((Sfulong_t)v.integer) >> r.integer;
1197
return v;
1198
case '<':
1199
v.integer = v.integer < r.integer;
1200
return v;
1201
case LE:
1202
v.integer = v.integer <= r.integer;
1203
return v;
1204
case GE:
1205
v.integer = v.integer >= r.integer;
1206
return v;
1207
case '>':
1208
v.integer = v.integer > r.integer;
1209
return v;
1210
}
1211
break;
1212
case STRING:
1213
switch (expr->op)
1214
{
1215
case S2B:
1216
v.integer = *v.string != 0;
1217
return v;
1218
case S2F:
1219
tmp = *expr->data.operand.left;
1220
tmp.data.constant.value = v;
1221
if ((*ex->disc->convertf)(ex, &tmp, FLOATING, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc))
1222
{
1223
tmp.data.constant.value.floating = strtod(v.string, &e);
1224
if (*e)
1225
tmp.data.constant.value.floating = *v.string != 0;
1226
}
1227
tmp.type = FLOATING;
1228
return tmp.data.constant.value;
1229
case S2I:
1230
tmp = *expr->data.operand.left;
1231
tmp.data.constant.value = v;
1232
if ((*ex->disc->convertf)(ex, &tmp, INTEGER, expr->data.operand.right ? expr->data.operand.right->data.variable.symbol : (Exid_t*)0, 0, ex->disc))
1233
{
1234
tmp.data.constant.value.integer = strtoll(v.string, &e, 0);
1235
if (*e)
1236
tmp.data.constant.value.integer = *v.string != 0;
1237
}
1238
tmp.type = INTEGER;
1239
return tmp.data.constant.value;
1240
case S2X:
1241
tmp = *expr->data.operand.left;
1242
tmp.data.constant.value = v;
1243
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))
1244
exerror("%s: cannot convert string value to external", tmp.data.variable.symbol->name);
1245
tmp.type = expr->type;
1246
return tmp.data.constant.value;
1247
case EQ:
1248
case NE:
1249
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);
1250
return v;
1251
case '+':
1252
v.string = str_add(ex, v.string, r.string);
1253
return v;
1254
case '|':
1255
v.string = str_ior(ex, v.string, r.string);
1256
return v;
1257
case '&':
1258
v.string = str_and(ex, v.string, r.string);
1259
return v;
1260
case '^':
1261
v.string = str_xor(ex, v.string, r.string);
1262
return v;
1263
case '%':
1264
v.string = str_mod(ex, v.string, r.string);
1265
return v;
1266
case '*':
1267
v.string = str_mpy(ex, v.string, r.string);
1268
return v;
1269
}
1270
v.integer = strcoll(v.string, r.string);
1271
switch (expr->op)
1272
{
1273
case '<':
1274
v.integer = v.integer < 0;
1275
return v;
1276
case LE:
1277
v.integer = v.integer <= 0;
1278
return v;
1279
case GE:
1280
v.integer = v.integer >= 0;
1281
return v;
1282
case '>':
1283
v.integer = v.integer > 0;
1284
return v;
1285
}
1286
goto huh;
1287
}
1288
huh:
1289
if (expr->binary)
1290
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");
1291
else
1292
exerror("operator %s %s not implemented", lexname(expr->op, expr->subop), lexname(expr->data.operand.left->type, -1));
1293
return exzero(expr->type);
1294
}
1295
1296
/*
1297
* evaluate expression expr
1298
*/
1299
1300
Extype_t
1301
exeval(Expr_t* ex, Exnode_t* expr, void* env)
1302
{
1303
Extype_t v;
1304
1305
vmclear(ex->ve);
1306
if (expr->compiled.integer)
1307
{
1308
switch (expr->type)
1309
{
1310
case FLOATING:
1311
v.floating = (*expr->compiled.floating)(ex->disc->data);
1312
break;
1313
case STRING:
1314
v.string = (*expr->compiled.string)(ex->disc->data);
1315
break;
1316
default:
1317
v.integer = (*expr->compiled.integer)(ex->disc->data);
1318
break;
1319
}
1320
}
1321
else
1322
{
1323
v = eval(ex, expr, env);
1324
if (ex->loopcount > 0)
1325
{
1326
ex->loopcount = 0;
1327
if (ex->loopop == RETURN)
1328
return ex->loopret;
1329
}
1330
}
1331
return v;
1332
}
1333
1334