shithub: scc

Download patch

ref: 38c240c4f09858a4ce71d70ee7fe16e7df7c9bff
parent: ba98fe9738f78620b50c8351d46c95f923052dd7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Jan 17 06:59:04 EST 2016

Move initializer code to a new file

This code is going to be too long, and it is not totally related
to expressions, so it is better to create a new file.

--- a/cc1/Makefile
+++ b/cc1/Makefile
@@ -3,7 +3,7 @@
 include ../config.mk
 
 OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
-	code.o stmt.o cpp.o fold.o
+	code.o stmt.o cpp.o fold.o init.o
 
 all: cc1
 
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -374,13 +374,14 @@
 extern TUINT ones(int nbytes);
 
 /* expr.c */
-extern Node *expr(void), *negate(Node *np), *constexpr(void);
+extern Node *decay(Node *), *negate(Node *np), *assign(Node *np);;
 extern Node *convert(Node *np, Type *tp1, char iscast);
-extern Node *iconstexpr(void), *condexpr(void);
+extern Node *iconstexpr(void), *condexpr(void), *expr(void);
 extern bool isnodecmp(int op);
 extern int negop(int op);
 extern bool cmpnode(Node *np, TUINT val);
-extern Node *decay(Node *np);
+
+/* init.c */
 extern void initializer(Symbol *sym, Type *tp, int nelem);
 
 /* cpp.c */
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -779,7 +779,7 @@
 
 	if (sym->token == IDEN && sym->type->op != FTN)
 		emit(ODECL, sym);
-	if (accept('='))
+	if (yytoken == '=')
 		initializer(sym, sym->type, -1);
 	if (!(sym->flags & (ISGLOBAL|ISEXTERN)) && tp->op != FTN)
 		sym->flags |= ISDEFINED;
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -629,8 +629,6 @@
 	return np;
 }
 
