shithub: scc

Download patch

ref: 1f4874cced9c4f1308556b07e835bb47547becc0
parent: 3e7e69413c50005c9e35de23fab8fc8ec9604f68
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Jun 12 17:53:47 EDT 2012

Rewrite the expression parser

This parser applies the rule in the correct order and runs actions each time
that one of the rule matches.

--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 
-OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o keyword.o
+OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o keyword.o code.o
 LIBS =
 
 all: kcc
--- /dev/null
+++ b/code.c
@@ -1,0 +1,253 @@
+
+#include "cc.h"
+#include "code.h"
+#include "symbol.h"
+
+
+#define NR_MACHINE_OP 30
+#define NR_SYM_STACK 30
+
+static struct symbol *stack[NR_SYM_STACK];
+static struct symbol **stackp = stack;
+
+void push(register struct symbol *sym)
+{
+	if (stackp == &stack[NR_SYM_STACK])
+		error("out of memory");
+	*stackp++ = sym;
+}
+
+void code(void *data)
+{
+}
+
+void execute(void)
+{
+}
+
+
+
+void gen_ary(void)
+{
+	puts("gen_ary");
+}
+
+void gen_call(void)
+{
+	puts("gen_call");
+}
+
+void gen_or(void)
+{
+	puts("gen_or");
+}
+
+void gen_tern(void)
+{
+	puts("gen_tern");
+}
+
+void gen_band(void)
+{
+	puts("gen_band");
+}
+
+void gen_bxor(void)
+{
+	puts("gen_bxor");
+}
+
+void gen_bor(void)
+{
+	puts("gen_bor");
+}
+
+void gen_and(void)
+{
+	puts("gen_and");
+}
+
+void gen_sizeof(void)
+{
+	puts("gen_sizeof");
+}
+
+void gen_field(void)
+{
+	puts("gen_field");
+}
+
+void gen_ptr(void)
+{
+	puts("gen_ptr");
+}
+
+void gen_preinc(void)
+{
+	puts("gen_preinc");
+}
+
+void gen_predec(void)
+{
+	puts("gen_predec");
+}
+
+void gen_addr(void)
+{
+	puts("gen_addr");
+}
+
+void gen_indir(void)
+{
+	puts("gen_indir");
+}
+
+void gen_minus(void)
+{
+	puts("gen_minus");
+}
+
+void gen_plus(void)
+{
+	puts("gen_plus");
+}
+
+void gen_cpl(void)
+{
+	puts("gen_cpl");
+}
+
+void gen_neg(void)
+{
+	puts("gen_neg");
+}
+
+void gen_mul(void)
+{
+	puts("gen_mul");
+}
+
+void gen_div(void)
+{
+	puts("gen_div");
+}
+
+void gen_mod(void)
+{
+	puts("gen_mod");
+}
+
+void gen_add(void)
+{
+	puts("gen_add");
+}
+
+void gen_sub(void)
+{
+	puts("gen_sub");
+}
+
+void gen_shl(void)
+{
+	puts("gen_shl");
+}
+
+void gen_shr(void)
+{
+	puts("gen_shr");
+}
+
+void gen_lt(void)
+{
+	puts("gen_lt");
+}
+
+void gen_gt(void)
+{
+	puts("gen_gt");
+}
+
+void gen_ge(void)
+{
+	puts("gen_ge");
+}
+
+void gen_le(void)
+{
+	puts("gen_le");
+}
+
+void gen_eq(void)
+{
+	puts("gen_eq");
+}
+
+void gen_ne(void)
+{
+	puts("gen_ne");
+}
+
+void gen_a_mul(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_div(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_mod(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_add(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_sub(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_shl(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_shr(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_and(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_xor(void)
+{
+	puts("gen_a");
+}
+
+void gen_a_or(void)
+{
+	puts("gen_a");
+}
+
+void gen_postinc(void)
+{
+	puts("gen_postinc");
+}
+
+void gen_postdec(void)
+{
+	puts("gen_postdec");
+}
+
+void gen_assign(void)
+{
+	puts("gen_assign");
+}
--- /dev/null
+++ b/code.h
@@ -1,0 +1,8 @@
+#ifndef CODE_H
+#define CODE_H
+
+struct symbol;
+extern void push(register struct symbol *sym);
+extern void runcode(void);
+
+#endif
--- a/expr.c
+++ b/expr.c
@@ -1,10 +1,24 @@
 #include <stddef.h>
+#include <stdio.h>
 
+#include "cc.h"
 #include "tokens.h"
 #include "symbol.h"
 #include "syntax.h"
+#include "code.h"
 
-#include <stdio.h>		/* TODO: remove this */
+extern void gen_ary(void), gen_call(void), gen_or(void), gen_tern(void),
+	gen_band(void), gen_bxor(void), gen_bor(void), gen_and(void),
+	gen_sizeof(void), gen_field(void), gen_ptr(void), gen_preinc(void),
+	gen_predec(void), gen_addr(void), gen_indir(void), gen_minus(void),
+	gen_plus(void), gen_cpl(void), gen_neg(void), gen_mul(void),
+	gen_div(void), gen_mod(void), gen_add(void), gen_sub(void),
+	gen_shl(void), gen_shr(void), gen_lt(void), gen_gt(void),
+	gen_ge(void), gen_le(void), gen_eq(void), gen_ne(void),
+	gen_a_mul(void), gen_a_div(void), gen_a_mod(void), gen_a_add(void),
+	gen_a_sub(void), gen_a_shl(void), gen_a_shr(void), gen_a_and(void),
+	gen_a_xor(void), gen_a_or(void), gen_postinc(void),
+	gen_postdec(void), gen_assign(void);
 
 
 void expr(void);
@@ -11,6 +25,7 @@
 
 static void primary(void)
 {
+	fputs("static void primary(void)", stderr);
 	switch (yytoken) {
 	case IDEN:
 		if (!yyval.sym)
@@ -17,6 +32,7 @@
 			error("'%s' undeclared", yytext);
 	case CONSTANT:
 		next();
+		push(yyval.sym);
 		break;
 	case '(':
 		next();
@@ -24,35 +40,44 @@
 		expect(')');
 		break;
 	}
+	fputs("leaving static void primary(void)", stderr);
 }
 
 static void postfix(void)
 {
-	primary();
+	fputs("static void postfix(void)", stderr);
+	primary();		/* TODO: fix ( case */
 	for (;;) {
+		register void (*fp)(void);
 		switch (yytoken) {
 		case '[':
 			next();
 			expr();
 			expect(']');
-			break;
+			gen_ary();
+			continue;
 		case '(':
 			next();
 			expr();
 			expect(')');
-			break;
-		case '.':
-		case PTR:
-			next();
-			expect(IDEN);
-			break;
-		case INC:
-		case DEC:
-			next();
-			break;
+			gen_call();
+			continue;
+		case '.': fp = gen_field; goto expect_iden;
+		case PTR: fp = gen_ptr; goto expect_iden;
+		case INC: fp = gen_postinc; goto next;
+		case DEC: fp = gen_postdec; goto next;
 		default:
+			fputs("leaving static void postfix(void)", stderr);
 			return;
 		}
+	expect_iden:
+		next();
+		expect(IDEN);
+		fp();
+		continue;
+	next:
+		next();
+		continue;
 	}
 }
 
@@ -60,7 +85,9 @@
 
 static void unary(void)
 {
+	fputs("static void unary(void)", stderr);
 	for (;;) {
+		register void (*fp)(void);
 		switch (yytoken) {
 		case SIZEOF:
 			next();
@@ -67,139 +94,250 @@
 			if (accept('(')) {
 				type_name();
 				expect(')');
-				return;
+			} else {
+				unary();
 			}
-			break;
-		case INC:
-		case DEC:
-			next();
-			break;
-		case '&': case '*': case '-': case '~': case '!': case '+':
-			next();
-			cast();
-			return;
+			gen_sizeof();
+			continue;
+		case INC: fp = gen_preinc; goto call_unary;
+		case DEC: fp = gen_predec; goto call_unary;
+		case '&': fp = gen_addr;  goto call_cast;
+		case '*': fp = gen_indir; goto call_cast;
+		case '-': fp = gen_minus; goto call_cast;
+		case '+': fp = gen_plus; goto call_cast;
+		case '~': fp = gen_cpl; goto call_cast;
+		case '!': fp = gen_neg; goto call_cast;
 		default:
 			postfix();
+			fputs("leaving static void unary(void)", stderr);
 			return;
 		}
+	call_cast:
+		next();
+		cast();
+		fp();
+		return;
+	call_unary:
+		next();
+		unary();
+		fp();
+		return;
 	}
 }
 
 static void cast(void)
 {
+	fputs("static void cast(void)", stderr);
 	while (accept('(')) {
 		type_name();	/* check if it really is a type name */
 		expect(')');
 	}
 	unary();
+	fputs("leaving static void cast(void)", stderr);
 }
 
 static void mul(void)
 {
-	do
+	fputs("static void mul(void)", stderr);
+	cast();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case '*': fp = gen_mul; break;
+		case '/': fp = gen_div; break;
+		case '%': fp = gen_mod; break;
+		default:
+			fputs("leaving static void mul(void)", stderr);
+			return;
+		}
+		next();
 		cast();
-	while(accept('*') || accept('/') || accept('%'));
+		fp();
+	}
 }
 
 static void add(void)
 {
-	do
+	fputs("static void add(void)", stderr);
+	mul();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case '+': fp = gen_add; break;
+		case '-': fp = gen_sub; break;
+		default:
+			fputs("leaving static void add (void)", stderr);
+			return;
+		}
+		next();
 		mul();
-	while (accept('+') || accept('-'));
+		fp();
+	}
 }
 
 static void shift(void)
 {
-	do
+	fputs("static void shift(void)", stderr);
+	add();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case LSHIFT: fp = gen_shl; break;
+		case RSHIFT: fp = gen_shr; break;
+		default:
+			fputs("leaving static void shift (void)", stderr);
+			return;
+		}
+		next();
 		add();
-	while (accept(LSHIFT) || accept(RSHIFT));
+		fp();
+	}
 }
 
 static void relational(void)
 {
-	do
+	fputs("static void relational(void)", stderr);
+	shift();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case '<': fp = gen_lt; break;
+		case '>': fp = gen_gt; break;
+		case GE: fp = gen_ge; break;
+		case LE: fp = gen_le; break;
+		default:
+			fputs("leaving static void relational (void)", stderr);
+			return;
+		}
+		next();
 		shift();
-	while (accept('<') || accept('>') || accept(GE) || accept(LE));
+		fp();
+	}
 }
 
