scc

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

commit 543ec38258d6de262c01d186939d3836d401099e
parent 9f0411880dcba1a99d5b7d76c0dc77424a139783
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 28 Jul 2012 20:38:13 +0200

Changed tree representation

With this new representation is possible use different node sizes, and have
meaningful names in the member. Instead of store a pointer to one function,
we store an id, which will be used later for call the appropriate functions.

Diffstat:
Makefile | 2+-
code.c | 177-------------------------------------------------------------------------------
expr.c | 136++++++++++++++++++++++++++++++++++++++-----------------------------------------
syntax.h | 29++++++++++++++++++++++-------
tree.c | 99++++++++++++++++++++++++++++++++++++++-----------------------------------------
5 files changed, 135 insertions(+), 308 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o keyword.o \ - code.o wrapper.o tree.o + wrapper.o tree.o LIBS = all: kcc diff --git a/code.c b/code.c @@ -1,177 +0,0 @@ -#include "syntax.h" - - -struct symbol *op_ary(struct node *np) -{ -} - -struct symbol *op_call(struct node *np) -{ -} - -struct symbol *op_field(struct node *np) -{ -} - -struct symbol *op_ptr(struct node *np) -{ -} - -struct symbol *op_postinc(struct node *np) -{ -} - -struct symbol *op_postdec(struct node *np) -{ -} - -struct symbol *op_preinc(struct node *np) -{ -} - -struct symbol *op_predec(struct node *np) -{ -} - -struct symbol *op_addr(struct node *np) -{ -} - -struct symbol *op_indir(struct node *np) -{ -} - -struct symbol *op_minus(struct node *np) -{ -} - -struct symbol *op_plus(struct node *np) -{ -} - -struct symbol *op_cpl(struct node *np) -{ -} - -struct symbol *op_neg(struct node *np) -{ -} - -struct symbol *op_mul(struct node *np) -{ -} - -struct symbol *op_div(struct node *np) -{ -} - -struct symbol *op_mod(struct node *np) -{ -} -struct symbol *op_add(struct node *np) -{ -} - -struct symbol *op_sub(struct node *np) -{ -} - -struct symbol *op_shl(struct node *np) -{ -} - -struct symbol *op_shr(struct node *np) -{ -} - -struct symbol *op_lt(struct node *np) -{ -} - -struct symbol *op_gt(struct node *np) -{ -} - -struct symbol *op_ge(struct node *np) -{ -} - -struct symbol *op_le(struct node *np) -{ -} - -struct symbol *op_eq(struct node *np) -{ -} - -struct symbol *op_ne(struct node *np) -{ -} - -struct symbol *op_band(struct node *np) -{ -} - -struct symbol *op_bxor(struct node *np) -{ -} - -struct symbol *op_bor(struct node *np) -{ -} - -struct symbol *op_and(struct node *np) -{ -} - -struct symbol *op_or(struct node *np) -{ -} - -struct symbol *op_tern(struct node *np) -{ -} - -struct symbol *op_assign(struct node *np) -{ -} - -struct symbol *op_a_mul(struct node *np) -{ -} - -struct symbol *op_a_div(struct node *np) -{ -} - -struct symbol *op_a_mod(struct node *np) -{ -} - -struct symbol *op_a_add(struct node *np) -{ -} - -struct symbol *op_a_sub(struct node *np) -{ -} - -struct symbol *op_a_shl(struct node *np) -{ -} - -struct symbol *op_a_shr(struct node *np) -{ -} - -struct symbol *op_a_and(struct node *np) -{ -} - -struct symbol *op_a_xor(struct node *np) -{ -} - -struct symbol *op_a_or(struct node *np) -{ -} diff --git a/expr.c b/expr.c @@ -7,12 +7,6 @@ #include "syntax.h" #include "code.h" -extern nodeop op_ary, op_call, op_field, op_ptr, op_postinc, op_postdec, - op_preinc, op_predec, op_addr, op_indir, op_minus, op_plus, op_cpl, - op_neg, op_mul, op_div, op_mod, op_add, op_sub, op_shl, op_shr, - op_lt, op_gt, op_ge, op_le, op_eq, op_ne, op_band, op_bxor, op_bor, - op_and, op_or, op_tern, op_assign, op_a_mul, op_a_div, op_a_mod, - op_a_add, op_a_sub, op_a_shl, op_a_shr, op_a_and, op_a_xor, op_a_or; struct node *expr(void); @@ -26,7 +20,7 @@ static struct node *primary(void) error("'%s' undeclared", yytext); case CONSTANT: next(); - np = leaf(yyval.sym); + np = nodesym(yyval.sym); break; case '(': next(); @@ -45,36 +39,36 @@ static struct node *postfix(void) np1 = primary(); /* TODO: fix ( case */ for (;;) { - register nodeop *op; + register unsigned char op; switch (yytoken) { case '[': next(); np2 = expr(); expect(']'); - op = op_ary; + op = OARY; goto node_2_childs; /* TODO: better names */ case '(': next(); np2 = expr(); expect(')'); - op = op_call; + op = OCALL; goto node_2_childs; - case '.': op = op_field; goto expect_iden; - case INDIR: op = op_ptr; goto expect_iden; - case INC: op = op_postinc; goto next; - case DEC: op = op_postdec; goto next; + case '.': op = OFIELD; goto expect_iden; + case INDIR: op = OPTR; goto expect_iden; + case INC: op = OPOSTINC; goto next; + case DEC: op = OPOSTDEC; goto next; default: return np1; } node_2_childs: - np1 = op2(op, np1, np2); + np1 = node2(op, np1, np2); continue; expect_iden: next(); expect(IDEN); - np1 = op2(op, np1, leaf(yyval.sym)); + np1 = node2(op, np1, nodesym(yyval.sym)); continue; next: - np1 = op1(op, np1); + np1 = node1(op, np1); next(); continue; } @@ -84,7 +78,7 @@ static struct node *cast(void); static struct node *unary(void) { - register nodeop *op; + register unsigned char op; switch (yytoken) { case SIZEOF: /* TODO: Implement sizeof */ @@ -95,25 +89,25 @@ static struct node *unary(void) } else { unary(); } - return leaf(NULL); - case INC: op = op_preinc; goto call_unary; - case DEC: op = op_predec; goto call_unary; - case '&': op = op_addr; goto call_cast; - case '*': op = op_indir; goto call_cast; - case '-': op = op_minus; goto call_cast; - case '+': op = op_plus; goto call_cast; - case '~': op = op_cpl; goto call_cast; - case '!': op = op_neg; goto call_cast; + return nodesym(NULL); + case INC: op = OPREINC; goto call_unary; + case DEC: op = OPREDEC; goto call_unary; + case '&': op = OADDR; goto call_cast; + case '*': op = OINDIR; goto call_cast; + case '-': op = OMINUS; goto call_cast; + case '+': op = OPLUS; goto call_cast; + case '~': op = OCPL; goto call_cast; + case '!': op = ONEG; goto call_cast; default: return postfix(); } call_cast: next(); - return op1(op, cast()); + return node1(op, cast()); call_unary: next(); - return op1(op, unary()); + return node1(op, unary()); } static struct node *cast(void) @@ -128,88 +122,88 @@ static struct node *cast(void) static struct node *mul(void) { register struct node *np; - register nodeop *op; + register unsigned char op; np = cast(); for (;;) { switch (yytoken) { - case '*': op = op_mul; break; - case '/': op = op_div; break; - case '%': op = op_mod; break; + case '*': op = OMUL; break; + case '/': op = ODIV; break; + case '%': op = OMOD; break; default: return np; } next(); - np = op2(op, np, cast()); + np = node2(op, np, cast()); } } static struct node *add(void) { - register nodeop *op; + register unsigned char op; register struct node *np; np = mul(); for (;;) { switch (yytoken) { - case '+': op = op_add; break; - case '-': op = op_sub; break; + case '+': op = OADD; break; + case '-': op = OSUB; break; default: return np; } next(); - np = op2(op, np, mul()); + np = node2(op, np, mul()); } } static struct node *shift(void) { - register nodeop *op; + register unsigned char op; register struct node *np; np = add(); for (;;) { switch (yytoken) { - case SHL: op = op_shl; break; - case SHR: op = op_shr; break; + case SHL: op = OSHL; break; + case SHR: op = OSHR; break; default: return np; } next(); - np = op2(op, np, add()); + np = node2(op, np, add()); } } static struct node *relational(void) { - register nodeop *op; + register unsigned char op; register struct node *np; np = shift(); for (;;) { switch (yytoken) { - case '<': op = op_lt; break; - case '>': op = op_gt; break; - case GE: op = op_ge; break; - case LE: op = op_le; break; + case '<': op = OLT; break; + case '>': op = OGT; break; + case GE: op = OGE; break; + case LE: op = OLE; break; default: return np; } next(); - np = op2(op, np, shift()); + np = node2(op, np, shift()); } } static struct node *eq(void) { - register nodeop *op; + register unsigned char op; register struct node *np; np = relational(); for (;;) { switch (yytoken) { - case EQ: op = op_eq; break; - case NE: op = op_ne; break; + case EQ: op = OEQ; break; + case NE: op = ONE; break; default: return np; } next(); - np = op2(op, np, relational()); + np = node2(op, np, relational()); } } @@ -220,7 +214,7 @@ static struct node *bit_and(void) np = eq(); while (yytoken == '&') { next(); - np = op2(op_band, np, eq()); + np = node2(OBAND, np, eq()); } return np; } @@ -232,7 +226,7 @@ static struct node *bit_xor(void) np = bit_and(); while (yytoken == '^') { next(); - np = op2(op_bxor, np, bit_and()); + np = node2(OBXOR, np, bit_and()); } return np; } @@ -244,7 +238,7 @@ static struct node *bit_or(void) np = bit_xor(); while (yytoken == '|') { next(); - np = op2(op_bor, np, bit_xor()); + np = node2(OBOR, np, bit_xor()); } return np; } @@ -256,7 +250,7 @@ static struct node *and(void) np = bit_or(); while (yytoken == AND) { next(); - np = op2(op_and, np, bit_or()); + np = node2(OAND, np, bit_or()); } return np; } @@ -268,7 +262,7 @@ static struct node *or(void) np = and(); while (yytoken == OR) { next(); - np = op2(op_or, np, and()); + np = node2(OOR, np, and()); } return np; } @@ -281,34 +275,34 @@ static struct node *cond(void) while (yytoken == '?') { aux = expr(); expect(':'); - np = op3(op_tern, np, aux, or()); + np = node3(OTERN, np, aux, or()); } return np; } static struct node *assign(void) { - register nodeop *op; + register unsigned char op; register struct node *np; np = cond(); for (;;) { switch (yytoken) { - case '=': op = op_assign; break; - case MUL_EQ: op = op_a_mul; break; - case DIV_EQ: op = op_a_div; break; - case MOD_EQ: op = op_a_mod; break; - case ADD_EQ: op = op_a_add; break; - case SUB_EQ: op = op_a_sub; break; - case SHL_EQ: op = op_a_shl; break; - case SHR_EQ: op = op_a_shr; break; - case AND_EQ: op = op_a_and; break; - case XOR_EQ: op = op_a_xor; break; - case OR_EQ: op = op_a_or; break; + case '=': op = OASSIGN; break; + case MUL_EQ: op = OA_MUL; break; + case DIV_EQ: op = OA_DIV; break; + case MOD_EQ: op = OA_MOD; break; + case ADD_EQ: op = OA_ADD; break; + case SUB_EQ: op = OA_SUB; break; + case SHL_EQ: op = OA_SHL; break; + case SHR_EQ: op = OA_SHR; break; + case AND_EQ: op = OA_AND; break; + case XOR_EQ: op = OA_XOR; break; + case OR_EQ: op = OA_OR; break; default: return np; } next(); - np = op2(op, np, assign()); + np = node2(op, np, assign()); } return np; } diff --git a/syntax.h b/syntax.h @@ -3,20 +3,35 @@ extern unsigned char nested_level; +enum { + OARY, OCALL, OFIELD, OPTR, OPOSTINC, OPOSTDEC, + OPREINC, OPREDEC, OADDR, OINDIR, OMINUS, OPLUS, + OCPL, ONEG, OMUL, ODIV, OMOD, OADD, OSUB, OSHL, + 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 +}; struct node; struct symbol; -typedef struct symbol *nodeop(struct node *np); - extern void compound(void); extern struct node *expr(void); extern unsigned char decl(void); extern void type_name(void); -extern struct node *leaf(struct symbol *sym); -extern struct node *op1(nodeop *op, struct node *np); -extern struct node *op2(nodeop *op, struct node *np1, struct node *np2); -extern struct node *op3(nodeop *op, - struct node *np1, struct node *np2, struct node *np3); +extern struct node * +node3(unsigned char op, struct node *l, struct node *i, struct node *r); + +extern struct node * +node2(unsigned char op, struct node *l, struct node *r); + +extern struct node * +node1(unsigned char op, struct node *i); + +extern struct node * +nodesym(struct symbol *sym); + + #endif diff --git a/tree.c b/tree.c @@ -6,82 +6,77 @@ #include "syntax.h" struct node { - nodeop *op; - struct node *child[]; + unsigned char op; }; -#define issym(np) (!(np)->op) -#define getsym(np) ((struct symbol *)(np)->child[0]) - - -static struct node * -node_alloc(unsigned char n) -{ - return xmalloc(sizeof(struct node) + sizeof(struct node *) * n); -} - -static struct node * -node1(struct node *np1) -{ - register struct node *np = node_alloc(1); +struct node_op1 { + struct node base; + struct node *infix; +}; - np->child[0] = np1; - return np; -} +struct node_op2 { + struct node base; + struct node *left; + struct node *rigth; +}; -static struct node * -node2(struct node *np1, struct node *np2) -{ - register struct node *np = node_alloc(2); +struct node_op3 { + struct node base; + struct node *left; + struct node *infix; + struct node *rigth; +}; - np->child[0] = np1; - np->child[1] = np2; - return np; -} +struct node_sym { + struct node base; + struct symbol *sym; +}; -static struct node * -node3(struct node *np1, struct node *np2, struct node *np3) -{ - register struct node *np = node_alloc(2); - np->child[0] = np1; - np->child[1] = np2; - np->child[2] = np3; - return np; -} +#define OSYM 1 struct node * -leaf(struct symbol *sym) +nodesym(struct symbol *sym) { - register struct node *new = node1(NULL); + register struct node_sym *np = xmalloc(sizeof(*np)); - new->child[0] = (struct node *) sym; - return new; + np->base.op = OSYM; + np->sym = sym; + return (struct node *) np; } struct node * -op1(nodeop op, struct node *np) +node3(unsigned char op, struct node *l, struct node *i, struct node *r) { - register struct node *new = node1(np); + register struct node_op3 *np = xmalloc(sizeof(*np)); + + np->base.op = op; + np->left = l; + np->infix = i; + np->rigth = r; - new->op = op; - return new; + return (struct node *) np; } struct node * -op2(nodeop op, struct node *np1, struct node *np2) +node2(unsigned char op, struct node *l, struct node *r) { - register struct node *new = node2(np1, np2); + register struct node_op2 *np = xmalloc(sizeof(*np)); - new->op = op; - return new; + np->base.op = op; + np->left = l; + np->rigth = r; + + return (struct node *) np; } struct node * -op3(nodeop op, struct node *np1, struct node *np2, struct node *np3) +node1(unsigned char op, struct node *i) { - register struct node *new = node3(np1, np2, np3); + register struct node_op1 *np = xmalloc(sizeof(*np)); + + np->base.op = op; + np->infix = i; - new->op = op; - return new; + return (struct node *) np; }