commit 43a3b37a514e390199668bab42c3451901de5917
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Mon Jan 18 15:20:50 2016 +0100
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Mon Jan 18 16:34:11 2016 +0100

    Emit compound initializers
    
    At this point we are not emiting anything, but we have the full process
    working. We have to create a function which could emit this kind of
    constants.

diff --git a/cc1/cc1.h b/cc1/cc1.h
index b6f1d4e..84bd68a 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -384,7 +384,7 @@ extern Node *castcode(Node *np, Type *newtp);
 extern TUINT ones(int nbytes);
 
 /* expr.c */
-extern Node *decay(Node *), *negate(Node *np), *assign(Node *np);;
+extern Node *decay(Node *), *negate(Node *np), *assign(void);;
 extern Node *convert(Node *np, Type *tp1, char iscast);
 extern Node *iconstexpr(void), *condexpr(void), *expr(void);
 extern bool isnodecmp(int op);
diff --git a/cc1/code.c b/cc1/code.c
index d72e5f1..884223b 100644
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -207,6 +207,8 @@ emitconst(Node *np)
                for (bp = sym->u.s; c = *bp; ++bp)
                        printf("%02X", c & 0xFF);
                break;
+       case STRUCT:
+               return;
        default:
                /* TODO: Handle other kind of constants */
                abort();
diff --git a/cc1/decl.c b/cc1/decl.c
index 2844540..6453649 100644
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -788,7 +788,7 @@ identifier(struct decl *dcl)
 
        if (sym->token == IDEN && sym->type->op != FTN)
                emit(ODECL, sym);
-       if (yytoken == '=')
+       if (accept('='))
                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 262f261..b20640c 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -512,9 +512,7 @@ static Node *
 assignop(char op, Node *lp, Node *rp)
 {
        if ((rp = convert(decay(rp), lp->type, 0)) == NULL) {
-               errorp((op == OINIT) ?
-                       "incorrect initiliazer" :
-                       "incompatible types when assigning");
+               errorp("incompatible types when assigning");
                return lp;
        }
 
@@ -657,7 +655,7 @@ arguments(Node *np)
        toomany = 0;
 
        do {
-               arg = decay(assign(NULL));
+               arg = decay(assign());
                argtype = *targs;
                if (argtype == ellipsistype) {
                        n = 0;
@@ -1006,21 +1004,15 @@ ternary(void)
 }
 
 Node *
-assign(Node *np)
+assign(void)
 {
-       Node *(*fun)(char , Node *, Node *);
+       Node *np, *(*fun)(char , Node *, Node *);
        char op;
 
-       if (np) {
-               op = OINIT;
-       } else {
-               op = OASSIGN;
-               np = ternary();
-       }
-
+       np = ternary();
        for (;;) {
                switch (yytoken) {
-               case '=': /* op = op; */;  fun = assignop;   break;
+               case '=':    op = OASSIGN; 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;
@@ -1035,7 +1027,7 @@ assign(Node *np)
                }
                chklvalue(np);
                next();
-               np = (fun)(op, np, assign(NULL));
+               np = (fun)(op, np, assign());
        }
 }
 
@@ -1073,9 +1065,9 @@ expr(void)
 {
        Node *lp, *rp;
 
-       lp = assign(NULL);
+       lp = assign();
        while (accept(',')) {
-               rp = assign(NULL);
+               rp = assign();
                lp = node(OCOMMA, rp->type, lp, rp);
        }
 
diff --git a/cc1/init.c b/cc1/init.c
index c5895ee..eb77cd3 100644
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -78,11 +78,24 @@ designation(Init *ip)
        return ip;
 }
 
+static Node *initlist(Type *tp);
+
 static Node *
-initlist(Symbol *sym, Type *tp)
+initialize(Type *tp)
+{
+       Node *np;
+
+       np = (accept('{')) ? initlist(tp) : assign();
+       if ((np = convert(decay(np), tp, 0)) == NULL)
+               errorp("incorrect initializer");
+       return np;
+}
+
+static Node *
+initlist(Type *tp)
 {
        Init *ip;
-       Symbol *nsym;
+       Symbol *sym;
        struct designator *dp;
        int toomany = 0;
        Type *newtp;
@@ -99,19 +112,20 @@ initlist(Symbol *sym, Type *tp)
                designation(ip);
                switch (tp->op) {
                case ARY:
-                       newtp = tp->type;
-                       if (!tp->defined || ip->pos < tp->n.elem)
+                       newtp = sym->type;
+                       if (!tp->defined || ip->pos <= tp->n.elem)
                                break;
                        if (!toomany)
                                warn("excess elements in array initializer");
                        toomany = 1;
                        break;
                case STRUCT:
-                       if (ip->pos < tp->n.elem) {
-                               sym = tp->p.fields[ip->pos];
+                       if (ip->pos <= tp->n.elem) {
+                               sym = tp->p.fields[ip->pos-1];
                                newtp = sym->type;
                                break;
                        }
+                       newtp = inttype;
                        if (!toomany)
                                warn("excess elements in struct initializer");
                        toomany = 1;
@@ -119,7 +133,7 @@ initlist(Symbol *sym, Type *tp)
                default:
                        newtp = tp;
                        warn("braces around scalar initializer");
-                       if (ip->pos <= 0)
+                       if (ip->pos == 1)
                                break;
                        if (!toomany)
                                warn("excess elements in scalar initializer");
@@ -128,8 +142,7 @@ initlist(Symbol *sym, Type *tp)
                }
                dp = ip->head;
                dp->pos = ip->pos;
-               /* TODO: pass the correct parameters to initlist */
-               dp->expr = (accept('{')) ? initlist(sym, tp) : assign(NULL);
+               dp->expr = initialize(newtp);
 
                if (!accept(','))
                        break;
@@ -141,9 +154,10 @@ end_of_initializer:
                tp->n.elem = ip->pos;
                tp->defined = 1;
        }
-       nsym = newsym(NS_IDEN);
-       nsym->u.init = ip;
-       return constnode(nsym);
+       sym = newsym(NS_IDEN);
+       sym->u.init = ip;
+       sym->type = tp;
+       return constnode(sym);
 }
 
 void
@@ -155,14 +169,7 @@ initializer(Symbol *sym, Type *tp, int nelem)
        if (tp->op == FTN)
                errorp("function '%s' is initialized like a variable", 
sym->name);
 
-       switch (yytoken) {
-       case '{':
-               initlist(sym, tp);
-               return;
-       case '=':
-               np = assign(varnode(sym));
-               break;
-       }
+       np = node(OINIT, tp, varnode(sym), initialize(tp));
 
        if (flags & ISDEFINED) {
                errorp("redeclaration of '%s'", sym->name);

Reply via email to