commit 1cc0995ffaabe9f5abc298123ff591df5ca32ce0
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Thu Apr 7 08:45:10 2016 +0200
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Thu Apr 7 08:45:10 2016 +0200

    [cc2] Add defpar() and defvar()
    
    Every target is going to do different things when a parameter
    or a variable is declared, so the best thing we can do is to
    create new functions to signal them these parsing events.

diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c
index e58b937..7076542 100644
--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
@@ -174,16 +174,31 @@ label(Symbol *sym)
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
        label(sym);
-       if (!alloc || (sym->type.flags & INITF))
+       if (sym->kind == EXTRN || (sym->type.flags & INITF))
                return;
        size2asm(&sym->type);
        puts("0");
 }
 
 void
+defvar(Symbol *sym)
+{
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
+}
+
+void
 writeout(void)
 {
 }
diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c
index fddb672..b012cf4 100644
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
@@ -173,16 +173,31 @@ label(Symbol *sym)
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
        label(sym);
-       if (!alloc || (sym->type.flags & INITF))
+       if (sym->kind == EXTRN || (sym->type.flags & INITF))
                return;
        size2asm(&sym->type);
        puts("0");
 }
 
 void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
+}
+
+void
 writeout(void)
 {
 }
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
index 003163b..b55a8bd 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -109,9 +109,9 @@ size2asm(Type *tp)
 }
 
 void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
 {
-       if (!alloc)
+       if (sym->kind == EXTRN)
                return;
        if (sym->kind == GLOB)
                fputs("export ", stdout);
@@ -122,6 +122,16 @@ defsym(Symbol *sym, int alloc)
 }
 
 void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
 data(Node *np)
 {
        putchar('\t');
diff --git a/cc2/arch/z80/cgen.c b/cc2/arch/z80/cgen.c
index 1101f84..1a70d6a 100644
--- a/cc2/arch/z80/cgen.c
+++ b/cc2/arch/z80/cgen.c
@@ -7,7 +7,73 @@ generate(void)
 {
 }
 
+/*
+ * This is strongly influenced by
+ * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
+ * calculate addresability as follows
+ *     AUTO => 11          value+fp
+ *     REG => 13           reg
+ *     STATIC => 12        (value)
+ *     CONST => 20         $value
+ */
+static Node *
+address(Node *np)
+{
+       Node *lp, *rp;
+
+       if (!np)
+               return np;
+
+       np->complex = 0;
+       np->address = 0;
+       lp = np->left;
+       rp = np->right;
+       switch (np->op) {
+       case AUTO:
+               np->address = 11;
+               break;
+       case REG:
+               np->address = 13;
+               break;
+       case MEM:
+               np->address = 12;
+               break;
+       case CONST:
+               np->address = 20;
+               break;
+       default:
+               if (lp)
+                       address(lp);
+               if (rp)
+                       address(rp);
+               break;
+       }
+
+       if (np->address > 10)
+               return np;
+       if (lp)
+               np->complex = lp->complex;
+       if (rp) {
+               int d = np->complex - rp->complex;
+
+               if (d == 0)
+                       ++np->complex;
+               else if (d < 0)
+                       np->complex = rp->complex;
+       }
+       if (np->complex == 0)
+               ++np->complex;
+       return np;
+}
+
 void
 addressability(void)
 {
+       Node *np;
+
+       if (!curfun)
+               return;
+
+       for (np = curfun->u.label; np; np = np->stmt)
+               address(np);
 }
diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c
index 49a4737..2954ecf 100644
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
@@ -14,6 +14,7 @@ enum segment {
 };
 
 static int curseg = NOSEG;
+static TSIZE offpar, offvar;
 
 static void
 segment(int seg)
@@ -162,10 +163,48 @@ size2asm(Type *tp)
 }
 
 void