-static void equality(void)
+static void eq(void)
 {
-	do
+	fputs("static void eq(void)", stderr);
+	relational();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case EQ: fp = gen_eq; break;
+		case NE: fp = gen_ne; break;
+		default:
+			fputs("leaving static void eq (void)", stderr);
+			return;
+		}
+		next();
 		relational();
-	while (accept(EQ) || accept(NE));
+		fp();
+	}
 }
 
 static void bit_and(void)
 {
-	do
-		equality();
-	while (accept('&'));
+	fputs("static void bit_and(void)", stderr);
+	eq();
+	while (yytoken == '&') {
+		next();
+		eq();
+		gen_band();
+	}
+	fputs("leaving static void bit_and (void)", stderr);
 }
 
-static void bit_exor(void)
+static void bit_xor(void)
 {
-	do
+	fputs("static void bit_xor(void)", stderr);
+	bit_and();
+	while (yytoken == '^') {
+		next();
 		bit_and();
-	while (accept('^'));
+		gen_bxor();
+	}
+	fputs("leaving static void bit_xor(void)", stderr);
 }
 
 static void bit_or(void)
 {
-	do
-		bit_exor();
-	while (accept('|'));
+	fputs("static void bit_or(void)", stderr);
+	bit_xor();
+	while (yytoken == '|') {
+		next();
+		bit_xor();
+		gen_bor();
+	}
+	fputs("leaving static void bit_or(void)", stderr);
 }
 
 static void and(void)
 {
-	do
+	fputs("static void and(void)", stderr);
+	bit_or();
+	while (yytoken == AND) {
+		next();
 		bit_or();
-	while (accept(AND));
+		gen_and();
+	}
+	fputs("leaving static void and(void)", stderr);
 }
 
 static void or(void)
 {
-	do
+	fputs("static void or(void)", stderr);
+	and();
+	while (yytoken == OR) {
+		next();
 		and();
-	while (accept(OR));
+		gen_or();
+	}
+	fputs("leaving static void or(void)", stderr);
 }
 
