commit d7cd0ce876107c05e34c7c00cef311e2023a9352
Author:     Roberto E. Vargas Caballero <k...@shike2.com>
AuthorDate: Sun Jan 24 18:45:18 2016 +0100
Commit:     Roberto E. Vargas Caballero <k...@shike2.com>
CommitDate: Sun Jan 24 21:09:21 2016 +0100

    [cc2] Generate code for initializers
    
    The only architecture that generates actual code is z80,
    in the other cases they are only stubs.

diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c
index 2159457..3fb051c 100644
--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
@@ -3,7 +3,12 @@
 #include "../../cc2.h"
 
 void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
 {
 }
 
diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c
index 2159457..3fb051c 100644
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
@@ -3,7 +3,12 @@
 #include "../../cc2.h"
 
 void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
 {
 }
 
diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c
index b140b03..ce0d2fe 100644
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
@@ -34,28 +34,46 @@ code(int op, Node *to, Node *from)
 {
 }
 
+void
+label(Symbol *sym)
+{
+       int seg, flags = sym->type.flags;
+
+       if (flags & FUNF)
+               seg = CODESEG;
+       else if (flags & INITF)
+               seg = DATASEG;
+       else
+               seg = BSSSEG;
+       segment(seg);
+
+       printf("%s:\n", symname(sym));
+}
+
 static void