-static Node *assign(void);
-
 static Node *
 arguments(Node *np)
 {
@@ -659,7 +657,7 @@
 	toomany = 0;
 
 	do {
-		arg = decay(assign());
+		arg = decay(assign(NULL));
 		argtype = *targs;
 		if (argtype == ellipsistype) {
 			n = 0;
@@ -1007,16 +1005,22 @@
 	return cond;
 }
 
-static Node *
-assign(void)
+Node *
+assign(Node *np)
 {
-	Node *np, *(*fun)(char , Node *, Node *);
+	Node *(*fun)(char , Node *, Node *);
 	char op;
 
-	np = ternary();
+	if (np) {
+		op = OINIT;
+	} else {
+		op = OASSIGN;
+		np = ternary();
+	}
+
 	for (;;) {
 		switch (yytoken) {
-		case '=':    op = OASSIGN; fun = assignop;   break;
+		case '=': /* op = op; */;  fun = assignop;   break;
 		case MUL_EQ: op = OA_MUL;  fun = arithmetic; break;
 		case DIV_EQ: op = OA_DIV;  fun = arithmetic; break;
 		case MOD_EQ: op = OA_MOD;  fun = integerop;  break;
@@ -1031,7 +1035,7 @@
 		}
 		chklvalue(np);
 		next();
-		np = (fun)(op, np, assign());
+		np = (fun)(op, np, assign(NULL));
 	}
 }
 
@@ -1069,9 +1073,9 @@
 {
 	Node *lp, *rp;
 
-	lp = assign();
+	lp = assign(NULL);
 	while (accept(',')) {
-		rp = assign();
+		rp = assign(NULL);
 		lp = node(OCOMMA, rp->type, lp, rp);
 	}
 
@@ -1087,177 +1091,4 @@
 	if (np->constant)
 		warn("conditional expression is constant");
 	return np;
-}
-
-struct designator {
-	TINT pos;
-	struct designator *next;
-};
-
-static TINT
-arydesig(Type *tp)
-{
-	TINT npos;
-	Node *np;
-
-	if (tp->op != ARY)
-		errorp("array index in non-array initializer");
-	next();
-	np = iconstexpr();
-	npos = np->sym->u.i;
-	freetree(np);
-	expect(']');
-	return npos;
-}
-
-static TINT
-fielddesig(Type *tp)
-{
-	TINT npos;
-	int ons;
-	Symbol *sym, **p;
-
-	if (!tp->aggreg)
-		errorp("field name not in record or union initializer");
-	ons = namespace;
-	namespace = tp->ns;
-	next();
-	namespace = ons;
-	if (yytoken != IDEN)
-		unexpected();
-	sym = yylval.sym;
-	if ((sym->flags & ISDECLARED) == 0) {
-		errorp(" unknown field '%s' specified in initializer",
-		      sym->name);
-		return 0;
-	}
-	for (p = tp->p.fields; *p != sym; ++p)
-		/* nothing */;
-	return p - tp->p.fields;
-}
-
-static struct designator *
-designation(Type *tp)
-{
-	struct designator *des = NULL, *d;
-	TINT (*fun)(Type *);
-
-	for (;;) {
-		switch (yytoken) {
-		case '[': fun = arydesig;   break;
-		case '.': fun = fielddesig; break;
-		default:
-			if (des)
-				expect('=');
-			return des;
-		}
-		d = xmalloc(sizeof(*d));
-		d->next = NULL;
-
-		if (!des) {
-			des = d;
-		} else {
-			des->next = d;
-			des = d;
-		}
-		des->pos  = (*fun)(tp);
-	}
-}
-
-static void
-initlist(Symbol *sym, Type *tp)
-{
-	struct designator *des;
-	int toomany = 0;
-	TINT n;
-	Type *newtp;
-
-	for (n = 0; ; ++n) {
-		if ((des = designation(tp)) == NULL) {
-			des = xmalloc(sizeof(*des));
-			des->pos = n;
-		} else {
-			n = des->pos;
-		}
-		switch (tp->op) {
-		case ARY:
-			if (tp->defined && n >= tp->n.elem) {
-				if (!toomany)
-					warn("excess elements in array initializer");
-				toomany = 1;
-				sym = NULL;
-			}
-			newtp = tp->type;
-			break;
-		case STRUCT:
-			if (n >= tp->n.elem) {
-				if (!toomany)
-					warn("excess elements in struct initializer");
-				toomany = 1;
-				sym = NULL;
-			} else {
-				sym = tp->p.fields[n];
-				newtp = sym->type;
-			}
-			break;
-		default:
-			newtp = tp;
-			warn("braces around scalar initializer");
-			if (n > 0) {
-				if (!toomany)
-					warn("excess elements in scalar initializer");
-				toomany = 1;
-				sym = NULL;
-			}
-			break;
-		}
-		initializer(sym, newtp, n);
-		if (!accept(','))
-			break;
-	}
-	expect('}');
-
-	if (tp->op == ARY && !tp->defined) {
-		tp->n.elem = n + 1;
-		tp->defined = 1;
-	}
-}
-
-void
-initializer(Symbol *sym, Type *tp, int nelem)
-{
-	Node *np;
-	int flags = sym->flags;
-
-	if (tp->op == FTN)
-		error("function '%s' is initialized like a variable", sym->name);
-
-	if (accept('{')) {
-		initlist(sym, tp);
-		return;
-	}
-	np = assign();
-
-	/* if !sym it means there are too much initializers */
-	if (!sym)
-		return;
-	if (nelem >= 0)
-		return;
-
-	np = assignop(OINIT, varnode(sym), np);
-
-	if (flags & ISDEFINED) {
-		errorp("redeclaration of '%s'", sym->name);
-	} else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {
-		if (!np->right->constant)
-			errorp("initializer element is not constant");
-		emit(OINIT, np);
-		sym->flags |= ISDEFINED;
-	} else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
-		errorp("'%s' has both '%s' and initializer",
-		       sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
-	} else {
-		np->op = OASSIGN;
-		emit(OEXPR, np);
-	}
 }
--- /dev/null
+++ b/cc1/init.c
@@ -1,0 +1,184 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../inc/cc.h"
+#include "../inc/sizes.h"
+#include "cc1.h"
+
+struct designator {
+	TINT pos;
+	struct designator *next;
+};
+
+static TINT
+arydesig(Type *tp)
+{
+	TINT npos;
+	Node *np;
+
+	if (tp->op != ARY)
+		errorp("array index in non-array initializer");
+	next();
+	np = iconstexpr();
+	npos = np->sym->u.i;
+	freetree(np);
+	expect(']');
+	return npos;
+}
+
+static TINT
+fielddesig(Type *tp)
+{
+	TINT npos;
+	int ons;
+	Symbol *sym, **p;
+
+	if (!tp->aggreg)
+		errorp("field name not in record or union initializer");
+	ons = namespace;
+	namespace = tp->ns;
+	next();
+	namespace = ons;
+	if (yytoken != IDEN)
+		unexpected();
+	sym = yylval.sym;
+	if ((sym->flags & ISDECLARED) == 0) {
+		errorp(" unknown field '%s' specified in initializer",
+		      sym->name);
+		return 0;
+	}
+	for (p = tp->p.fields; *p != sym; ++p)
+		/* nothing */;
+	return p - tp->p.fields;
+}
+
+static struct designator *
+designation(Type *tp)
+{
+	struct designator *des = NULL, *d;
+	TINT (*fun)(Type *);
+
+	for (;;) {
+		switch (yytoken) {
+		case '[': fun = arydesig;   break;
+		case '.': fun = fielddesig; break;
+		default:
+			if (des)
+				expect('=');
+			return des;
+		}
+		d = xmalloc(sizeof(*d));
+		d->next = NULL;
+
+		if (!des) {
+			des = d;
+		} else {
+			des->next = d;
+			des = d;
+		}
+		des->pos  = (*fun)(tp);
+	}
+}
+
+static void
+initlist(Symbol *sym, Type *tp)
+{
+	struct designator *des;
+	int toomany = 0;
+	TINT n;
+	Type *newtp;
+
+	for (n = 0; ; ++n) {
+		if ((des = designation(tp)) == NULL) {
+			des = xmalloc(sizeof(*des));
+			des->pos = n;
+		} else {
+			n = des->pos;
+		}
+		switch (tp->op) {
+		case ARY:
+			if (tp->defined && n >= tp->n.elem) {
+				if (!toomany)
+					warn("excess elements in array initializer");
+				toomany = 1;
+				sym = NULL;
+			}
+			newtp = tp->type;
+			break;
+		case STRUCT:
+			if (n >= tp->n.elem) {
+				if (!toomany)
+					warn("excess elements in struct initializer");
+				toomany = 1;
+				sym = NULL;
+			} else {
+				sym = tp->p.fields[n];
+				newtp = sym->type;
+			}
+			break;
+		default:
+			newtp = tp;
+			warn("braces around scalar initializer");
+			if (n > 0) {
+				if (!toomany)
+					warn("excess elements in scalar initializer");
+				toomany = 1;
+				sym = NULL;
+			}
+			break;
+		}
+		initializer(sym, newtp, n);
+		if (!accept(','))
+			break;
+	}
+	expect('}');
+
+	if (tp->op == ARY && !tp->defined) {
+		tp->n.elem = n + 1;
+		tp->defined = 1;
+	}
+}
+
+extern Node *assign(Node *np);
+
+void
+initializer(Symbol *sym, Type *tp, int nelem)
+{
+	Node *np;
+	int flags = sym->flags;
+
+	if (tp->op == FTN)
+		errorp("function '%s' is initialized like a variable", sym->name);
+
+	switch (yytoken) {
+	case '{':
+		initlist(sym, tp); /* FIXME: This code is not complete */
+		return;
+	case '=':
+		np = assign(varnode(sym));
+		break;
+	}
+
+	/* FIXME: old code used in the recursive call
+	 * if (!sym)
+	 *	return;
+	 * if (nelem >= 0)
+	 *	return;
+	 */
+
+	if (flags & ISDEFINED) {
+		errorp("redeclaration of '%s'", sym->name);
+	} else if ((flags & (ISGLOBAL|ISLOCAL|ISPRIVATE)) != 0) {
+		if (!np->right->constant)
+			errorp("initializer element is not constant");
+		emit(OINIT, np);
+		sym->flags |= ISDEFINED;
+	} else if ((flags & (ISEXTERN|ISTYPEDEF)) != 0) {
+		errorp("'%s' has both '%s' and initializer",
+		       sym->name, (flags&ISEXTERN) ? "extern" : "typedef");
+	} else {
+		np->op = OASSIGN;
+		emit(OEXPR, np);
+	}
+}