scc

Simple C99 Compiler
Log | Files | Refs | README | LICENSE

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:
cc.h | 2++
flow.c | 3++-
syntax.h | 4++--
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(')'); +}