[hackers] [scc] Move initializer code to a new file || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Sun, 17 Jan 2016 21:57:55 +0100 (CET)

commit 38c240c4f09858a4ce71d70ee7fe16e7df7c9bff
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Sun Jan 17 11:59:04 2016 +0100
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Sun Jan 17 14:09:34 2016 +0100

    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.

diff --git a/cc1/Makefile b/cc1/Makefile
index 30b459b..01dd816 100644
--- a/cc1/Makefile
+++ b/cc1/Makefile
_AT_@ -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
 
diff --git a/cc1/cc1.h b/cc1/cc1.h
index 73a76fb..47710b7 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -374,13 +374,14 @@ extern Node *castcode(Node *np, Type *newtp);
 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 */
diff --git a/cc1/decl.c b/cc1/decl.c
index c1fcdac..e2fbae7 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
_AT_@ -779,7 +779,7 @@ identifier(struct decl *dcl)
 
         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;
diff --git a/cc1/expr.c b/cc1/expr.c
index 36eef5f..262f261 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -629,8 +629,6 @@ primary(void)
         return np;
 }
 
-static Node *assign(void);
-
 static Node *
 arguments(Node *np)
 {
_AT_@ -659,7 +657,7 @@ arguments(Node *np)
         toomany = 0;
 
         do {
- arg = decay(assign());
+ arg = decay(assign(NULL));
                 argtype = *targs;
                 if (argtype == ellipsistype) {
                         n = 0;
_AT_@ -1007,16 +1005,22 @@ ternary(void)
         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;
_AT_@ -1031,7 +1035,7 @@ assign(void)
                 }
                 chklvalue(np);
                 next();
- np = (fun)(op, np, assign());
+ np = (fun)(op, np, assign(NULL));
         }
 }
 
_AT_@ -1069,9 +1073,9 @@ expr(void)
 {
         Node *lp, *rp;
 
- lp = assign();
+ lp = assign(NULL);
         while (accept(',')) {
- rp = assign();
+ rp = assign(NULL);
                 lp = node(OCOMMA, rp->type, lp, rp);
         }
 
_AT_@ -1088,176 +1092,3 @@ condexpr(void)
                 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);
- }
-}
diff --git a/cc1/init.c b/cc1/init.c
new file mode 100644
index 0000000..f56e47f
--- /dev/null
+++ b/cc1/init.c
_AT_@ -0,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);
+ }
+}
Received on Sun Jan 17 2016 - 21:57:55 CET

This archive was generated by hypermail 2.3.0 : Sun Jan 17 2016 - 22:00:19 CET