Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
excc.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11/*
12 * Glenn Fowler
13 * AT&T Research
14 *
15 * expression library C program generator
16 */
17
18#include <cgraph/agxbuf.h>
19#include <cgraph/exit.h>
20#include <expr/exlib.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25typedef struct Excc_s Excc_t;
26typedef struct Exccdisc_s Exccdisc_t;
27
28struct Exccdisc_s /* excc() discipline */
29{
30 agxbuf *text; // text output buffer
31 char* id; /* symbol prefix */
32 uint64_t flags; /* EXCC_* flags */
34 /* program generator function */
35};
36
37struct Excc_s /* excc() state */
38{
39 Expr_t* expr; /* exopen() state */
40 Exdisc_t* disc; /* exopen() discipline */
41 char* id; /* prefix + _ */
42 int lastop; /* last op */
43 int tmp; /* temp var index */
44 Exccdisc_t* ccdisc; /* excc() discipline */
45};
46
47#define EX_CC_DUMP 0x8000
48
49static const char quote[] = "\"";
50
51static void gen(Excc_t*, Exnode_t*);
52
53/*
54 * return C name for op
55 */
56
57char*
58exopname(int op)
59{
60 static char buf[16];
61
62 switch (op)
63 {
64 case '!':
65 return "!";
66 case '%':
67 return "%";
68 case '&':
69 return "&";
70 case '(':
71 return "(";
72 case '*':
73 return "*";
74 case '+':
75 return "+";
76 case ',':
77 return ",";
78 case '-':
79 return "-";
80 case '/':
81 return "/";
82 case ':':
83 return ":";
84 case '<':
85 return "<";
86 case '=':
87 return "=";
88 case '>':
89 return ">";
90 case '?':
91 return "?";
92 case '^':
93 return "^";
94 case '|':
95 return "|";
96 case '~':
97 return "~";
98 case AND:
99 return "&&";
100 case EQ:
101 return "==";
102 case GE:
103 return ">=";
104 case LE:
105 return "<=";
106 case LSH:
107 return "<<";
108 case NE:
109 return "!=";
110 case OR:
111 return "||";
112 case RSH:
113 return ">>";
114 default:
115 break;
116 }
117 snprintf(buf, sizeof(buf) - 1, "(OP=%03o)", op);
118 return buf;
119}
120
121/*
122 * generate printf()
123 */
124
125static void print(Excc_t *cc, Exnode_t *exnode) {
126 Print_t* x;
127
128 if ((x = exnode->data.print.args))
129 {
130 char *quoted = fmtesq(x->format, quote);
131 agxbprint(cc->ccdisc->text, "sfprintf(%s, \"%s", exnode->data.print.descriptor->op == CONSTANT && exnode->data.print.descriptor->data.constant.value.integer == 2 ? "sfstderr" : "sfstdout", quoted);
132 free(quoted);
133 while ((x = x->next)) {
134 quoted = fmtesq(x->format, quote);
135 agxbput(cc->ccdisc->text, quoted);
136 free(quoted);
137 }
138 agxbputc(cc->ccdisc->text, '"');
139 for (x = exnode->data.print.args; x; x = x->next)
140 {
141 if (x->arg)
142 {
143 for (size_t i = 0; i < elementsof(x->param) && x->param[i]; i++)
144 {
145 agxbput(cc->ccdisc->text, ", (");
146 gen(cc, x->param[i]);
147 agxbputc(cc->ccdisc->text, ')');
148 }
149 agxbput(cc->ccdisc->text, ", (");
150 gen(cc, x->arg);
151 agxbputc(cc->ccdisc->text, ')');
152 }
153 }
154 agxbput(cc->ccdisc->text, ");\n");
155 }
156}
157
158/*
159 * generate scanf()
160 */
161
162static void scan(Excc_t *cc, Exnode_t *exnode) {
163 Print_t* x;
164
165 if ((x = exnode->data.print.args))
166 {
167 char *quoted = fmtesq(x->format, quote);
168 agxbprint(cc->ccdisc->text, "sfscanf(sfstdin, \"%s", quoted);
169 free(quoted);
170 while ((x = x->next)) {
171 quoted = fmtesq(x->format, quote);
172 agxbput(cc->ccdisc->text, quoted);
173 free(quoted);
174 }
175 agxbputc(cc->ccdisc->text, '"');
176 for (x = exnode->data.print.args; x; x = x->next)
177 {
178 if (x->arg)
179 {
180 for (size_t i = 0; i < elementsof(x->param) && x->param[i]; i++)
181 {
182 agxbput(cc->ccdisc->text, ", &(");
183 gen(cc, x->param[i]);
184 agxbputc(cc->ccdisc->text, ')');
185 }
186 agxbput(cc->ccdisc->text, ", &(");
187 gen(cc, x->arg);
188 agxbputc(cc->ccdisc->text, ')');
189 }
190 }
191 agxbput(cc->ccdisc->text, ");\n");
192 }
193}
194
195/*
196 * internal excc
197 */
198
199static void gen(Excc_t *cc, Exnode_t *exnode) {
200 Exnode_t* x;
201 Exnode_t* y;
202 int n;
203 int m;
204 char* s;
205 Extype_t* v;
206 Extype_t** p;
207
208 if (!exnode)
209 return;
210 if (exnode->op == CALL) {
211 agxbprint(cc->ccdisc->text, "%s(", exnode->data.call.procedure->name);
212 if (exnode->data.call.args)
213 gen(cc, exnode->data.call.args);
214 agxbputc(cc->ccdisc->text, ')');
215 return;
216 }
217 x = exnode->data.operand.left;
218 switch (exnode->op)
219 {
220 case BREAK:
221 agxbput(cc->ccdisc->text, "break;\n");
222 return;
223 case CONTINUE:
224 agxbput(cc->ccdisc->text, "continue;\n");
225 return;
226 case CONSTANT:
227 switch (exnode->type)
228 {
229 case FLOATING:
230 agxbprint(cc->ccdisc->text, "%g", exnode->data.constant.value.floating);
231 break;
232 case STRING: {
233 char *quoted = fmtesq(exnode->data.constant.value.string, quote);
234 agxbprint(cc->ccdisc->text, "\"%s\"", quoted);
235 free(quoted);
236 break;
237 }
238 case UNSIGNED:
239 agxbprint(cc->ccdisc->text, "%llu",
240 (long long unsigned)exnode->data.constant.value.integer);
241 break;
242 default:
243 agxbprint(cc->ccdisc->text, "%lld", exnode->data.constant.value.integer);
244 break;
245 }
246 return;
247 case DEC:
248 agxbprint(cc->ccdisc->text, "%s--", x->data.variable.symbol->name);
249 return;
250 case DYNAMIC:
251 agxbput(cc->ccdisc->text, exnode->data.variable.symbol->name);
252 return;
253 case EXIT:
254 agxbput(cc->ccdisc->text, "exit(");
255 gen(cc, x);
256 agxbput(cc->ccdisc->text, ");\n");
257 return;
258 case FUNCTION:
259 gen(cc, x);
260 agxbputc(cc->ccdisc->text, '(');
261 if ((y = exnode->data.operand.right)) {
262 gen(cc, y);
263 }
264 agxbputc(cc->ccdisc->text, ')');
265 return;
266 case RAND:
267 agxbput(cc->ccdisc->text, "rand();\n");
268 return;
269 case SRAND:
270 if (exnode->binary) {
271 agxbput(cc->ccdisc->text, "srand(");
272 gen(cc, x);
273 agxbput(cc->ccdisc->text, ");\n");
274 } else
275 agxbput(cc->ccdisc->text, "srand();\n");
276 return;
277 case GSUB:
278 case SUB:
279 case SUBSTR:
280 s = (exnode->op == GSUB ? "gsub(" : exnode->op == SUB ? "sub(" : "substr(");
281 agxbput(cc->ccdisc->text, s);
282 gen(cc, exnode->data.string.base);
283 agxbput(cc->ccdisc->text, ", ");
284 gen(cc, exnode->data.string.pat);
285 if (exnode->data.string.repl) {
286 agxbput(cc->ccdisc->text, ", ");
287 gen(cc, exnode->data.string.repl);
288 }
289 agxbputc(cc->ccdisc->text, ')');
290 return;
291 case IN_OP:
292 gen(cc, exnode->data.variable.index);
293 agxbprint(cc->ccdisc->text, " in %s", exnode->data.variable.symbol->name);
294 return;
295 case IF:
296 agxbput(cc->ccdisc->text, "if (");
297 gen(cc, x);
298 agxbput(cc->ccdisc->text, ") {\n");
299 gen(cc, exnode->data.operand.right->data.operand.left);
300 if (exnode->data.operand.right->data.operand.right)
301 {
302 agxbput(cc->ccdisc->text, "} else {\n");
303 gen(cc, exnode->data.operand.right->data.operand.right);
304 }
305 agxbput(cc->ccdisc->text, "}\n");
306 return;
307 case FOR:
308 agxbput(cc->ccdisc->text, "for (;");
309 gen(cc, x);
310 agxbput(cc->ccdisc->text, ");");
311 if (exnode->data.operand.left)
312 {
313 agxbputc(cc->ccdisc->text, '(');
314 gen(cc, exnode->data.operand.left);
315 agxbputc(cc->ccdisc->text, ')');
316 }
317 agxbput(cc->ccdisc->text, ") {");
318 if (exnode->data.operand.right)
319 gen(cc, exnode->data.operand.right);
320 agxbputc(cc->ccdisc->text, '}');
321 return;
322 case ID:
323 if (cc->ccdisc->ccf)
324 cc->ccdisc->ccf(cc, exnode, exnode->data.variable.symbol, exnode->data.variable.reference, exnode->data.variable.index, cc->ccdisc);
325 else
326 agxbput(cc->ccdisc->text, exnode->data.variable.symbol->name);
327 return;
328 case INC:
329 agxbprint(cc->ccdisc->text, "%s++", x->data.variable.symbol->name);
330 return;
331 case ITERATE:
332 case ITERATER:
333 if (exnode->op == DYNAMIC)
334 {
335 agxbprint(cc->ccdisc->text, "{ Exassoc_t* %stmp_%d;", cc->id, ++cc->tmp);
336 agxbprint(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, exnode->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp, exnode->data.generate.index->name, cc->id, cc->tmp, cc->id, cc->tmp, exnode->data.generate.array->data.variable.symbol->name, cc->id, cc->tmp);
337 gen(cc, exnode->data.generate.statement);
338 agxbput(cc->ccdisc->text, "} }");
339 }
340 return;
341 case PRINT:
342 agxbput(cc->ccdisc->text, "print");
343 if (x)
344 gen(cc, x);
345 else
346 agxbput(cc->ccdisc->text, "()");
347 return;
348 case PRINTF:
349 print(cc, exnode);
350 return;
351 case RETURN:
352 agxbput(cc->ccdisc->text, "return(");
353 gen(cc, x);
354 agxbput(cc->ccdisc->text, ");\n");
355 return;
356 case SCANF:
357 scan(cc, exnode);
358 return;
359 case SPLIT:
360 case TOKENS:
361 if (exnode->op == SPLIT)
362 agxbput(cc->ccdisc->text, "split (");
363 else
364 agxbput(cc->ccdisc->text, "tokens (");
365 gen(cc, exnode->data.split.string);
366 agxbprint(cc->ccdisc->text, ", %s", exnode->data.split.array->name);
367 if (exnode->data.split.seps) {
368 agxbputc(cc->ccdisc->text, ',');
369 gen(cc, exnode->data.split.seps);
370 }
371 agxbputc(cc->ccdisc->text, ')');
372 return;
373 case SWITCH: {
374 long t = x->type;
375 agxbprint(cc->ccdisc->text, "{ %s %stmp_%d = ", extype(t), cc->id, ++cc->tmp);
376 gen(cc, x);
377 agxbputc(cc->ccdisc->text, ';');
378 x = exnode->data.operand.right;
379 y = x->data.select.statement;
380 n = 0;
381 while ((x = x->data.select.next))
382 {
383 if (n)
384 agxbput(cc->ccdisc->text, "else ");
385 if (!(p = x->data.select.constant))
386 y = x->data.select.statement;
387 else
388 {
389 m = 0;
390 while ((v = *p++))
391 {
392 if (m)
393 agxbput(cc->ccdisc->text, "||");
394 else
395 {
396 m = 1;
397 agxbput(cc->ccdisc->text, "if (");
398 }
399 if (t == STRING) {
400 char *quoted = fmtesq(v->string, quote);
401 agxbprint(cc->ccdisc->text, "strmatch(%stmp_%d, \"%s\")", cc->id, cc->tmp, quoted);
402 free(quoted);
403 } else {
404 agxbprint(cc->ccdisc->text, "%stmp_%d == ", cc->id, cc->tmp);
405 switch (t)
406 {
407 case INTEGER:
408 case UNSIGNED:
409 agxbprint(cc->ccdisc->text, "%llu",
410 (unsigned long long)v->integer);
411 break;
412 default:
413 agxbprint(cc->ccdisc->text, "%g", v->floating);
414 break;
415 }
416 }
417 }
418 agxbput(cc->ccdisc->text, ") {");
419 gen(cc, x->data.select.statement);
420 agxbputc(cc->ccdisc->text, '}');
421 }
422 }
423 if (y)
424 {
425 if (n)
426 agxbput(cc->ccdisc->text, "else ");
427 agxbputc(cc->ccdisc->text, '{');
428 gen(cc, y);
429 agxbputc(cc->ccdisc->text, '}');
430 }
431 agxbputc(cc->ccdisc->text, '}');
432 return;
433 }
434 case UNSET:
435 agxbprint(cc->ccdisc->text, "unset(%s", exnode->data.variable.symbol->name);
436 if (exnode->data.variable.index) {
437 agxbputc(cc->ccdisc->text, ',');
438 gen(cc, exnode->data.variable.index);
439 }
440 agxbputc(cc->ccdisc->text, ')');
441 return;
442 case WHILE:
443 agxbput(cc->ccdisc->text, "while (");
444 gen(cc, x);
445 agxbput(cc->ccdisc->text, ") {");
446 if (exnode->data.operand.right)
447 gen(cc, exnode->data.operand.right);
448 agxbputc(cc->ccdisc->text, '}');
449 return;
450 case '#':
451 agxbprint(cc->ccdisc->text, "# %s", exnode->data.variable.symbol->name);
452 return;
453 case '=':
454 agxbprint(cc->ccdisc->text, "(%s%s=", x->data.variable.symbol->name, exnode->subop == '=' ? "" : exopname(exnode->subop));
455 gen(cc, exnode->data.operand.right);
456 agxbputc(cc->ccdisc->text, ')');
457 return;
458 case ';':
459 for (;;)
460 {
461 if (!(x = exnode->data.operand.right))
462 switch (cc->lastop = exnode->data.operand.left->op)
463 {
464 case FOR:
465 case IF:
466 case PRINTF:
467 case PRINT:
468 case RETURN:
469 case WHILE:
470 break;
471 default:
472 agxbprint(cc->ccdisc->text, "_%svalue=", cc->id);
473 break;
474 }
475 gen(cc, exnode->data.operand.left);
476 agxbput(cc->ccdisc->text, ";\n");
477 if (!(exnode = x))
478 break;
479 switch (cc->lastop = exnode->op)
480 {
481 case ';':
482 continue;
483 case FOR:
484 case IF:
485 case PRINTF:
486 case PRINT:
487 case RETURN:
488 case WHILE:
489 break;
490 default:
491 agxbprint(cc->ccdisc->text, "_%svalue=", cc->id);
492 break;
493 }
494 gen(cc, exnode);
495 agxbput(cc->ccdisc->text, ";\n");
496 break;
497 }
498 return;
499 case ',':
500 agxbputc(cc->ccdisc->text, '(');
501 gen(cc, x);
502 while ((exnode = exnode->data.operand.right) && exnode->op == ',')
503 {
504 agxbput(cc->ccdisc->text, "), (");
505 gen(cc, exnode->data.operand.left);
506 }
507 if (exnode)
508 {
509 agxbput(cc->ccdisc->text, "), (");
510 gen(cc, exnode);
511 }
512 agxbputc(cc->ccdisc->text, ')');
513 return;
514 case '?':
515 agxbputc(cc->ccdisc->text, '(');
516 gen(cc, x);
517 agxbput(cc->ccdisc->text, ") ? (");
518 gen(cc, exnode->data.operand.right->data.operand.left);
519 agxbput(cc->ccdisc->text, ") : (");
520 gen(cc, exnode->data.operand.right->data.operand.right);
521 agxbputc(cc->ccdisc->text, ')');
522 return;
523 case AND:
524 agxbputc(cc->ccdisc->text, '(');
525 gen(cc, x);
526 agxbput(cc->ccdisc->text, ") && (");
527 gen(cc, exnode->data.operand.right);
528 agxbputc(cc->ccdisc->text, ')');
529 return;
530 case OR:
531 agxbputc(cc->ccdisc->text, '(');
532 gen(cc, x);
533 agxbput(cc->ccdisc->text, ") || (");
534 gen(cc, exnode->data.operand.right);
535 agxbputc(cc->ccdisc->text, ')');
536 return;
537 case F2I:
538 agxbprint(cc->ccdisc->text, "(%s)(", extype(INTEGER));
539 gen(cc, x);
540 agxbputc(cc->ccdisc->text, ')');
541 return;
542 case I2F:
543 agxbprint(cc->ccdisc->text, "(%s)(", extype(FLOATING));
544 gen(cc, x);
545 agxbputc(cc->ccdisc->text, ')');
546 return;
547 case S2I:
548 agxbput(cc->ccdisc->text, "strtoll(");
549 gen(cc, x);
550 agxbput(cc->ccdisc->text, ",(char**)0,0)");
551 return;
552 case X2I:
553 agxbput(cc->ccdisc->text, "X2I(");
554 gen(cc, x);
555 agxbputc(cc->ccdisc->text, ')');
556 return;
557 case X2X:
558 agxbput(cc->ccdisc->text, "X2X(");
559 gen(cc, x);
560 agxbputc(cc->ccdisc->text, ')');
561 return;
562 }
563 y = exnode->data.operand.right;
564 if (x->type == STRING)
565 {
566 switch (exnode->op)
567 {
568 case S2B:
569 agxbput(cc->ccdisc->text, "*(");
570 gen(cc, x);
571 agxbput(cc->ccdisc->text, ")!=0");
572 return;
573 case S2F:
574 agxbput(cc->ccdisc->text, "strtod(");
575 gen(cc, x);
576 agxbput(cc->ccdisc->text, ",0)");
577 return;
578 case S2I:
579 agxbput(cc->ccdisc->text, "strtol(");
580 gen(cc, x);
581 agxbput(cc->ccdisc->text, ",0,0)");
582 return;
583 case S2X:
584 agxbput(cc->ccdisc->text, "** cannot convert string value to external **");
585 return;
586 case NE:
587 agxbputc(cc->ccdisc->text, '!');
588 /*FALLTHROUGH*/
589 case EQ:
590 agxbput(cc->ccdisc->text, "strmatch(");
591 gen(cc, x);
592 agxbputc(cc->ccdisc->text, ',');
593 gen(cc, y);
594 agxbputc(cc->ccdisc->text, ')');
595 return;
596 case '+':
597 case '|':
598 case '&':
599 case '^':
600 case '%':
601 case '*':
602 agxbput(cc->ccdisc->text, "** string bits not supported **");
603 return;
604 }
605 switch (exnode->op)
606 {
607 case '<':
608 s = "<0";
609 break;
610 case LE:
611 s = "<=0";
612 break;
613 case GE:
614 s = ">=0";
615 break;
616 case '>':
617 s = ">0";
618 break;
619 default:
620 s = "** unknown string op **";
621 break;
622 }
623 agxbput(cc->ccdisc->text, "strcoll(");
624 gen(cc, x);
625 agxbputc(cc->ccdisc->text, ',');
626 gen(cc, y);
627 agxbprint(cc->ccdisc->text, ")%s", s);
628 return;
629 }
630 else
631 {
632 if (!y)
633 agxbput(cc->ccdisc->text, exopname(exnode->op));
634 agxbputc(cc->ccdisc->text, '(');
635 gen(cc, x);
636 if (y)
637 {
638 agxbprint(cc->ccdisc->text, ")%s(", exopname(exnode->op));
639 gen(cc, y);
640 }
641 agxbputc(cc->ccdisc->text, ')');
642 }
643 return;
644}
645
646/*
647 * generate global declarations
648 */
649
650static int global(void *object, void *handle) {
651 agxbuf *stream = handle;
652 Exid_t* sym = object;
653
654 if (sym->lex == DYNAMIC)
655 agxbprint(stream, "static %s %s;\n", extype(sym->type), sym->name);
656 return 0;
657}
658
659/*
660 * open C program generator context
661 */
662
663static Excc_t *exccopen(Expr_t *ex, Exccdisc_t *disc) {
664 Excc_t* cc;
665 char* id;
666
667 if (!(id = disc->id))
668 id = "";
669 if (!(cc = calloc(1, sizeof(Excc_t) + strlen(id) + 2)))
670 return 0;
671 cc->expr = ex;
672 cc->disc = ex->disc;
673 cc->id = (char*)(cc + 1);
674 cc->ccdisc = disc;
675 if (!(disc->flags & EX_CC_DUMP))
676 {
677 agxbprint(disc->text, "/* : : generated by %s : : */\n", exversion);
678 agxbput(disc->text, "\n#include <ast/ast.h>\n");
679 if (*id)
680 snprintf(cc->id, strlen(id) + 2, "%s_", id);
681 agxbputc(disc->text, '\n');
682 dtwalk(ex->symbols, global, disc->text);
683 }
684 return cc;
685}
686
687/*
688 * close C program generator context
689 */
690
691static int exccclose(Excc_t *cc) {
692 int r = 0;
693
694 if (!cc)
695 r = -1;
696 else
697 {
698 if (!(cc->ccdisc->flags & EX_CC_DUMP))
699 {
700 if (cc->ccdisc->text)
701 agxbuse(cc->ccdisc->text);
702 else
703 r = -1;
704 }
705 free(cc);
706 }
707 return r;
708}
709
710/*
711 * dump an expression tree to a buffer
712 */
713
715 Excc_t* cc;
716 Exccdisc_t ccdisc;
717 Exid_t* sym;
718
719 memset(&ccdisc, 0, sizeof(ccdisc));
720 ccdisc.flags = EX_CC_DUMP;
721 ccdisc.text = xb;
722 if (!(cc = exccopen(ex, &ccdisc)))
723 return -1;
724 if (node)
725 gen(cc, node);
726 else
727 for (sym = dtfirst(ex->symbols); sym; sym = dtnext(ex->symbols, sym))
728 if (sym->lex == PROCEDURE && sym->value)
729 {
730 agxbprint(xb, "%s:\n", sym->name);
731 gen(cc, sym->value->data.procedure.body);
732 }
733 agxbputc(xb, '\n');
734 return exccclose(cc);
735}
static size_t agxbput(agxbuf *xb, const char *s)
append string s into xb
Definition agxbuf.h:249
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:213
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Definition agxbuf.h:256
static char * agxbuse(agxbuf *xb)
Definition agxbuf.h:286
char * fmtesq(const char *, const char *)
Definition fmtesc.c:123
#define elementsof(x)
Definition ast.h:33
CDT_API int dtwalk(Dt_t *, int(*)(void *, void *), void *)
Definition dtwalk.c:9
#define dtnext(d, o)
Definition cdt.h:188
#define dtfirst(d)
Definition cdt.h:187
static void scan(Excc_t *cc, Exnode_t *exnode)
Definition excc.c:162
#define EX_CC_DUMP
Definition excc.c:47
static int global(void *object, void *handle)
Definition excc.c:650
char * exopname(int op)
Definition excc.c:58
static void print(Excc_t *cc, Exnode_t *exnode)
Definition excc.c:125
static Excc_t * exccopen(Expr_t *ex, Exccdisc_t *disc)
Definition excc.c:663
static const char quote[]
Definition excc.c:49
static int exccclose(Excc_t *cc)
Definition excc.c:691
static void gen(Excc_t *, Exnode_t *)
Definition excc.c:199
int exdump(Expr_t *ex, Exnode_t *node, agxbuf *xb)
Definition excc.c:714
const char * exversion
Definition exdata.c:22
#define UNSIGNED
Definition exparse.c:237
#define DYNAMIC
Definition exparse.c:252
#define SCANF
Definition exparse.c:274
#define RSH
Definition exparse.c:307
#define OR
Definition exparse.c:300
#define GE
Definition exparse.c:305
#define ITERATER
Definition exparse.c:259
#define S2X
Definition exparse.c:294
#define WHILE
Definition exparse.c:284
#define ITERATE
Definition exparse.c:258
#define NE
Definition exparse.c:303
#define SRAND
Definition exparse.c:277
#define S2I
Definition exparse.c:291
#define SUB
Definition exparse.c:279
#define LSH
Definition exparse.c:306
#define FLOATING
Definition exparse.c:239
#define FOR
Definition exparse.c:255
#define IN_OP
Definition exparse.c:308
#define SUBSTR
Definition exparse.c:280
#define TOKENS
Definition exparse.c:282
#define RAND
Definition exparse.c:272
#define PRINT
Definition exparse.c:268
#define I2F
Definition exparse.c:287
#define CONSTANT
Definition exparse.c:248
#define LE
Definition exparse.c:304
#define S2B
Definition exparse.c:289
#define CALL
Definition exparse.c:246
#define GSUB
Definition exparse.c:257
#define UNSET
Definition exparse.c:283
#define CONTINUE
Definition exparse.c:249
#define F2I
Definition exparse.c:285
#define EQ
Definition exparse.c:302
#define BREAK
Definition exparse.c:245
#define S2F
Definition exparse.c:290
#define IF
Definition exparse.c:261
#define PROCEDURE
Definition exparse.c:270
#define SWITCH
Definition exparse.c:281
#define AND
Definition exparse.c:301
#define X2X
Definition exparse.c:298
#define EXIT
Definition exparse.c:254
#define X2I
Definition exparse.c:296
#define PRINTF
Definition exparse.c:269
#define FUNCTION
Definition exparse.c:256
#define INC
Definition exparse.c:310
#define DEC
Definition exparse.c:311
char * extype(long int)
Definition extype.c:24
#define ID
Definition gmlparse.c:415
#define STRING
Definition gmlparse.c:414
#define INTEGER
Definition gmlparse.c:412
void free(void *)
static uint64_t id
Definition gv2gml.c:42
#define SPLIT(x, n, s)
Definition htmltable.c:1273
#define RETURN(v)
Definition strmatch.c:144
Definition excc.c:38
Exdisc_t * disc
Definition excc.c:40
Exccdisc_t * ccdisc
Definition excc.c:44
int lastop
Definition excc.c:42
Expr_t * expr
Definition excc.c:39
int tmp
Definition excc.c:43
char * id
Definition excc.c:41
agxbuf * text
Definition excc.c:30
int(* ccf)(Excc_t *, Exnode_t *, Exid_t *, Exref_t *, Exnode_t *, Exccdisc_t *)
Definition excc.c:33
uint64_t flags
Definition excc.c:32
char * id
Definition excc.c:31
Definition expr.h:93
long type
Definition expr.h:97
long lex
Definition expr.h:95
char name[EX_NAMELEN]
Definition expr.h:103
Exnode_t * value
Definition expr.h:100
int op
Definition expr.h:153
long type
value type
Definition expr.h:152
int binary
Definition expr.h:154
Exdata_t data
Definition expr.h:162
Definition expr.h:202
Dt_t * symbols
Definition expr.h:204
struct Exnode_s * param[3]
Definition exlib.h:48
char * format
Definition exlib.h:47
struct Exnode_s * arg
Definition exlib.h:49
struct Print_s * next
Definition exlib.h:46
char * string
Definition exparse.c:327
long long integer
Definition exparse.c:325
double floating
Definition exparse.c:322
struct Exdata_u::@87 constant
Exnode_t * left
Definition expr.h:124
Exnode_t * right
Definition expr.h:125
Exid_t * reference
Definition expr.h:119
Exnode_t * next
Definition expr.h:132
struct Exdata_u::@88 operand
Exnode_t * statement
Definition expr.h:131
Exid_t * symbol
Definition expr.h:138
struct Exdata_u::@89 select
Extype_t value
Definition expr.h:118
Exnode_t * index
Definition expr.h:140
struct Exdata_u::@90 variable
Definition grammar.c:93