shithub: scc

Download patch

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;
 }