ref: cd933c3ca6494045d5d258c4aecb8372cf703976
parent: f68fdbc771e1a8d3a0944c4fd455bcdcb48bdcd8
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 15 14:47:49 EDT 2012
Added prtree function prtree is intended for printing to the output the tree of a expresion, using a polish notation for the tree.
--- a/cc.h
+++ b/cc.h
@@ -1,6 +1,8 @@
#ifndef CC_H
#define CC_H
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
extern unsigned linenum;
extern unsigned columnum;
extern const char *filename;
--- a/flow.c
+++ b/flow.c
@@ -105,7 +105,8 @@
case IDEN:
/* TODO: check if it can be a label */
default:
- expr();
+ prtree(expr());
+ putchar('\n');break;
}
expect(';');--- a/syntax.h
+++ b/syntax.h
@@ -10,7 +10,7 @@
OSHR, OLT, OGT, OGE, OLE, OEQ, ONE, OBAND, OBXOR,
OBOR, OAND, OOR, OTERN, OASSIGN, OA_MUL, OA_DIV,
OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR, OA_AND,
- OA_XOR, OA_OR
+ OA_XOR, OA_OR, OSYM
};
struct node;
@@ -33,5 +33,5 @@
extern struct node *
nodesym(struct symbol *sym);
-
+extern void prtree(register struct node *np);
#endif
--- a/tree.c
+++ b/tree.c
@@ -1,9 +1,11 @@
-#include <stdarg.h>
+#include <assert.h>
#include <stddef.h>
+#include <stdio.h>
#include "cc.h"
#include "syntax.h"
+#include "symbol.h"
struct node {unsigned char op;
@@ -32,9 +34,6 @@
struct symbol *sym;
};
-
-#define OSYM 1
-
struct node *
nodesym(struct symbol *sym)
{@@ -79,4 +78,85 @@
np->infix = i;
return (struct node *) np;
+}
+
+void
+prtree(register struct node *np)
+{+ static struct optab {+ unsigned char nchild;
+ const char *txt;
+ } *bp, optab [] = {+ [OCALL] = {1, "()"},+ [OARY] = {2, "[]"},+ [OFIELD] = {2, "."},+ [OPTR] = {2, "->"},+ [OPOSTINC] = {1, ".++"},+ [OPOSTDEC] = {1, "++."},+ [OPREINC] = {1, "++."},+ [OPREDEC] = {1, "--."},+ [OADDR] = {1, "&."},+ [OINDIR] = {1, "[*]"},+ [OMINUS] = {1, "-."},+ [OPLUS] = {1, "+."},+ [OCPL] = {1, "~"},+ [ONEG] = {1, "!"},+ [OMUL] = {2, "*"},+ [ODIV] = {2, "/"},+ [OMOD] = {2, "%"},+ [OADD] = {2, "+"},+ [OSUB] = {2, "-"},+ [OSHL] = {2, "<<"},+ [OSHR] = {2, ">>"},+ [OLT] = {2, "<"},+ [OGT] = {2, ">"},+ [OGE] = {2, ">="},+ [OLE] = {2, "<="},+ [OEQ] = {2, "=="},+ [ONE] = {2, "!="},+ [OBAND] = {2, "&"},+ [OBXOR] = {2, "^"},+ [OBOR] = {2, "|"},+ [OAND] = {2, "&&"},+ [OOR] = {2, "||"},+ [OTERN] = {3, "?"},+ [OASSIGN] = {2, "="},+ [OA_MUL] = {2, "*="},+ [OA_DIV] = {2, "/="},+ [OA_MOD] = {2, "%="},+ [OA_ADD] = {2, "+="},+ [OA_SUB] = {2, "-="},+ [OA_SHL] = {2, "<<="},+ [OA_SHR] = {2, ">>="},+ [OA_AND] = {2, "&="},+ [OA_XOR] = {2, "^="},+ [OA_OR] = {2, "|="},+ [OSYM] = {0, "sym"}+ };
+
+ assert(np && np->op < ARRAY_SIZE(optab));
+ bp = &optab[np->op];
+ if (bp->nchild)
+ printf("(%s ", bp->txt);+
+ switch (bp->nchild) {+ case 0: {+ register struct symbol *sym = ((struct node_sym *) np)->sym;
+ printf(" %s", (sym->name) ? sym->name : ".");+ return;
+ }
+ case 1:
+ prtree(((struct node_op1 *) np)->infix);
+ break;
+ case 2:
+ prtree(((struct node_op2 *) np)->left);
+ prtree(((struct node_op2 *) np)->rigth);
+ break;
+ case 3:
+ prtree(((struct node_op3 *) np)->left);
+ prtree(((struct node_op3 *) np)->infix);
+ prtree(((struct node_op3 *) np)->rigth);
+ break;
+ }
+ putchar(')');}
--
⑨