ref: cfaeee0e4fd0919a5eadf402eb76f8652e90d657
parent: d956ad1f14fceb8368cd60c31cf765df818586c7
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Mar 8 06:50:20 EDT 2015
Unify all the functions in node All these functions were builders of nodes, and basically they only differes in the function associated to every kind of node and the number of childs. These differences can be written in a table, and unify all the code in only one function.
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -160,7 +160,7 @@
} Node;
enum {
- OCAST = 1, OPTR, OADD, OSIZE, OMUL, OSUB,
+ OPTR = 1, OADD, OSIZE, OMUL, OSUB,
OINC, ODEC, ODIV, OMOD, OSHL, OSHR,
OBAND, OBXOR, OBOR, OASSIGN, OA_MUL, OA_DIV,
OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR,
@@ -187,16 +187,12 @@
emitdefault(Symbol *),
emitstruct(Symbol *sym), emitestruct(void);
-extern Node
- *node(void (*code)(Node *),
- Type *tp, union unode u, uint8_t nchilds),
- *unarycode(char op, Type *tp, Node *child),
- *bincode(char op, Type *tp, Node *np1, Node *np2),
- *castcode(Node *child, Type *tp),
- *sizeofcode(Type *tp),
- *ternarycode(Node *cond, Node *ifyes, Node *ifno),
- *symcode(Symbol *sym),
- *fieldcode(Node *child, Symbol *field);
+enum {
+ CAST, FIELD, UNARY, BINARY,
+ SIZEOFCODE, SYMBOL, TERNARY
+};
+
+extern Node *node(char kind, Type *tp, ...);
extern void freetree(Node *np);
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -2,15 +2,11 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include "../inc/cc.h"
#include "cc1.h"
-#define SYM(s) ((union unode) {.sym = s})
-#define TYP(s) ((union unode) {.type = s})
-#define OP(s) ((union unode) {.op = s})
-#define FIELD(s) ((union unode) {.field = s})
-
char *opcodes[] = {
[OADD] = "+",
[OSUB] = "-",
@@ -51,21 +47,6 @@
[OCOMMA] = ","
};
-Node *
-node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
-{
- Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
-
- np->code = code;
- np->type = tp;
- np->typeop = tp->op;
- np->nchilds = nchilds;
- np->u = u;
- np->b.symbol = np->b.lvalue = 0;
-
- return np;
-}
-
void
freetree(Node *np)
{
@@ -156,7 +137,7 @@
Node *child = np->childs[0];
(*child->code)(child);
- printf("\t%c%c", np->u.type->letter, np->type->letter);
+ printf("\t%c%c", child->type->letter, np->type->letter);
}
void
@@ -300,67 +281,89 @@
emitvar(np->u.sym);
}
-Node *
-fieldcode(Node *child, Symbol *field)
-{
- Node *np = node(emitfield, field->type, SYM(field), 1);
- np->childs[0] = child;
- return np;
-}
+enum {
+ SYM, TYP, OP
+};
-Node *
-castcode(Node *child, Type *tp)
-{
- Node *np = node(emitcast, tp, TYP(child->type), 1);
- np->childs[0] = child;
- return np;
-}
+/*TODO: Remove type of union unode */
-Node *
-unarycode(char op, Type *tp, Node *child)
-{
- Node *np = node(emitunary, tp, OP(op), 1);
- np->childs[0] = child;
- return np;
-}
+struct kindnode {
+ uint8_t nchilds;
+ char unode;
+ void (*code)(Node *);
+} kindnodes [] = {
+ [CAST]= {
+ .nchilds = 1,
+ .code = emitcast
+ },
+ [FIELD] = { /*TODO: Create a node for the symbol */
+ .nchilds = 1,
+ .unode = SYM,
+ .code = emitfield
+ },
+ [UNARY] = {
+ .nchilds = 1,
+ .unode = OP,
+ .code = emitunary
+ },
+ [BINARY] = {
+ .nchilds = 2,
+ .unode = OP,
+ .code = emitbin
+ },
+ [SIZEOFCODE] = {
+ .nchilds = 0,
+ .unode = TYP,
+ .code = emitsizeof
+ },
+ [SYMBOL] = {
+ .nchilds = 0,
+ .unode = SYM,
+ .code = emitsym
+ },
+ [TERNARY] = {
+ .nchilds = 3,
+ .code = emitternary
+ }
+};
Node *
-bincode(char op, Type *tp, Node *np1, Node *np2)
+node(char kind, Type *tp, ...)
{
- Node *np = node(emitbin, tp, OP(op), 2);
- np->childs[0] = np1;
- np->childs[1] = np2;
- return np;
-}
+ uint8_t nchilds, i;
+ va_list va;
+ struct kindnode *kp;
+ Node *np;
-Node *
-sizeofcode(Type *tp)
-{
- if (!tp->defined)
- error("invalid use of indefined type");
- if (tp->op == FTN)
- error("sizeof of a function");
- return node(emitsizeof, inttype, TYP(tp), 0);
-}
+ va_start(va, tp);
+ kp = &kindnodes[kind];
+ nchilds = kp->nchilds;
+ np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
-Node *
-ternarycode(Node *cond, Node *ifyes, Node *ifno)
-{
- Node *np= node(emitternary, ifyes->type, OP(0), 3);
- np->childs[0] = cond;
- np->childs[1] = ifyes;
- np->childs[2] = ifno;
- return np;
-}
+ np->code = kp->code;
+ np->nchilds = nchilds;
+ np->type = tp;
+ np->typeop = tp->op;
+ np->b.symbol = np->b.lvalue = 0;
-Node *
-symcode(Symbol *sym)
-{
- Node *np;
+ switch (kp->unode) {
+ case TYP:
+ np->u.type = va_arg(va, Type *);
+ break;
+ case SYM:
+ np->u.sym = va_arg(va, Symbol *);
+ np->b.symbol = 1;
+ np->b.constant = 1;
+ break;
+ case OP:
+ np->u.op = va_arg(va, int);
+ break;
+ }
- np = node(emitsym, sym->type, SYM(sym), 0);
- np->b.symbol = 1;
- np->b.constant = 1;
+ for (i = 0; i < nchilds; ++i)
+ np->childs[i] = va_arg(va, Node *);
+
+ va_end(va);
return np;
}
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -5,6 +5,8 @@
#include "../inc/cc.h"
#include "cc1.h"
+#define Q(sym) node(SYMBOL, inttype, (sym))
+
static Symbol *zero, *one;
Node *expr(void);
@@ -35,7 +37,8 @@
r = tp->n.rank;
if (r > RANK_UINT || tp == inttype || tp == uinttype)
return np;
- return castcode(np, (r == RANK_UINT) ? uinttype : inttype);
+ tp = (r == RANK_UINT) ? uinttype : inttype;
+ return node(CAST, tp, np);
}
static void
@@ -52,9 +55,9 @@
tp2 = np2->type;
if (tp1 != tp2) {
if ((n = tp1->n.rank - tp2->n.rank) > 0)
- np2 = castcode(np2, tp1);
+ np2 = node(CAST, tp1, np2);
else if (n < 0)
- np1 = castcode(np1, tp2);
+ np1 = node(CAST, tp2, np1);
}
*p1 = np1;
*p2 = np2;
@@ -76,7 +79,7 @@
return NULL;
if (!ISNODELOG(np))
return np;
- return ternarycode(np, symcode(one), symcode(zero));
+ return node(TERNARY, inttype, np, Q(one), Q(zero));
}
static Node *
@@ -87,7 +90,7 @@
if (np1->typeop != INT || np2->typeop != INT)
error("operator requires integer operands");
typeconv(&np1, &np2);
- return bincode(op, np1->type, np1, np2);
+ return node(BINARY, np1->type, op, np1, np2);
}
static Node *
@@ -96,7 +99,9 @@
np = eval(np);
switch (np->typeop) {
case INT: case FLOAT:
- return (op == OADD) ? np : unarycode(op, np->type, np);
+ if (op == OADD)
+ return np;
+ return node(UNARY, np->type, op, np);
default:
error("unary operator requires integer operand");
}
@@ -108,13 +113,13 @@
np = eval(np);
if (np->typeop != INT)
error("unary operator requires integer operand");
- return unarycode(op, np->type, np);
+ return node(UNARY, np->type, op, np);
}
static Node *
decay(Node *np)
{
- return unarycode(OADDR, mktype(np->type, PTR, 0, NULL), np);
+ return node(UNARY, mktype(np->type, PTR, 0, NULL), OADDR, np);
}
/*
@@ -162,7 +167,7 @@
default:
return NULL;
}
- return castcode(np, tp);
+ return node(CAST, tp, np);
}
static Node *
@@ -172,7 +177,7 @@
Node *size;
tp = np1->type;
- size = sizeofcode(tp->type);
+ size = node(SIZEOFCODE, inttype, tp->type);
if (np2->typeop == ARY)
np2 = decay(np2);
@@ -179,14 +184,14 @@
if (op == OSUB && np2->typeop == PTR) {
if (tp != np2->type)
goto incorrect;
- np1 = bincode(OSUB, inttype, np1, np2);
- return bincode(ODIV, inttype, np1, size);
+ np1 = node(BINARY, inttype, OSUB, np1, np2);
+ return node(BINARY, inttype, ODIV, np1, size);
}
if (np2->typeop != INT)
goto incorrect;
- np2 = castcode(promote(np2), tp);
- np2 = bincode(OMUL, tp, np2, size);
- return bincode(op, tp, np1, np2);
+ np2 = node(CAST, tp, promote(np2));
+ np2 = node(BINARY, tp, OMUL, np2, size);
+ return node(BINARY, tp, op, np1, np2);
incorrect:
error("incorrect arithmetic operands");
@@ -221,7 +226,7 @@
error("incorrect arithmetic operands");
}
- return bincode(op, np1->type, np1, np2);
+ return node(BINARY, np1->type, op, np1, np2);
}
static Node *
@@ -228,7 +233,7 @@
pcompare(char op, Node *np1, Node *np2)
{
if (np2->typeop == INT && np2->b.symbol && np2->u.sym->u.i == 0) {
- np2 = castcode(np2, pvoidtype);
+ np2 = node(CAST, pvoidtype, np2);
} else if (np2->typeop != PTR) {
error("incompatibles type in comparision");
} else {
@@ -236,7 +241,7 @@
"comparision between different pointer types");
}
- return bincode(op, np1->type, np1, np2);
+ return node(BINARY, np1->type, op, np1, np2);
}
static Node *
@@ -267,7 +272,7 @@
error("incompatibles type in comparision");
}
- return bincode(op, inttype, np1, np2);
+ return node(BINARY, inttype, op, np1, np2);
}
static Node *
@@ -278,7 +283,7 @@
return np;
}
- return compare(ONE ^ neg, np, symcode(zero));
+ return compare(ONE ^ neg, np, Q(zero));
}
static Node *
@@ -286,7 +291,7 @@
{
np1 = exp2cond(np1, 0);
np2 = exp2cond(np2, 0);
- return bincode(op, inttype, np1, np2);
+ return node(BINARY, inttype, op, np1, np2);
}
static Node *
@@ -305,7 +310,7 @@
error("incorrect field in struct/union");
lex_ns = NS_IDEN;
next();
- return fieldcode(np, sym);
+ return node(FIELD, sym->type, sym, np);
default:
error("struct or union expected");
}
@@ -322,7 +327,7 @@
tp = np1->type;
if (tp->op != PTR)
error("subscripted value is neither array nor pointer nor vector");
- np1 = unarycode(OPTR, tp->type , np1);
+ np1 = node(UNARY, tp->type, OPTR, np1);
np1->b.lvalue = 1;
return np1;
}
@@ -332,7 +337,7 @@
{
if (ISNODECMP(np))
return np;
- return compare(ONE, np, symcode(zero));
+ return compare(ONE, np, Q(zero));
}
static Node *
@@ -346,7 +351,7 @@
if ((np2 = convert(np2, np1->type, 0)) == NULL)
error("incompatible types when assigning");
}
- return bincode(op, np1->type, np1, np2);
+ return node(BINARY, np1->type, op, np1, np2);
}
static Node *
@@ -361,10 +366,10 @@
case PTR:
if (!tp->defined)
error("invalid use of indefined type");
- inc = sizeofcode(tp->type);
+ inc = node(SIZEOFCODE, inttype, tp->type);
break;
case INT: case FLOAT:
- inc = symcode(one);
+ inc = Q(one);
break;
default:
error("incorrect type in arithmetic operation");
@@ -379,7 +384,7 @@
error("lvalue required in unary expression");
if (np->b.symbol && np->u.sym->isregister)
error("address of register variable '%s' requested", yytext);
- return unarycode(op, mktype(np->type, PTR, 0, NULL), np);
+ return node(UNARY, mktype(np->type, PTR, 0, NULL), op, np);
}
static Node *
@@ -389,7 +394,7 @@
case ARY: case FTN:
np = decay(np);
case PTR:
- np = unarycode(op, np->type->type, np);
+ np = node(UNARY, np->type, op, np);
np->b.lvalue = 1;
return np;
default:
@@ -423,7 +428,7 @@
case STRING: case CONSTANT: case IDEN:
if ((sym = yylval.sym) == NULL)
error("'%s' undeclared", yytext);
- np = symcode(yylval.sym);
+ np = node(SYMBOL, yylval.sym->type, yylval.sym);
if (yytoken == IDEN) {
np->b.lvalue = 1;
np->b.constant = 0;
@@ -539,7 +544,7 @@
case SIZEOF:
next();
tp = (yytoken == '(') ? sizeexp() : typeof(unary());
- return sizeofcode(tp);
+ return node(SIZEOFCODE, inttype, tp);
case INC: case DEC:
op = (yytoken == INC) ? OA_ADD : OA_SUB;
next();
@@ -750,7 +755,7 @@
expect(':');
ifno = promote(ternary());
typeconv(&ifyes, &ifno);
- np = ternarycode(iszero(np), ifyes, ifno);
+ np = node(TERNARY, ifyes->type, np, ifyes, ifno);
}
return np;
}
@@ -791,7 +796,7 @@
np1 = assign();
while (accept(',')) {
np2 = assign();
- np1 = bincode(OCOMMA, np2->type, np1, np2);
+ np1 = node(BINARY, np2->type, OCOMMA, np1, np2);
}
return np1;