-defsym(Symbol *sym, int alloc)
+newfun()
+{
+       offpar = offvar = 0;
+}
+
+void
+defpar(Symbol *sym)
+{
+       TSIZE align, size;
+
+       if (sym->kind != REG && sym->kind != AUTO)
+               return;
+       align = sym->type.align;
+       size = sym->type.size;
+
+       offpar -= align-1 & ~align;
+       sym->u.off = offpar;
+       offpar -= size;
+       sym->kind = AUTO;
+}
+
+void
+defvar(Symbol *sym)
+{
+       TSIZE align, size;
+
+       if (sym->kind != REG && sym->kind != AUTO)
+               return;
+       align = sym->type.align;
+       size = sym->type.size;
+
+       offvar += align-1 & ~align;
+       sym->u.off = offvar;
+       offvar += size;
+       sym->kind = AUTO;
+}
+
+void
+defglobal(Symbol *sym)
 {
        label(sym);
-       if (!alloc || (sym->type.flags & INITF))
+       if (sym->kind == EXTRN || (sym->type.flags & INITF))
                return;
        size2asm(&sym->type);
        puts("0");
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 4a91575..442d7ce 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -35,14 +35,22 @@ enum op {
        MEM      = 'M',
        AUTO     = 'A',
        REG      = 'R',
+       CONST    = '#',
+       STRING   = '"',
+       LABEL    = 'L',
        /* storage class */
        GLOB     = 'G',
        EXTRN    = 'X',
        PRIVAT   = 'Y',
        LOCAL    = 'T',
        MEMBER   = 'M',
-       LABEL    = 'L',
        /* operands */
+       OMEM     = 'M',
+       OAUTO    = 'A',
+       OREG     = 'R',
+       OCONST   = '#',
+       OSTRING  = '"',
+       OLABEL   = 'L',
        OADD     = '+',
        OSUB     = '-',
        OMUL     = '*',
@@ -74,8 +82,6 @@ enum op {
        OPTR     = '@',
        OSYM     = 'i',
        OCAST    = 'g',
-       OCONST   = '#',
-       OSTRING  = '"',
        OINC     = 'i',
        ODEC     = 'd',
        /*statements */
@@ -134,6 +140,8 @@ struct symbol {
 struct node {
        char op;
        Type type;
+       char complex;
+       char address;
        union {
                TUINT i;
                char *s;
@@ -163,14 +171,15 @@ extern void peephole(void);
 
 /* code.c */
 extern void data(Node *np);
-extern void defsym(Symbol *sym, int alloc);
-extern void writeout(void), endinit(void);
+extern void writeout(void), endinit(void), newfun(void);
+extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *);
 
 /* node.c */
 extern void cleannodes(void);
 extern void delnode(Node *np);
 extern void deltree(Node *np);
 extern Node *newnode(void);
+extern Symbol *curfun;
 
 /* symbol.c */
 extern Symbol *getsym(int id);
diff --git a/cc2/node.c b/cc2/node.c
index 7433e1e..4bfc353 100644
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -8,14 +8,16 @@
 
 #define NSYMBOLS   32
 
-int inhome;
+Symbol *curfun;
 
 struct arena {
        Node *mem;
        struct arena *next;
 };
+
 static struct arena *arena;
 static Node *freep;
+static int inhome;
 
 Node *
 newnode(void)
diff --git a/cc2/parser.c b/cc2/parser.c
index 0657dc6..a02de01 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -44,14 +44,14 @@ static struct decoc {
        void (*parse)(char *token, union tokenop);
        union tokenop u;
 } optbl[] = {            /*  eval     parse           args */
-       [AUTO]        = {  vardecl,  symbol, .u.op  =         AUTO},
-       [REG]         = {  vardecl,  symbol, .u.op  =          REG},
-       [GLOB]        = {  vardecl,  symbol, .u.op  =          MEM},
-       [EXTRN]       = {  vardecl,  symbol, .u.op  =          MEM},
-       [PRIVAT]      = {  vardecl,  symbol, .u.op  =          MEM},
-       [LOCAL]       = {  vardecl,  symbol, .u.op  =          MEM},
-       [MEMBER]      = {  flddecl,  symbol,                     0},
-       [LABEL]       = { labeldcl,  symbol,                     0},
+       [AUTO]        = {  vardecl,  symbol, .u.op  =        OAUTO},
+       [REG]         = {  vardecl,  symbol, .u.op  =         OREG},
+       [GLOB]        = {  vardecl,  symbol, .u.op  =         OMEM},
+       [EXTRN]       = {  vardecl,  symbol, .u.op  =         OMEM},
+       [PRIVAT]      = {  vardecl,  symbol, .u.op  =         OMEM},
+       [LOCAL]       = {  vardecl,  symbol, .u.op  =         OMEM},
+       [MEMBER]      = {  flddecl,  symbol, .u.op  =         OMEM},
+       [LABEL]       = { labeldcl,  symbol, .u.op  =       OLABEL},
 
        [INT8]        = {     NULL,    type, .u.arg =    &int8type},
        [INT16]       = {     NULL,    type, .u.arg =   &int16type},
@@ -130,11 +130,9 @@ static struct decoc {
        [OTABLE]      = {     NULL, casetbl,                     0}
 };
 
-static Symbol *curfun;
-static int funpars = -1, sclass, ininit, endf, lineno;
+static int sclass, inpars, ininit, endf, lineno;
 static Node *stmtp;
 static void *stack[STACKSIZ], **sp = stack;
-static Symbol *params[NR_FUNPARAM];
 
 static void
 push(void *elem)
@@ -447,9 +445,9 @@ einit(char *token, union tokenop u)
 static void
 endpars(void)
 {
-       if (!curfun || funpars == -1)
+       if (!curfun || !inpars)
                error(ESYNTAX);
-       funpars = -1;
+       inpars = 0;
 }
 
 static void
@@ -499,35 +497,28 @@ array(void)
 static void
 decl(Symbol *sym)
 {
-       int alloc;
        Type *tp = &sym->type;
 
        if (tp->flags & FUNF) {
                curfun = sym;
-               return;
        } else {
                switch (sym->kind) {
                case EXTRN:
-                       alloc = 0;
-                       break;
                case GLOB:
                case PRIVAT:
                case LOCAL:
-                       alloc = 1;
+                       defglobal(sym);
                        break;
                case AUTO:
                case REG:
-                       if (funpars >= 0) {
-                               if (funpars == NR_FUNPARAM)
-                                       error(EOUTPAR);
-                               params[funpars++] = sym;
-                       }
-                       return;
+                       if (!curfun)
+                               error(ESYNTAX);
+                       ((inpars) ? defpar : defvar)(sym);
+                       break;
                default:
                        abort();
                }
        }
-       defsym(sym, alloc);
 }
 
 static void
@@ -622,8 +613,7 @@ stmt(void)
 static void
 beginfun(void)
 {
-       memset(params, 0, sizeof(params));
-       funpars = 0;
+       inpars = 0;
        pushctx();
 }
 
@@ -633,19 +623,19 @@ endfun(void)
        Node *np;
 
        np = newnode();
-       np->op = ONOP;
-       addstmt(np);
-       /* TODO: process the function */
        curfun = NULL;
-       funpars = -1;
+       inpars = 0; /* I know, it is a bit redundant */
        endf = 1;
-       popctx();
 }
 
 void
 parse(void)
 {
+       cleannodes();  /* remove code of previous function */
+       popctx();  /* remove context of previous function */
+       curfun = NULL;
        endf = 0;
+
        while (!endf && nextline())
                /* nothing */;
        if (ferror(stdin))

Reply via email to