-static void conditional(void)
+static void cond(void)
 {
+	fputs("static void cond(void)", stderr);
 	or();
-	if (accept('?')) {
-		expr();
-		expect(':');
-		conditional();
+	while (yytoken == '?') {
+			expr();
+			expect(':');
+			or();
+			gen_tern();
 	}
+	fputs("leaving static void cond(void)", stderr);
 }
 
 static void assign(void)
 {
-	unary();
-	switch (yytoken) {
-	case '=':
-	case MUL_EQ:
-	case DIV_EQ:
-	case MOD_EQ:
-	case ADD_EQ:
-	case SUB_EQ:
-	case LSHIFT_EQ:
-	case RSHIFT_EQ:
-	case AND_EQ:
-	case XOR_EQ:
-	case OR_EQ:
+	fputs("static void assign(void)", stderr);
+	cond();
+	for (;;) {
+		register void (*fp)(void);
+		switch (yytoken) {
+		case '=': fp = gen_assign; break;
+		case MUL_EQ: fp = gen_a_mul; break;
+		case DIV_EQ: fp = gen_a_div; break;
+		case MOD_EQ: fp = gen_a_mod; break;
+		case ADD_EQ: fp = gen_a_add; break;
+		case SUB_EQ: fp = gen_a_sub; break;
+		case LSHIFT_EQ: fp = gen_a_shl; break;
+		case RSHIFT_EQ: fp = gen_a_shr; break;
+		case AND_EQ: fp = gen_a_and; break;
+		case XOR_EQ: fp = gen_a_xor; break;
+		case OR_EQ: fp = gen_a_or; break;
+		default:
+			fputs("static void assign (void)", stderr);
+			return;
+		}
 		next();
 		assign();
-		break;
-	default:
-		conditional();
-		break;
+		fp();
 	}
 }
 
 void expr(void)
 {
+	fputs("void expr(void)", stderr);
 	do
 		assign();
 	while (yytoken == ',');