shithub: scc

Download patch

ref: 6124426ed00d4e0802766a6100b8032155f0bb44
parent: a62bbf6a5d79b1428f3a8016644daf4b44614d95
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jan 25 16:39:19 EST 2016

Simplify definitions in the IR

Having the definition of initializers in the nex line was causing
that was impossible to be able to emit variables until parsing
the next element, which forced us to deal with a lastsym variable
and several cases. It is better to know in the same line if
the symbol is initialized or not.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -187,7 +187,8 @@
 	ISDEFINED  =    2048,
 	ISSTRING   =    4096,
 	ISTYPEDEF  =    8192,
-	ISINITLST  =   16384
+	ISINITLST  =   16384,
+	ISINIT    =    32768
 };
 
 /* lexer mode, compiler or preprocessor directive */
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -365,7 +365,7 @@
 {
 	Node *np = arg;
 
-	puts("(");
+	puts("\t(");
 	emitdesig(np, np->type);
 	puts(")");
 }
@@ -384,8 +384,9 @@
 	printf("\t\"%s", (sym->name) ? sym->name : "");
 	if (sym->flags & ISFIELD)
 		printf("\t#%c%llX", sizettype->letter, sym->u.i);
-	putchar('\n');
 	sym->flags |= ISEMITTED;
+	if ((sym->flags & ISINIT) == 0)
+		putchar('\n');
 }
 
 static void
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -619,6 +619,7 @@
 	switch (yytoken) {
 	case STRING:
 		np = constnode(sym);
+		sym->flags |= ISINIT;
 		emit(ODECL, sym);
 		emit(OINIT, np);
 		np = decay(varnode(sym));
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -300,7 +300,6 @@
 	}
 	np = initialize(tp);
 
-	emit(ODECL, sym);
 	if (flags & ISDEFINED) {
 		errorp("redeclaration of '%s'", sym->name);
 	} else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {
@@ -308,6 +307,8 @@
 			errorp("initializer element is not constant");
 			return;
 		}
+		sym->flags |= ISINIT;
+		emit(ODECL, sym);
 		emit(OINIT, np);
 		sym->flags |= ISDEFINED;
 	} else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
@@ -314,6 +315,7 @@
 		errorp("'%s' has both '%s' and initializer",
 		       sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
 	} else {
+		emit(ODECL, sym);
 		np = node(OASSIGN, tp, varnode(sym), np);
 		emit(OEXPR, np);
 	}
