commit 5029b379b8193ead69618b3e306c9dcd2e1ab296
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Sat Jan 23 11:09:20 2016 +0100
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Sat Jan 23 11:09:20 2016 +0100

    [cc2] Add parser of IR
    
    This is a totally incomplete parser, and it is in a state not thought to be 
shown,
    but it is something to begin to talk.

diff --git a/cc2/Makefile b/cc2/Makefile
index 2651d3a..0b30c73 100644
--- a/cc2/Makefile
+++ b/cc2/Makefile
@@ -2,7 +2,8 @@
 
 include ../config.mk
 
-OBJS = main.o parser.o code.o optm.o peep.o cgen.o
+OBJS = main.o parser.o code.o optm.o peep.o cgen.o \
+       symbol.o node.o arch/$(ARCH)/types.o
 
 all: cc2
 
diff --git a/cc2/arch/amd64-sysv/arch.h b/cc2/arch/amd64-sysv/arch.h
new file mode 100644
index 0000000..fa129dd
--- /dev/null
+++ b/cc2/arch/amd64-sysv/arch.h
@@ -0,0 +1,5 @@
+
+#define TINT    long long
+#define TUINT   unsigned long long
+#define TFLOAT  double
+
diff --git a/cc2/arch/amd64-sysv/types.c b/cc2/arch/amd64-sysv/types.c
new file mode 100644
index 0000000..a258c4f
--- /dev/null
+++ b/cc2/arch/amd64-sysv/types.c
@@ -0,0 +1,89 @@
+
+#include "arch.h"
+#include "../../cc2.h"
+
+
+Type int8type = {
+       .flags  = SIGNF | INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type int16type = {
+       .flags  = SIGNF | INTF,
+       .size   = 2,
+       .align  = 2
+};
+
+Type int32type = {
+       .flags  = SIGNF | INTF,
+       .size   = 4,
+       .align  = 4
+};
+
+Type int64type = {
+       .flags  = SIGNF | INTF,
+       .size   = 8,
+       .align  = 8
+};
+
+Type uint8type = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type uint16type = {
+       .flags  = INTF,
+       .size   = 2,
+       .align  = 2
+};
+
+Type uint32type = {
+       .flags  = INTF,
+       .size   = 4,
+       .align  = 2
+};
+
+Type uint64type = {
+       .flags  = INTF,
+       .size   = 8,
+       .align  = 2
+};
+
+Type ptrtype = {
+       .flags  = INTF,
+       .size   = 8,
+       .align  = 8
+};
+
+Type booltype = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type float32type = {
+       .size   = 4,
+       .align  = 4
+};
+
+Type float64type = {
+       .size   = 8,
+       .align  = 8
+};
+
+Type float80type = {
+       .size   = 10,
+       .align  = 12
+};
+
+Type voidtype = {
+       .size = 0,
+       .align = 0
+};
+
+Type elipsistype = {
+       .size = 0,
+       .align = 0
+};
diff --git a/cc2/arch/i386-sysv/arch.h b/cc2/arch/i386-sysv/arch.h
new file mode 100644
index 0000000..fa129dd
--- /dev/null
+++ b/cc2/arch/i386-sysv/arch.h
@@ -0,0 +1,5 @@
+
+#define TINT    long long
+#define TUINT   unsigned long long
+#define TFLOAT  double
+
diff --git a/cc2/arch/i386-sysv/types.c b/cc2/arch/i386-sysv/types.c
new file mode 100644
index 0000000..66ed4a1
--- /dev/null
+++ b/cc2/arch/i386-sysv/types.c
@@ -0,0 +1,89 @@
+
+#include "arch.h"
+#include "../../cc2.h"
+
+
+Type int8type = {
+       .flags  = SIGNF | INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type int16type = {
+       .flags  = SIGNF | INTF,
+       .size   = 2,
+       .align  = 2
+};
+
+Type int32type = {
+       .flags  = SIGNF | INTF,
+       .size   = 4,
+       .align  = 4
+};
+
+Type int64type = {
+       .flags  = SIGNF | INTF,
+       .size   = 8,
+       .align  = 8
+};
+
+Type uint8type = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type uint16type = {
+       .flags  = INTF,
+       .size   = 2,
+       .align  = 2
+};
+
+Type uint32type = {
+       .flags  = INTF,
+       .size   = 4,
+       .align  = 2
+};
+
+Type uint64type = {
+       .flags  = INTF,
+       .size   = 8,
+       .align  = 2
+};
+
+Type ptrtype = {
+       .flags  = INTF,
+       .size   = 4,
+       .align  = 4
+};
+
+Type booltype = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type float32type = {
+       .size   = 4,
+       .align  = 4
+};
+
+Type float64type = {
+       .size   = 8,
+       .align  = 8
+};
+
+Type float80type = {
+       .size   = 10,
+       .align  =  4
+};
+
+Type voidtype = {
+       .size = 0,
+       .align = 0
+};
+
+Type elipsistype = {
+       .size = 0,
+       .align = 0
+};
diff --git a/cc2/arch/z80/arch.h b/cc2/arch/z80/arch.h
new file mode 100644
index 0000000..fa129dd
--- /dev/null
+++ b/cc2/arch/z80/arch.h
@@ -0,0 +1,5 @@
+
+#define TINT    long long
+#define TUINT   unsigned long long
+#define TFLOAT  double
+
diff --git a/cc2/arch/z80/types.c b/cc2/arch/z80/types.c
new file mode 100644
index 0000000..bf88a2c
--- /dev/null
+++ b/cc2/arch/z80/types.c
@@ -0,0 +1,89 @@
+
+#include "arch.h"
+#include "../../cc2.h"
+
+
+Type int8type = {
+       .flags  = SIGNF | INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type int16type = {
+       .flags  = SIGNF | INTF,
+       .size   = 2,
+       .align  = 1
+};
+
+Type int32type = {
+       .flags  = SIGNF | INTF,
+       .size   = 4,
+       .align  = 1
+};
+
+Type int64type = {
+       .flags  = SIGNF | INTF,
+       .size   = 8,
+       .align  = 1
+};
+
+Type uint8type = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type uint16type = {
+       .flags  = INTF,
+       .size   = 2,
+       .align  = 1
+};
+
+Type uint32type = {
+       .flags  = INTF,
+       .size   = 4,
+       .align  = 1
+};
+
+Type uint64type = {
+       .flags  = INTF,
+       .size   = 8,
+       .align  = 1
+};
+
+Type ptrtype = {
+       .flags  = INTF,
+       .size   = 2,
+       .align  = 1
+};
+
+Type booltype = {
+       .flags  = INTF,
+       .size   = 1,
+       .align  = 1
+};
+
+Type float32type = {
+       .size   = 4,
+       .align  = 1
+};
+
+Type float64type = {
+       .size   = 4,
+       .align  = 1
+};
+
+Type float80type = {
+       .size   = 4,
+       .align  = 1
+};
+
+Type voidtype = {
+       .size = 0,
+       .align = 0
+};
+
+Type elipsistype = {
+       .size = 0,
+       .align = 0
+};
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 9a52f3c..ae9f166 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -1,14 +1,136 @@
 
+enum tflags {
+       SIGNF   = 1,
+       INTF    = 2,
+       DEFTYP  = 4,
+       STRUCTF = 8,
+       UNIONF  = 16,
+       FUNCF   = 32,
+       ARYF    = 64
+};
+
+enum op {
+       /* types */
+       ELLIPSIS = 'E',
+       INT8     = 'C',
+       INT16    = 'I',
+       INT32    = 'W',
+       INT64    = 'Q',
+       UINT8    = 'K',
+       UINT16   = 'N',
+       UINT32   = 'Z',
+       UINT64   = 'O',
+       POINTER  = 'P',
+       FUNCTION = 'F',
+       VECTOR   = 'V',
+       UNION    = 'U',
+       STRUCT   = 'S',
+       BOOL     = 'B',
+       FLOAT    = 'J',
+       DOUBLE   = 'D',
+       LDOUBLE  = 'H',
+       VOID     = '0',
+       ONAME    = '"',
+       /* kind of operand */
+       NONE     = 0,
+       MEM      = 'M',
+       AUTO     = 'A',
+       REG      = 'R',
+       /* storage class */
+       GLOB     = 'G',
+       EXTRN    = 'X',
+       PRIVAT   = 'Y',
+       LOCAL    = 'T',
+       MEMBER   = 'M',
+       LABEL    = 'L',
+       /* operands */
+       OADD     = '+',
+       OSUB     = '-',
+       OMUL     = '*',
+       OMOD     = '%',
+       ODIV     = '/',
+       OSHL     = 'l',
+       OSHR     = 'r',
+       OLT      = '<',
+       OGT      = '>',
+       OLE      = '[',
+       OGE      = ']',
+       OEQ      = '=',
+       ONE      = '!',
+       OBAND    = '&',
+       OBOR     = '|',
+       OBXOR    = '^',
+       OCPL     = '~',
+       OASSIG   = ':',
+       ONEG     = '_',
+       OCALL    = 'c',
+       OPAR     = 'p',
+       OFIELD   = '.',
+       OCOMMA   = ',',
+       OASK     = '?',
+       OCOLON   = ' ',
+       OADDR    = '\'',
+       OAND     = 'a',
+       OOR      = 'b',
+       OPTR     = '@',
+       OSYM     = 'y',
+       OCAST    = 'g',
+       OCONST   = '#',
+       OSTRING  = '"',
+       /*statements */
+       OJMP     = 'j',
+       ORET     = 'r',
+       OBLOOP   = 'b',
+       OELOOP   = 'e',
+       OCASE    = 'v',
+       ODEFAULT = 'f',
+       OTABLE   = 't',
+       OSWITCH  = 's',
+       OEPARS   = '\\',
+       OSTMT    = '\t'
+};
+
 enum nerrors {
+       EIDOVER,       /* identifier overflow */
+       EOUTPAR,       /* out pf params */
+       ESYNTAX,       /* syntax error */
+       ESTACKA,       /* stack unaligned */
+       ESTACKO,       /* stack overflow */
+       ESTACKU,       /* stack underflow */
        ELNLINE,       /* line too long */
        EFERROR,       /* error reading from file:%s*/
        ENUMERR
 };
 
 typedef struct node Node;
+typedef struct type Type;
+typedef struct symbol Symbol;
+
+struct type {
+       unsigned short size;
+       unsigned short align;
+       unsigned short flags;
+};
+
+struct symbol {
+       unsigned short id;
+       char *name;
+       Type type;
+       char kind;
+       union {
+               TUINT i;
+               char *s;
+       } u;
+       Symbol *next;
+       Symbol *h_next;
+};
 
 struct node {
-       unsigned char op;
+       char op;
+       Type type;
+       Symbol *sym;
+       Node *left, *right;
+       Node *stmt;
 };
 
 /* main.c */
@@ -29,3 +151,14 @@ extern void peephole(void);
 
 /* code.c */
 extern void writeout(void);
+
+/* node.c */
+extern void cleannodes(void);
+extern void delnode(Node *np);
+extern Node *newnode(void);
+
+/* symbol.c */
+extern Symbol *getsym(int id);
+extern void popctx(void);
+extern void pushctx(void);
+extern void freesym(Symbol *sym);
diff --git a/cc2/cgen.c b/cc2/cgen.c
index 8dc1915..0e8d43b 100644
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -1,4 +1,5 @@
 
+#include "arch.h"
 #include "cc2.h"
 
 void
diff --git a/cc2/code.c b/cc2/code.c
index 48fbf84..26192c4 100644
--- a/cc2/code.c
+++ b/cc2/code.c
@@ -1,4 +1,5 @@
 
+#include "arch.h"
 #include "cc2.h"
 
 void
diff --git a/cc2/main.c b/cc2/main.c
index 3e4b3f0..b71f468 100644
--- a/cc2/main.c
+++ b/cc2/main.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "arch.h"
 #include "cc2.h"
 #include "error.h"
 
diff --git a/cc2/node.c b/cc2/node.c
new file mode 100644
index 0000000..5e4f325
--- /dev/null
+++ b/cc2/node.c
@@ -0,0 +1,64 @@
+
+#include <stdlib.h>
+
+#include "../inc/cc.h"
+
+#include "arch.h"
+#include "cc2.h"
+
+#define NSYMBOLS   32
+
+int inhome;
+
+struct arena {
+       Node *mem;
+       struct arena *next;
+};
+static struct arena *arena;
+static Node *freep;
+
+Node *
+newnode(void)
+{
+       struct arena *ap;
+       Node *np;
+
+       if (!freep) {
+               ap = xmalloc(sizeof(*ap));
+               ap->mem = xcalloc(NSYMBOLS, sizeof(Node));
+               ap->next = arena;
+               arena = ap;
+               for (np = ap->mem; np < &ap->mem[NSYMBOLS-1]; ++np)
+                       np->left = np+1;
+               np->left = NULL;
+               freep = np;
+       }
+
+       np = freep;
+       freep = np->left;
+
+       np->right = NULL;
+       np->left = NULL;
+       np->sym = NULL;
+       np->stmt = NULL;
+       return np;
+}
+
+void
+delnode(Node *np)
+{
+       np->left = freep;
+       freep = np;
+}
+
+void
+cleannodes(void)
+{
+       struct arena *ap, *next;
+
+       for (ap = arena; ap; ap = next) {
+               next = ap;
+               free(ap->mem);
+               free(ap);
+       }
+}
diff --git a/cc2/optm.c b/cc2/optm.c
index 3583bbd..b86d32e 100644
--- a/cc2/optm.c
+++ b/cc2/optm.c
@@ -1,4 +1,5 @@
 
+#include "arch.h"
 #include "cc2.h"
 
 void
diff --git a/cc2/parser.c b/cc2/parser.c
index 23a0e88..eef2f22 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -1,60 +1,405 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
+#include "../inc/cc.h"
+#include "../inc/sizes.h"
+
+#include "arch.h"
 #include "cc2.h"
 
-#define MAXLINE 200
+#define MAXLINE     200
+#define STACKSIZ     50
+
+extern Type int8type, int16type, int32type, int64type,
+            uint8type, uint16type, uint32type, uint64type,
+            float32type, float64type, float80type,
+            booltype,
+            ptrtype,
+            voidtype,
+            elipsistype;
+
+Type funtype = {
+       .flags = DEFTYP | FUNCF
+};
+
+Type arrtype = {
+       .flags = DEFTYP | ARYF
+};
+
+Type uniontype = {
+       .flags = DEFTYP | UNIONF
+};
+
+Type strtype = {
+       .flags = DEFTYP | STRUCTF
+};
+
+union tokenop {
+       void *arg;
+       int op;
+};
+
+typedef void parsefun(char *, union tokenop);
+static parsefun type, symbol, getname, unary, binary, ternary, call,
+                parameter, constant;
+
+typedef void evalfun(void);
+static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, endinit;
+
+static struct decoc {
+       void (*eval)(void);
+       void (*parse)(char *token, union tokenop);
+       union tokenop u;
+} optbl[] = {
+       [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]      = {NULL, symbol},
+       [LABEL]       = {NULL, symbol},
+
+       [INT8]        = {NULL, type, .u.arg   = &int8type},
+       [INT16]       = {NULL, type, .u.arg   = &int16type},
+       [INT32]       = {NULL, type, .u.arg   = &int32type},
+       [INT64]       = {NULL, type, .u.arg   = &int64type},
+       [UINT8]       = {NULL, type, .u.arg   = &uint8type},
+       [UINT16]      = {NULL, type, .u.arg   = &uint16type},
+       [UINT32]      = {NULL, type, .u.arg   = &uint32type},
+       [UINT64]      = {NULL, type, .u.arg   = &uint64type},
+       [FLOAT]       = {NULL, type, .u.arg   = &float32type},
+       [DOUBLE]      = {NULL, type, .u.arg   = &float64type},
+       [LDOUBLE]     = {NULL, type, .u.arg   = &float80type},
+       [VOID]        = {NULL, type, .u.arg   = &voidtype},
+       [BOOL]        = {NULL, type, .u.arg   = &booltype},
+       [POINTER]     = {NULL, type, .u.arg   = &ptrtype},
+       [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},
+
+       [ONAME]       = {NULL, getname},
+       ['{']         = {beginfun},
+       ['}']         = {endfun},
+       ['(']         = {begininit},
+       [')']         = {endinit},
+       [OEPARS]      = {endpars},
+       [OSTMT]       = {stmt},
+
+       [OCPL]        = {NULL, unary},
+       [ONEG]        = {NULL, unary},
+       [OFIELD]      = {NULL, unary},
+       [OADDR]       = {NULL, unary},
+       [OAND]        = {NULL, unary},
+       [OOR]         = {NULL, unary},
+       [OPTR]        = {NULL, unary},
+       [OCAST]       = {NULL, unary},
+       [OPAR ]       = {NULL, unary},
+
+       [OADD]        = {NULL, binary},
+       [OSUB]        = {NULL, binary},
+       [OMUL]        = {NULL, binary},
+       [OMOD]        = {NULL, binary},
+       [ODIV]        = {NULL, binary},
+       [OSHL]        = {NULL, binary},
+       [OSHR]        = {NULL, binary},
+       [OLT]         = {NULL, binary},
+       [OGT]         = {NULL, binary},
+       [OLE]         = {NULL, binary},
+       [OGE]         = {NULL, binary},
+       [OEQ]         = {NULL, binary},
+       [ONE]         = {NULL, binary},
+       [OBAND]       = {NULL, binary},
+       [OBOR]        = {NULL, binary},
+       [OBXOR]       = {NULL, binary},
+       [OASSIG]      = {NULL, binary},
+       [OCOMMA]      = {NULL, binary},
+
+       [OASK]        = {NULL, ternary},
+       [OCALL]       = {NULL, call},
+
+       [OCONST]      = NULL, constant,
+
+       [OCASE]       = NULL,
+       [ODEFAULT]    = NULL,
+       [OTABLE]      = NULL,
+       [OSWITCH]     = NULL
+};
+
+static void *stack[STACKSIZ], **sp = stack;
+static Symbol *lastsym, *curfun;
+static Symbol *params[NR_FUNPARAM];
+static int funpars = -1, sclass, callpars, ininit;
+static Node *stmtp, *callp;
 
 static void
-push(Node * np)
+push(void *elem)
 {
+       if (sp == stack[STACKSIZ])
+               error(ESTACKO);
+       *sp++ = elem;
 }
 
-static Node *
+static void *
 pop(void)
 {
+       if (sp == stack)
+               error(ESTACKU);
+       return *--sp;
+}
+
+static unsigned short
+newid(void)
+{
+       static unsigned short id;
+
+       if (++id == 0)
+               error(EIDOVER);
 }
 
 static void
-expr(char *tok)
+type(char *token, union tokenop u)
 {
+       push(u.arg);
 }
 
 static void
-stmt(Node *np)
+getname(char *t, union tokenop u)
 {
+       push((*++t) ? xstrdup(t) : NULL);
 }
 
 static void
-decl(char *tok)
+symbol(char *token, union tokenop u)
 {
+       Node *np;
+
+       sclass = *token++;
+       np = newnode();
+       np->sym = getsym(atoi(token));
+       np->op = u.op;
+       push(np);
+}
+
+static Type *
+gettype(char *token)
+{
+       struct decoc *dp;
+
+       dp = &optbl[*token];
+       if (!dp->parse)
+               error(ESYNTAX);
+       (*dp->parse)(token, dp->u);
+       return pop();
+}
+
+static void
+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;
+               np->type = ptrtype;
+               sym->id = newid();
+               sym->u.s = xstrdup(++token);
+       } else {
+               np->op = OCONST;
+               np->type = *gettype(token++);
+               for (v = 0; c = *token++; v += c) {
+                       v <<= 4;
+                       c = strchr(letters, c) - letters;
+               }
+               sym->u.i = v;
+       }
+}
+
+static void
+ternary(char *token, union tokenop u)
+{
+       Node *ask, *colon;
+       Type *tp;
+
+       tp = gettype(++token);
+
+       colon = newnode();
+       colon->op = OCOLON;
+       colon->right = pop();
+       colon->left = pop();
+
+       ask = newnode();
+       ask->op = OASK;
+       ask->type = *tp;
+       ask->left = pop();
+       ask->right = pop();
+       push(ask);
+}
+
+static void
+unary(char *token, union tokenop u)
+{
+       Node *np = newnode();
+
+       np->op = *token++;
+       np->type = *gettype(token);
+       np->left = pop();
+       np->right = NULL;
+       push(np);
+}
+
+static void
+call(char *token, union tokenop u)
+{
+       Node *np, *par, *fun;
+
+       for (par = NULL;; par = np) {
+               np = pop();
+               if (np->op != OPAR)
+                       break;
+               np->right = par;
+       }
+       fun = newnode();
+       fun->op = OCALL;
+       fun->type = *gettype(token);
+       fun->left = np;
+       fun->right = par;
+       push(fun);
+}
+
+static void
+binary(char *token, union tokenop u)
+{
+       Node *np = newnode();
+
+       np->op = *token++;
+       np->type = *gettype(token);
+       np->right = pop();
+       np->left = pop();
+       push(np);
+}
+
+static void
+begininit(void)
+{
+       inint = 1;
+}
+
+static void
+endinit(void)
+{
+       ininit = 0;
+}
+
+static void
+beginfun(void)
+{
+       if (curfun)
+               error(ESYNTAX);
+       memset(params, 0, sizeof(params));
+       funpars = 0;
+       curfun = lastsym;
+       pushctx();
+}
+
+static void
+endfun(void)
+{
+       if (!curfun)
+               error(ESYNTAX);
+       popctx();
+       curfun = NULL;
+       funpars = -1;
+}
+
+static void
+endpars(void)
+{
+       if (!curfun || funpars == -1)
+               error(ESYNTAX);
+       funpars = -1;
+}
+
+static void
+vardecl(void)
+{
+       Type *tp;
+       Node *np;
+       Symbol *sym;
+       char *name;
+
+       name = pop();
+       tp = pop();
+       np = pop();
+
+       sym = np->sym;
+       sym->name = name;
+       sym->type = *tp;
+       sym->kind = sclass;
+       lastsym = sym;
+
+       if (funpars >= 0) {
+               if (funpars == NR_FUNPARAM)
+                       error(EOUTPAR);
+               params[funpars++] = sym;
+       }
+       delnode(np);
+}
+
+static void
+stmt(void)
+{
+       static Node *lastp;
+       Node *np = pop();
+
+       if (!stmtp)
+               stmtp = np;
+       else
+               lastp->stmt = np;
+       lastp = np;
 }
 
 void
 parse(void)
 {
-       char line[MAXLINE];
+       char line[MAXLINE], *t;
        size_t len;
+       int c;
+       struct decoc *dp;
 
        for (;;) {
-               if (fgets(line, sizeof(line), stdin))
+               if (!fgets(line, sizeof(line), stdin))
                        break;
                if ((len = strlen(line)) == 0 || line[0] == '\n')
                        continue;
                if (line[len-1] != '\n')
                        error(ELNLINE);
                line[len-1] = '\0';
-               switch (*line) {
-               case '\t':
-                       expr(strtok(line, "\t"));
-                       stmt(pop());
-                       break;
-               default:
-                       decl(strtok(line, "\t"));
-                       break;
+
+               c = *line;
+               for (t = strtok(line, "\t\n"); t; t = strtok(NULL, "\t\n")) {
+                       dp = &optbl[*t];
+                       if (!dp->parse)
+                               break;
+                       (*dp->parse)(t, dp->u);
                }
+
+               (*optbl[c].eval)();
+               if (sp != stack)
+                       error(ESTACKA);
+               if (c == '}')
+                       break;
        }
 
        if (ferror(stdin))
diff --git a/cc2/peep.c b/cc2/peep.c
index 2558a58..cc05aee 100644
--- a/cc2/peep.c
+++ b/cc2/peep.c
@@ -1,4 +1,5 @@
 
+#include "arch.h"
 #include "cc2.h"
 
 void
diff --git a/cc2/symbol.c b/cc2/symbol.c
new file mode 100644
index 0000000..299e54d
--- /dev/null
+++ b/cc2/symbol.c
@@ -0,0 +1,66 @@
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../inc/cc.h"
+
+#include "arch.h"
+#include "cc2.h"
+
+#define NR_SYMHASH  64
+
+static Symbol *symtab[NR_SYMHASH];
+static Symbol *locals;
+static int infunction;
+
+
+void
+freesym(Symbol *sym)
+{
+       free(sym->name);
+       free(sym);
+}
+
+void
+pushctx(void)
+{
+       infunction = 1;
+}
+
+void
+popctx(void)
+{
+       Symbol *sym, *next;
+
+       infunction = 0;
+       for (sym = locals; sym; sym = next) {
+               next = sym->next;
+               symtab[sym->id & NR_SYMHASH-1] = sym->h_next;
+               freesym(sym);
+       }
+}
+
+Symbol *
+getsym(int id)
+{
+       Symbol **htab, *sym;
+
+       htab = &symtab[id & NR_SYMHASH-1];
+       for (sym = *htab; sym; sym = sym->h_next) {
+               if (sym->id > 0 && sym->id != id)
+                       break;
+       }
+       if (!sym) {
+               sym = xcalloc(1, sizeof(*sym));
+               sym->id = id;
+               if (!infunction) {
+                       sym->next = NULL;
+               } else {
+                       sym->next = locals;
+                       locals = sym;
+               }
+               sym->h_next = *htab;
+               *htab = sym;
+       }
+       return sym;
+}

Reply via email to