shithub: scc

Download patch

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(')');
 }
--