ref: acfcdefc522706869302970518bb7b06c1455867
parent: b22f2a06bf01cfc183aee424bf99b6bc1ebb2ad7
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Mar 30 09:28:11 EDT 2014
Add tree structure to expressinons
--- a/cc.h
+++ b/cc.h
@@ -31,6 +31,8 @@
extern char *xstrdup(const char *s);
extern void *xrealloc(void *buff, register size_t size);
+/* definitions of types */
+
#define CTX_OUTER 0
#define CTX_FUNC 1
@@ -75,6 +77,8 @@
struct funpar *next;
};
+/* definition of symbols */
+
union value {
char c;
int i;
@@ -206,4 +210,31 @@
extern uint8_t next(void);
extern void expect(uint8_t tok);
+
+
+typedef struct node {
+ void (*code)(struct node *);
+ Type *type;
+ union unode {
+ Symbol *sym;
+ char op;
+ } u;
+ struct node *childs[];
+} Node;
+
+typedef void (*Inst)(Node *);
+
+enum {
+ OCAST, OPTR, OADD, OARY
+};
+
+extern void emitsym(Node *), emitunary(Node *), emitbin(Node *);
+extern Node
+ *node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds),
+ *unarycode(char op, Type *tp, Node *child),
+ *bincode(char op, Node *np1, Node *np2);
+
+#define SYM(s) ((union unode) {.sym = s})
+#define OP(s) ((union unode) {.op = s})
+
#endif
--- a/code.c
+++ b/code.c
@@ -4,9 +4,39 @@
#include "cc.h"
+Node *
+node(Inst code, Type *tp, union unode u, uint8_t nchilds)
+{
+ Node *np = xmalloc(sizeof(*np) + nchilds * sizeof(np));
+
+ np->code = code;
+ np->type = tp;
+ np->u = u;
+
+ return np;
+}
+
+Node *
+unarycode(char op, Type *tp, Node *child)
+{
+ Node *np = node(emitunary, tp, OP(op), 1);
+ np->childs[0] = child;
+ return np;
+}
+
+Node *
+bincode(char op, Node *np1, Node *np2)
+{
+ Node *np = node(emitbin, np1->type, OP(op), 2);
+ np->childs[0] = np1;
+ np->childs[1] = np2;
+ return np;
+}
+
void
-emitsym(Symbol *sym)
+emitsym(Node *np)
{
+ Symbol *sym = np->u.sym;
char c;
if (sym->s.isglobal)
@@ -18,6 +48,16 @@
else
c = 'A';
printf("\t%c%d", c, sym->id);
+}
+
+void
+emitunary(Node *np)
+{
+}
+
+void
+emitbin(Node *np)
+{
}
void
--- a/expr.c
+++ b/expr.c
@@ -3,17 +3,21 @@
#include "cc.h"
-void expr(void);
+#define SWAP(x1, x2, t) (t = x1, x1 = x2, x2 = t)
-static struct node *
+Node *expr(void);
+
+static Node *
primary(void)
{
- register struct node *np;
+ Node *np;
+ Symbol *sym;
switch (yytoken) {
case IDEN:
- if (yylval.sym == NULL)
+ if ((sym = yylval.sym) == NULL)
error("'%s' undeclared", yytext);
+ np = node(emitsym, sym->type, SYM(sym), 0);
next();
break;
case CONSTANT:
@@ -22,37 +26,134 @@
break;
case '(':
next();
- expr();
+ np = expr();
expect(')');
break;
default:
- np = NULL;
+ ;
}
return np;
}
+void
+intconv(Node **np1, Node **np2)
+{
+}
-static void
-ary(void)
+void
+floatconv(Node **np1, Node **np2)
{
}
-static void
+static Node *
+add(Node *np1, Node *np2)
+{
+ Node *naux;
+ Type *tp1, *tp2;
+ uint8_t t1, t2, taux;
+
+ tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np1->type);
+ t1 = tp1->op, t2 = tp2->op;
+
+ switch (t1) {
+ case BOOL: case INT:
+ switch (t2) {
+ case BOOL: case INT:
+ if (tp1 != tp2)
+ intconv(&np1, &np2);
+ break;
+ case FLOAT:
+ SWAP(np1, np2, naux);
+ goto int_float;
+ case PTR: case FTN: case ARY:
+ SWAP(np1, np2, naux);
+ SWAP(t1, t2, taux);
+ goto pointer;
+ default:
+ goto incorrect;
+ }
+ break;
+ case FLOAT:
+ switch (t2) {
+ case FLOAT:
+ if (tp1 != tp2)
+ floatconv(&np1, &np2);
+ break;
+ case BOOL: case INT:
+int_float: np2 = unarycode(OCAST, np1->type, np2);
+ break;
+ default:
+ goto incorrect;
+ }
+ break;
+ case PTR: case FTN: case ARY:
+pointer: if (t1 == PTR)
+ np1 = unarycode(OPTR, np1->type, np1);
+ if (t2 != INT)
+ goto incorrect;
+ np2 = unarycode(OCAST, np1->type, np2);
+ break;
+ default:
+ goto incorrect;
+ }
+
+ return bincode(OADD, np1, np2);
+
+incorrect:
+ error("incorrect arithmetic operands"); /*TODO: print type names */
+}
+
+static Node *
+array(Node *np1, Node *np2)
+{
+ Type *tp;
+ uint8_t t1, t2;
+ char *err;
+
+ t1 = BTYPE(np1->type);
+ t2 = BTYPE(np2->type);
+ if (!isaddr(t1) && !isaddr(t2))
+ goto bad_vector;
+ if (t1 != INT && t2 != INT)
+ goto bad_subs;
+ np1 = add(np1, np2);
+ return unarycode(OARY, UNQUAL(np1->type)->type , np1);
+
+bad_vector:
+ err = "subscripted value is neither array nor pointer nor vector";
+ goto error;
+bad_subs:
+ err = "array subscript is not an integer";
+error: error(err);
+}
+
+static Node *
postfix(void)
{
- primary();
+ Node *np1, *np2;
+
+ np1 = primary();
for (;;) {
switch (yytoken) {
- case '[': next(); ary(); break;
- default: return;
+ case '[':
+ next();
+ np2 = expr();
+ np1 = array(np1, np2);
+ expect(']');
+ break;
+ default:
+ return np1;
}
- }
+ }
}
-void
+Node *
expr(void)
{
+ Node *np;
+
do
- postfix();
+ np = postfix();
while (yytoken == ',');
+ return np;
}