commit 38c240c4f09858a4ce71d70ee7fe16e7df7c9bff
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Sun Jan 17 11:59:04 2016 +0100
Commit:     Roberto E. Vargas Caballero <k...@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
@@ -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
@@ -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
@@ -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
@@ -629,8 +629,6 @@ primary(void)
        return np;
 }
 
-static Node *assign(void);
-
 static Node *
 arguments(Node *np)
 {
@@ -659,7 +657,7 @@ arguments(Node *np)
        toomany = 0;
 
        do {
-               arg = decay(assign());
+               arg = decay(assign(NULL));
                argtype = *targs;
                if (argtype == ellipsistype) {
                        n = 0;
@@ -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;
@@ -1031,7 +1035,7 @@ assign(void)
                }
                chklvalue(np);
                next();
-               np = (fun)(op, np, assign());
+               np = (fun)(op, np, assign(NULL));
        }
 }
 
@@ -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);
        }
 
@@ -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
@@ -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);
+       }
+}

Reply via email to