commit cd933c3ca6494045d5d258c4aecb8372cf703976
parent f68fdbc771e1a8d3a0944c4fd455bcdcb48bdcd8
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Wed, 15 Aug 2012 18:47:49 +0200
Added prtree function
prtree is intended for printing to the output the tree of a expresion, using
a polish notation for the tree.
Diffstat:
M | cc.h | | | 2 | ++ |
M | flow.c | | | 3 | ++- |
M | syntax.h | | | 4 | ++-- |
M | tree.c | | | 88 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
4 files changed, 90 insertions(+), 7 deletions(-)
diff --git 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;
diff --git a/flow.c b/flow.c
@@ -105,7 +105,8 @@ void stmt(void)
case IDEN:
/* TODO: check if it can be a label */
default:
- expr();
+ prtree(expr());
+ putchar('\n');
break;
}
expect(';');
diff --git a/syntax.h b/syntax.h
@@ -10,7 +10,7 @@ enum {
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 @@ node1(unsigned char op, struct node *i);
extern struct node *
nodesym(struct symbol *sym);
-
+extern void prtree(register struct node *np);
#endif
diff --git 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 node_sym {
struct symbol *sym;
};
-
-#define OSYM 1
-
struct node *
nodesym(struct symbol *sym)
{
@@ -80,3 +79,84 @@ node1(unsigned char op, struct node *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(')');
+}