--- a/cc1/tests/test001.c
+++ b/cc1/tests/test001.c
@@ -7,8 +7,7 @@
 {
 \
 V8	K	#N13
-Y7	V8	"
-(
+Y7	V8	"	(
 	#"hello world
 	#K0A
 	#K00
--- a/cc1/tests/test026.c
+++ b/cc1/tests/test026.c
@@ -10,13 +10,12 @@
 A4	I	"y
 A6	P	"p
 V8	K	#N10
-Y7	V8	"
-(
+Y7	V8	"	(
 	#"test026.c
 	#K00
 )
 	A6	Y7	'P	:P
-	A4	#I24	:I
+	A4	#I23	:I
 	A4	#I1	:I
 	A4	#I1	:I
 	A4	#I1	:I
--- a/cc1/tests/test027.c
+++ b/cc1/tests/test027.c
@@ -9,8 +9,7 @@
 \
 A5	P	"p
 V7	K	#N25
-Y6	V7	"
-(
+Y6	V7	"	(
 	#"hello is better than bye
 	#K00
 )
--- a/cc1/tests/test028.c
+++ b/cc1/tests/test028.c
@@ -8,8 +8,7 @@
 {
 \
 V8	K	#N3
-Y10	V8	"
-(
+Y10	V8	"	(
 	#"hi
 	#K00
 )
--- a/cc1/tests/test032.c
+++ b/cc1/tests/test032.c
@@ -8,8 +8,7 @@
 {
 \
 V9	K	#N44
-Y8	V9	"
-(
+Y8	V9	"	(
 	#"This is a string $ or # or ##and it is ok !
 	#K00
 )
--- a/cc1/tests/test038.c
+++ b/cc1/tests/test038.c
@@ -6,7 +6,7 @@
 test038.c:43: error: redeclaration of 'x'
 output:
 G1	I	"x
-(
+	(
 	#I0
 )
 G5	F	"foo
--- a/cc1/tests/test045.c
+++ b/cc1/tests/test045.c
@@ -3,8 +3,7 @@
 description: Basic test of initializers
 error:
 output:
-G1	I	"x
-(
+G1	I	"x	(
 	#I5
 )
 G3	F	"main
--- a/cc1/tests/test046.c
+++ b/cc1/tests/test046.c
@@ -4,8 +4,7 @@
 error:
 output:
 V1	I	#N3
-G2	V1	"x
-(
+G2	V1	"x	(
 	#I1
 	#I2
 	#I3
--- a/cc1/tests/test047.c
+++ b/cc1/tests/test047.c
@@ -7,8 +7,7 @@
 M3	I	"a	#N0
 M4	I	"b	#N2
 M5	I	"c	#N4
-G6	S2	"x
-(
+G6	S2	"x	(
 	#I1
 	#I2
 	#I3
--- a/cc1/tests/test048.c
+++ b/cc1/tests/test048.c
@@ -7,8 +7,7 @@
 M3	I	"a	#N0
 M4	I	"b	#N2
 V5	S2	#N1
-G6	V5	"x
-(
+G6	V5	"x	(
 	#I1
 	#I2
 )
--- a/cc1/tests/test049.c
+++ b/cc1/tests/test049.c
@@ -3,12 +3,10 @@
 description: Basic test for initializer
 error:
 output:
-G1	I	"x
-(
+G1	I	"x	(
 	#I5
 )
-G3	P	"p
-(
+G3	P	"p	(
 	G1	'P
 )
 G5	F	"main
--- a/cc1/tests/test051.c
+++ b/cc1/tests/test051.c
@@ -4,8 +4,7 @@
 error:
 output:
 V1	I	#N3
-G2	V1	"arr
-(
+G2	V1	"arr	(
 	#I0
 	#I1
 	#I2
--- a/cc1/tests/test052.c
+++ b/cc1/tests/test052.c
@@ -7,8 +7,7 @@
 M3	I	"a	#N0
 M4	I	"b	#N2
 V5	S2	#N2
-G6	V5	"arr
-(
+G6	V5	"arr	(
 	#I1
 	#I2
 	#I3
--- a/cc1/tests/test053.c
+++ b/cc1/tests/test053.c
@@ -6,8 +6,7 @@
 S2	"S	#N4	#N1
 M3	I	"a	#N0
 M4	I	"b	#N2
-G5	S2	"s
-(
+G5	S2	"s	(
 	#I1
 	#I2
 )
--- a/cc1/tests/test056.c
+++ b/cc1/tests/test056.c
@@ -10,8 +10,7 @@
 M5	I	"c	#N4
 M7	V6	"d	#N6
 M8	I	"e	#N9
-G9	S2	"s
-(
+G9	S2	"s	(
 	#I1
 	#I2
 	#I0
@@ -21,8 +20,7 @@
 	#I0
 )
 V10	K	#N0
-G11	V10	"m
-(
+G11	V10	"m	(
 )
 G13	F	"main
 {
--- a/cc1/tests/test057.c
+++ b/cc1/tests/test057.c
@@ -6,8 +6,7 @@
 output:
 V1	I	#N3
 V2	V1	#N2
-G3	V2	"arr1
-(
+G3	V2	"arr1	(
 	#I2
 	#I7
 	#I5
@@ -15,8 +14,7 @@
 	#I1
 	#I2
 )
-G4	V2	"arr2
-(
+G4	V2	"arr2	(
 	#I2
 	#I7
 	#I5
--- a/cc1/tests/test058.c
+++ b/cc1/tests/test058.c
@@ -6,8 +6,7 @@
 V1	I	#N5
 V2	V1	#N3
 V3	V2	#N2
-G4	V3	"arr
-(
+G4	V3	"arr	(
 	#I0
 	#I0
 	#I3
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -32,11 +32,11 @@
 
 typedef void parsefun(char *, union tokenop);
 static parsefun type, symbol, getname, unary, binary, ternary, call,
-                parameter, constant, composed;
+                parameter, constant, composed, begininit, endinit;
 
 typedef void evalfun(void);
-static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit,
-               endinit, array, aggregate, flddecl;
+static evalfun vardecl, beginfun, endfun, endpars, stmt,
+               array, aggregate, flddecl;
 
 static struct decoc {
 	void (*eval)(void);
@@ -76,8 +76,8 @@
 	[ONAME]       = {NULL, getname},
 	['{']         = {beginfun},
 	['}']         = {endfun},
-	['(']         = {begininit},
-	[')']         = {endinit},
+	['(']         = {NULL, begininit},
+	[')']         = {NULL, endinit},
 	[OEPARS]      = {endpars},
 	[OSTMT]       = {stmt},
 
@@ -280,15 +280,13 @@
 }
 
 static void
-begininit(void)
+begininit(char *token, union tokenop u)
 {
 	ininit = 1;
-	lastsym->type.flags |= INITF;
-	label(lastsym);
 }
 
 static void
-endinit(void)
+endinit(char *token, union tokenop u)
 {
 	ininit = 0;
 }
@@ -368,6 +366,32 @@
 }
 
 static void
+decl(Symbol *sym)
+{
+	switch (sym->kind) {
+	case EXTRN:
+		label(sym);
+		break;
+	case GLOB:
+	case PRIVAT:
+	case LOCAL:
+		label(sym);
+		if (!ininit)
+			allocdata(&sym->type);
+		break;
+	case AUTO:
+	case REG:
+		if (funpars >= 0) {
+			if (funpars == NR_FUNPARAM)
+				error(EOUTPAR);
+			params[funpars++] = sym;
+			break;
+		}
+		break;
+	}
+}
+
+static void
 vardecl(void)
 {
 	Type *tp;
@@ -375,20 +399,6 @@
 	Symbol *sym;
 	char *name;
 
-	if (lastsym && (lastsym->type.flags & INITF) == 0) {
-		switch (lastsym->kind) {
-		case EXTRN:
-			label(lastsym);
-			break;
-		case GLOB:
-		case PRIVAT:
-		case LOCAL:
-			label(lastsym);
-			allocdata(&lastsym->type);
-			break;
-		}
-	}
-
 	name = pop();
 	tp = pop();
 	np = pop();
@@ -397,13 +407,11 @@
 	sym->name = name;
 	sym->type = *tp;
 	sym->kind = sclass;
+	if (ininit)
+		sym->type.flags |= INITF;
 	lastsym = sym;
+	decl(sym);
 
-	if (funpars >= 0) {
-		if (funpars == NR_FUNPARAM)
-			error(EOUTPAR);
-		params[funpars++] = sym;
-	}
 	delnode(np);
 }
 
@@ -457,6 +465,7 @@
 	size_t len;
 	int c;
 	struct decoc *dp;
+	void (*fun)(void);
 
 	for (;;) {
 		if (!fgets(line, sizeof(line), stdin))
@@ -475,7 +484,8 @@
 			(*dp->parse)(t, dp->u);
 		}
 
-		(*optbl[c].eval)();
+		if ((fun = *optbl[c].eval) != NULL)
+			(*fun)();
 		if (sp != stack)
 			error(ESTACKA);
 		if (c == '}')