-emitsym(Symbol *sym)
+emitstring(Node *np)
 {
        /*In z80 we can ignore the aligment */
-       if (sym->type.flags & STRF) {
-               fputs(sym->u.s, stdout);
-               free(sym->u.s);
-               sym->u.s = NULL;
-       } else {
-               switch (sym->type.size) {
-               case 1:
-                       printf("%02X", (int) (sym->u.i & 0xFF));
-                       break;
-               case 2:
-                       printf("%04X", (int) (sym->u.i & 0xFFFF));
-                       break;
-               case 4:
-                       printf("%08X", (long) (sym->u.i & 0xFFFFFFFF));
-                       break;
-               default:
-                       abort();
-               }
+       printf("\"%s\"", np->u.s);
+       free(np->u.s);
+       np->u.s = NULL;
+}
+
+static void
+emitconst(Node *np)
+{
+       switch (np->type.size) {
+       case 1:
+               printf("%02X", (int) np->u.i & 0xFF);
+               break;
+       case 2:
+               printf("%04X", (int) np->u.i & 0xFFFF);
+               break;
+       case 4:
+               printf("%08X", (long) np->u.i & 0xFFFFFFFF);
+               break;
+       default:
+               abort();
        }
 }
 
@@ -64,24 +82,36 @@ emittree(Node *np)
 {
        if (!np)
                return;
-       if (np->op == OSYM) {
-               emitsym(np->sym);
-       } else {
-               emit(np->left);
+
+       switch (np->op) {
+       case OSTRING:
+               emitstring(np);
+               break;
+       case OCONST:
+               emitconst(np);
+               break;
+       case OADDR:
+               emittree(np->left);
+               break;
+       case MEM:
+               fputs(symname(np->u.sym), stdout);
+               break;
+       default:
+               emittree(np->left);
                printf(" %c ", np->op);
-               emit(np->right);
+               emittree(np->right);
+               break;
        }
 }
 
 void
-emit(Node *np)
+data(Node *np)
 {
        char *s;
 
        /*
         * In z80 we can ignore the alignment
         */
-       segment(DATASEG);
        switch (np->type.size) {
        case 1:
                s = "\tDB\t";
@@ -98,6 +128,7 @@ emit(Node *np)
        }
        fputs(s, stdout);
        emittree(np);
+       putchar('\n');
 }
 
 void
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 6af98df..b2eb4c3 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -2,12 +2,11 @@
 enum tflags {
        SIGNF   =    1,
        INTF    =    2,
-       DEFTYP  =    4,
-       STRUCTF =    8,
+       STRF    =    8,
        UNIONF  =    16,
-       FUNCF   =    32,
+       FUNF    =    32,
        ARYF    =    64,
-       STRF    =   128
+       INITF   =   128
 };
 
 enum op {
@@ -115,13 +114,10 @@ struct type {
 
 struct symbol {
        unsigned short id;
+       unsigned short numid;
        char *name;
        Type type;
        char kind;
-       union {
-               TUINT i;
-               char *s;
-       } u;
        Symbol *next;
        Symbol *h_next;
 };
@@ -129,7 +125,11 @@ struct symbol {
 struct node {
        char op;
        Type type;
-       Symbol *sym;
+       union {
+               TUINT i;
+               char *s;
+               Symbol *sym;
+       } u;
        Node *left, *right;
        Node *stmt;
 };
@@ -151,7 +151,8 @@ extern void generate(void);
 extern void peephole(void);
 
 /* code.c */
-extern void emit(Node *np);
+extern void label(Symbol *sym);
+extern void data(Node *np);
 extern void writeout(void);
 
 /* node.c */
@@ -165,3 +166,4 @@ extern Symbol *getsym(int id);
 extern void popctx(void);
 extern void pushctx(void);
 extern void freesym(Symbol *sym);
+extern char *symname(Symbol *sym);
diff --git a/cc2/node.c b/cc2/node.c
index 39ab4ca..5b291ff 100644
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -39,7 +39,6 @@ newnode(void)
 
        np->right = NULL;
        np->left = NULL;
-       np->sym = NULL;
        np->stmt = NULL;
        return np;
 }
diff --git a/cc2/parser.c b/cc2/parser.c
index ebe4a93..796212c 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -22,19 +22,7 @@ extern Type int8type, int16type, int32type, int64type,
             elipsistype;
 
 Type funtype = {
-       .flags = DEFTYP | FUNCF
-};
-
-Type arrtype = {
-       .flags = DEFTYP | ARYF
-};
-
-Type uniontype = {
-       .flags = DEFTYP | UNIONF
-};
-
-Type strtype = {
-       .flags = DEFTYP | STRUCTF
+       .flags = FUNF
 };
 
 union tokenop {
@@ -44,10 +32,11 @@ union tokenop {
 
 typedef void parsefun(char *, union tokenop);
 static parsefun type, symbol, getname, unary, binary, ternary, call,
-                parameter, constant;
+                parameter, constant, aggregate;
 
 typedef void evalfun(void);
-static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, endinit;
+static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit,
+               endinit, array;
 
 static struct decoc {
        void (*eval)(void);
@@ -80,9 +69,9 @@ static struct decoc {
        [ELLIPSIS]    = {NULL, type, .u.arg   = &elipsistype},
 
        [FUNCTION]    = {NULL, type, .u.arg = &funtype},
-       [VECTOR]      = {NULL, NULL, .u.arg = &arrtype},
-       [UNION]       = {NULL, NULL, .u.arg = &uniontype},
-       [STRUCT]      = {NULL, NULL, .u.arg = &strtype},
+       [VECTOR]      = {array, aggregate},
+       [UNION]       = {NULL, NULL},
+       [STRUCT]      = {NULL, NULL},
 
        [ONAME]       = {NULL, getname},
        ['{']         = {beginfun},
@@ -161,6 +150,7 @@ newid(void)
 
        if (++id == 0)
                error(EIDOVER);
+       return id;
 }
 
 static void
@@ -170,6 +160,15 @@ type(char *token, union tokenop u)
 }
 
 static void
+aggregate(char *token, union tokenop u)
+{
+       Symbol *sym;
+
+       sym = getsym(atoi(token+1));
+       push(&sym->type);
+}
+
+static void
 getname(char *t, union tokenop u)
 {
        push((*++t) ? xstrdup(t) : NULL);
@@ -182,7 +181,7 @@ symbol(char *token, union tokenop u)
 
        sclass = *token++;
        np = newnode();
-       np->sym = getsym(atoi(token));
+       np->u.sym = getsym(atoi(token));
        np->op = u.op;
        push(np);
 }
@@ -204,17 +203,14 @@ constant(char *token, union tokenop u)
 {
        static char letters[] = "0123456789ABCDEF";
        Node *np = newnode();
-       Symbol *sym = getsym(0);
        TUINT v;
        unsigned c;
 
-       np->sym = sym;
        ++token;
        if (*token == OSTRING) {
-               np->op = OSYM;
-               sym->id = newid();
-               sym->type.flags = STRF;
-               sym->u.s = xstrdup(++token);
+               np->op = OSTRING;
+               np->type.flags = STRF;
+               np->u.s = xstrdup(++token);
        } else {
                np->op = OCONST;
                np->type = *gettype(token++);
@@ -222,7 +218,7 @@ constant(char *token, union tokenop u)
                        v <<= 4;
                        c = strchr(letters, c) - letters;
                }
-               sym->u.i = v;
+               np->u.i = v;
        }
        push(np);
 }
@@ -295,6 +291,8 @@ static void
 begininit(void)
 {
        ininit = 1;
+       lastsym->type.flags |= INITF;
+       label(lastsym);
 }
 
 static void
@@ -333,6 +331,17 @@ endpars(void)
 }
 
 static void
+array(void)
+{
+       Type *tp, *base;
+       Node *np;
+
+       np = pop();
+       base = pop();
+       tp = pop();
+}
+
+static void
 vardecl(void)
 {
        Type *tp;
@@ -344,11 +353,13 @@ vardecl(void)
        tp = pop();
        np = pop();
 
-       sym = np->sym;
+       sym = np->u.sym;
        sym->name = name;
        sym->type = *tp;
        sym->kind = sclass;
        lastsym = sym;
+       if (!name)
+               sym->numid = newid();
 
        if (funpars >= 0) {
                if (funpars == NR_FUNPARAM)
@@ -365,7 +376,7 @@ stmt(void)
        Node *np = pop();
 
        if (ininit) {
-               emit(np);
+               data(np);
                deltree(np);
                return;
        }
diff --git a/cc2/symbol.c b/cc2/symbol.c
index 299e54d..2b26eff 100644
--- a/cc2/symbol.c
+++ b/cc2/symbol.c
@@ -1,4 +1,5 @@
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -47,7 +48,7 @@ getsym(int id)
 
        htab = &symtab[id & NR_SYMHASH-1];
        for (sym = *htab; sym; sym = sym->h_next) {
-               if (sym->id > 0 && sym->id != id)
+               if (sym->id > 0 && sym->id == id)
                        break;
        }
        if (!sym) {
@@ -64,3 +65,15 @@ getsym(int id)
        }
        return sym;
 }
+
+char *
+symname(Symbol *sym)
+{
+       static char name[20];
+
+       if (sym->name)
+               return sym->name;
+       sprintf(name, ".%d", sym->numid);
+
+       return name;
+}

Reply via email to