shithub: scc

Download patch

ref: 3a7f44ab39f632bf2fe8b6c7ea1b56822f78d0d1
parent: ffc846e846ca027ab5ac3a710b2a4269680c5bcb
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Jul 3 19:19:34 EDT 2013

Add intermediate code for symbol definition

We need some intermediate code for the symbol definitions, because
symbol definitions can have initializators, and the initializators
of extern symbols can't be attatched to the current function.

--- a/decl.c
+++ b/decl.c
@@ -150,10 +150,14 @@
 	return np;
 }
 
-static void
-listdcl(register struct ctype *tp)
+static struct node *
+listdcl(struct ctype *tp)
 {
+	struct node *lp = nodecomp();
+
 	do {
+		register struct node *sp, *np;
+
 		declarator();
 		tp = decl_type(tp);
 		if (!tp->type) {
@@ -160,28 +164,32 @@
 			warning_error(options.implicit,
 				      "type defaults to 'int' in declaration of '%s'",
 				      yytext);
-		} else if (tp->type == FTN && yytoken == '{') {
-			function(cursym);
-			return;
 		}
-		if (accept('='))
-			initializer(tp);
+		sp = nodesym(cursym);
+		if (tp->type == FTN && yytoken == '{') {
+			np  = node2(ODEF, sp, function(cursym));
+			return addstmt(lp, np);
+		}
+		np = node2(ODEF, sp, accept('=') ? initializer(tp) : NULL);
+		lp = addstmt(lp, np);
 	} while (accept(','));
 	expect(';');
+
+	return lp;
 }
 
-unsigned char
+struct node *
 decl(void)
 {
 	register struct ctype *tp;
+	register struct node *np = NULL;
 
-	if (accept(';'))
-		return 1;
-
+	while (accept(';'))
+		/* nothing */;
 	tp = newctype();
 	if (!spec(tp)) {
 		if (curctx != CTX_OUTER)
-			return 0;
+			goto end;
 		warning("data definition has no type or storage class");
 	}
 	if (accept(';')) {
@@ -188,11 +196,11 @@
 		warning_error(options.useless,
 			      "useless type name in empty declaration");
 	} else {
-		listdcl(tp);
+		np = listdcl(tp);
 	}
-	delctype(tp);
 
-	return 1;
+end:	delctype(tp);
+	return np;
 }
 
 void
--- a/flow.c
+++ b/flow.c
@@ -233,17 +233,17 @@
 static struct node *
 compound(void)
 {
-	register struct node *np = nodecomp();
+	register struct node *lp = nodecomp(), *np;
 
 	expect('{');
 	new_ctx();
-	while (decl())
-		/* nothing */;
+	while (np = decl())
+		addstmt(lp, np);
 	while (!accept('}'))
-		addstmt(np, stmt());
+		addstmt(lp, stmt());
 	del_ctx();
 
-	return np;
+	return lp;
 }
 
 static struct node *
@@ -271,13 +271,16 @@
 	return np;
 }
 
-void
+struct node *
 function(register struct symbol *sym)
 {
-	register struct node *np;
-
 	curfun = sym;
-	np = node2(OFTN, nodesym(sym), compound());
+	return node1(OFTN, compound());
+}
+
+void
+run(register struct node *np)
+{
 	prtree(np);
 	putchar('\n');
 	freesyms();
--- a/main.c
+++ b/main.c
@@ -6,18 +6,20 @@
 #include "syntax.h"
 
 extern void open_file(const char *file);
+extern void run(struct node *np);
 struct user_opt options;
 
 
 
-
 int
 main(int argc, char *argv[])
 {
+	struct node *np;
+
 	init_keywords();
 	open_file(NULL);
-	for (next(); yytoken != EOFTOK; decl())
-		/* nothing */;
+	for (next(); yytoken != EOFTOK; run(np))
+		np = decl();
 
 	return 0;
 }
--- a/syntax.h
+++ b/syntax.h
@@ -12,7 +12,7 @@
 	OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR, OA_AND,
 	OA_XOR, OA_OR, OSYM, OCOMP, OSWITCH, OIF, OFOR,
 	OFEXP, ODO, OWHILE, OLABEL, OGOTO, OBREAK, OCONT,
-	ORETURN, OCASE, ODEFAULT, OFTN
+	ORETURN, OCASE, ODEFAULT, OFTN, ODEF
 };
 
 struct node;
@@ -19,9 +19,9 @@
 struct symbol;
 
 extern struct node *expr(void);
-extern unsigned char decl(void);
+extern struct node *decl(void);
 extern void type_name(void);
-extern void function(struct symbol *sym);
+extern struct node *function(struct symbol *sym);
 
 extern struct node *node3(unsigned char op,
 			  struct node *l, struct node *i, struct node *r);
--- a/tree.c
+++ b/tree.c
@@ -190,7 +190,8 @@
 		[ORETURN] = {1, "return"},
 		[OCASE] = {1, "case"},
 		[ODEFAULT] = {1, "default"},
-		[OFTN] = {2, "function"}
+		[OFTN] = {1, "function"},
+		[ODEF] = {2, "def"}
 	};
 	if (!np) {
 		fputs(" nil", stdout);