shithub: mc

Download patch

ref: 7c3b9e70440e0356db1638a425bd0e7c834ef850
parent: 58bda459dfd58e2b3dc3b9bc31051ca9ede70698
author: Ori Bernstein <[email protected]>
date: Tue Jan 3 11:46:20 EST 2012

Start of pickling stuff.

--- a/parse/Makefile
+++ b/parse/Makefile
@@ -1,11 +1,12 @@
 BIN=pt
 OBJ=dump.o \
     ds.o \
+    gram.o \
     infer.o \
     main.o \
     names.o \
     node.o \
-    gram.o \
+    pickle.o \
     tok.o \
     type.o \
     use.o \
@@ -18,4 +19,3 @@
 
 ops.o: ../mc/ops.c
 	$(CC) -c $(CFLAGS) $<
-
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -161,6 +161,9 @@
             }
             fprintf(fd, ")\n");
             break;
+        case Nnone:
+            die("Nnone a real node type!");
+            break;
     }
 }
 
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -149,6 +149,7 @@
 %%
 
 module  : file
+        | /* empty */
         ;
 
 file    : toplev
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -324,6 +324,9 @@
         case Nuse:
         case Nlbl:
             break;
+        case Nnone:
+            die("Nnone should not be seen as node type!");
+            break;
     }
 }
 
@@ -389,6 +392,9 @@
         case Nlit:
         case Nuse:
         case Nlbl:
+            break;
+        case Nnone:
+            die("Nnone should not be seen as node type!");
             break;
     }
 }
--- a/parse/main.c
+++ b/parse/main.c
@@ -26,6 +26,8 @@
 {
     int opt;
     int i;
+    Node *rdback;
+    FILE *tmp;
 
     while ((opt = getopt(argc, argv, "dho:")) != -1) {
         switch (opt) {
@@ -50,7 +52,18 @@
         file->file.exports = mkstab(NULL);
         file->file.globls = mkstab(NULL);
         yyparse();
+
         dump(file, stdout);
+
+        tmp = fopen("test.pkl", "w");
+        pickle(file, tmp);
+        fclose(tmp);
+
+        tmp = fopen("test.pkl", "r");
+        rdback = unpickle(tmp);
+        dump(rdback, stdout);
+        fclose(tmp);
+
         infer(file);
         dump(file, stdout);
         gen();
--- a/parse/node.c
+++ b/parse/node.c
@@ -12,7 +12,7 @@
 
 #include "parse.h"
 
-static Node *mknode(int line, Ntype nt)
+Node *mknode(int line, Ntype nt)
 {
     Node *n;
 
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -1,3 +1,4 @@
+N(Nnone)
 N(Nfile)
 N(Nblock)
 N(Nifstmt)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -175,14 +175,14 @@
 
         struct {
             Sym *sym;
-            Node *init;
             int flags;
+            Node *init;
         } decl;
 
         struct {
             Stab *scope;
-            Node **args;
             size_t nargs;
+            Node **args;
             Node *body;
         } func;
     };
@@ -263,6 +263,7 @@
 void tlappend(Type ***tl, int *len, Type *t);
 
 /* node creation */
+Node *mknode(int line, Ntype nt);
 Node *mkfile(char *name);
 Node *mkuse(int line, char *use, int islocal);
 Node *mkexpr(int line, Op op, ...); /* NULL terminated */
@@ -304,6 +305,10 @@
 char *nodestr(Ntype nt);
 char *litstr(Littype lt);
 char *tidstr(Ty tid);
+
+/* serialization/usefiles */
+void pickle(Node *n, FILE *fd);
+Node *unpickle(FILE *fd);
 
 /* convenience func */
 void nlappend(Node ***nl, size_t *len, Node *n);
--- /dev/null
+++ b/parse/pickle.c
@@ -1,0 +1,375 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#include <endian.h>
+
+#include "parse.h"
+static void wrtype(FILE *fd, Type *val);
+static Type *rdtype(FILE *fd);
+static void wrstab(FILE *fd, Stab *val);
+static Stab *rdstab(FILE *fd);
+static void wrsym(FILE *fd, Sym *val);
+static Sym *rdsym(FILE *fd);
+
+static void wrbyte(FILE *fd, char val)
+{
+    if (fputc(val, fd) == EOF)
+        die("Unexpected EOF");
+}
+
+/*static*/ char rdbyte(FILE *fd)
+{
+    int c;
+    c = fgetc(fd);
+    if (c == EOF)
+        die("Unexpected EOF");
+    return c;
+}
+
+static void wrint(FILE *fd, int32_t val)
+{
+    val = htobe32(val);
+    if (fwrite(&val, sizeof(int32_t), 1, fd) == EOF)
+        die("Unexpected EOF");
+}
+
+/*static*/ int32_t rdint(FILE *fd)
+{
+    uint32_t val;
+
+    if (fread(&val, sizeof(uint32_t), 1, fd) == EOF)
+        die("Unexpected EOF");
+    return be32toh(val);
+}
+
+static void wrstr(FILE *fd, char *val)
+{
+    if (!val) {
+        wrint(fd, -1);
+    } else {
+        wrint(fd, strlen(val));
+        if (fwrite(val, strlen(val), 1, fd) == EOF)
+            die("Unexpected EOF");
+    }
+}
+
+/*static */char *rdstr(FILE *fd)
+{
+    int len;
+    char *s;
+
+    len = rdint(fd);
+    if (len == -1) {
+        return NULL;
+    } else {
+        s = xalloc(len + 1);
+        if (fread(s, len, 1, fd) == EOF)
+            die("Unexpected EOF");
+        s[len] = '\0';
+        return s;
+    }
+}
+
+static void wrflt(FILE *fd, double val)
+{
+    /* Assumption: We have 'val' in 64 bit IEEE format */
+    union {
+        uvlong ival;
+        double fval;
+    } u;
+
+    u.fval = val;
+    u.ival = htobe64(u.ival);
+    if (fwrite(&u.ival, sizeof(uvlong), 1, fd) == EOF)
+        die("Unexpected EOF");
+}
+
+/*static */double rdflt(FILE *fd)
+{
+    union {
+        uvlong ival;
+        double fval;
+    } u;
+
+    if (fread(&u.ival, sizeof(uvlong), 1, fd) == EOF)
+        die("Unexpected EOF");
+    u.ival = be64toh(u.ival);
+    return u.fval;
+}
+
+static void wrbool(FILE *fd, int val)
+{
+    wrbyte(fd, val);
+}
+
+/*static*/ int rdbool(FILE *fd)
+{
+    return rdbyte(fd);
+}
+
+static void wrstab(FILE *fd, Stab *val)
+{
+    int i;
+
+    wrstr(fd, val->name);
+    wrint(fd, val->ntypes);
+    for (i = 0; i < val->ntypes; i++)
+        wrsym(fd, val->types[i]);
+    wrint(fd, val->nsyms);
+    for (i = 0; i < val->nsyms; i++)
+        wrsym(fd, val->syms[i]);
+}
+
+/*static*/ Stab *rdstab(FILE *fd)
+{
+    Stab *st;
+    int i;
+
+    st = mkstab(NULL);
+    st->name = rdstr(fd);
+    st->ntypes = rdint(fd);
+    st->types = xalloc(sizeof(Sym*)*st->ntypes);
+    for (i = 0; i < st->ntypes; i++)
+        st->types[i] = rdsym(fd);
+    st->nsyms = rdint(fd);
+    st->syms = xalloc(sizeof(Sym*)*st->nsyms);
+    for (i = 0; i < st->nsyms; i++)
+        st->syms[i] = rdsym(fd);
+    return st;
+}
+
+static void wrsym(FILE *fd, Sym *val)
+{
+    wrint(fd, val->line);
+    pickle(val->name, fd);
+    wrtype(fd, val->type);
+}
+
+/*static*/ Sym *rdsym(FILE *fd)
+{
+    int line;
+    Node *name;
+    Type *type;
+
+    line = rdint(fd);
+    name = unpickle(fd);
+    type = rdtype(fd);
+    return mksym(line, name, type);
+}
+
+
+static void wrtype(FILE *fd, Type *t)
+{
+}
+
+/*static*/ Type *rdtype(FILE *fd)
+{
+    return mktyvar(-1);
+}
+
+/* pickle format:
+ *      type:byte
+ *      node-attrs: string|size|
+ *      nsub:int32_be
+ *      sub:node[,]
+ */
+void pickle(Node *n, FILE *fd)
+{
+    int i;
+
+    if (!n) {
+        wrbyte(fd, Nnone);
+        return;
+    }
+    wrbyte(fd, n->type);
+    wrint(fd, n->line);
+    switch (n->type) {
+        case Nfile:
+            wrstr(fd, n->file.name);
+            wrint(fd, n->file.nuses);
+            for (i = 0; i < n->file.nuses; i++)
+                pickle(n->file.uses[i], fd);
+            wrint(fd, n->file.nstmts);
+            for (i = 0; i < n->file.nstmts; i++)
+                pickle(n->file.stmts[i], fd);
+            wrstab(fd, n->file.globls);
+            wrstab(fd, n->file.exports);
+            break;
+
+        case Nexpr:
+            wrbyte(fd, n->expr.op);
+            wrtype(fd, n->expr.type);
+            wrbool(fd, n->expr.isconst);
+            wrint(fd, n->expr.nargs);
+            for (i = 0; i < n->expr.nargs; i++)
+                pickle(n->expr.args[i], fd);
+            break;
+        case Nname:
+            wrint(fd, n->name.nparts);
+            for (i = 0; i < n->name.nparts; i++)
+                wrstr(fd, n->name.parts[i]);
+            break;
+        case Nuse:
+            wrbool(fd, n->use.islocal);
+            wrstr(fd, n->use.name);
+            break;
+        case Nlit:
+            wrbyte(fd, n->lit.littype);
+            wrtype(fd, n->lit.type);
+            switch (n->lit.littype) {
+                case Lchr:      wrint(fd, n->lit.chrval);       break;
+                case Lint:      wrint(fd, n->lit.intval);       break;
+                case Lflt:      wrflt(fd, n->lit.fltval);       break;
+                case Lstr:      wrstr(fd, n->lit.strval);       break;
+                case Lbool:     wrbool(fd, n->lit.boolval);     break;
+                case Lfunc:     pickle(n->lit.fnval, fd);       break;
+                case Larray:    pickle(n->lit.arrval, fd);      break;
+            }
+            break;
+        case Nloopstmt:
+            pickle(n->loopstmt.init, fd);
+            pickle(n->loopstmt.cond, fd);
+            pickle(n->loopstmt.step, fd);
+            pickle(n->loopstmt.body, fd);
+            break;
+        case Nifstmt:
+            pickle(n->ifstmt.cond, fd);
+            pickle(n->ifstmt.iftrue, fd);
+            pickle(n->ifstmt.iffalse, fd);
+            break;
+        case Nblock:
+            wrstab(fd, n->block.scope);
+            wrint(fd, n->block.nstmts);
+            for (i = 0; i < n->block.nstmts; i++)
+                pickle(n->block.stmts[i], fd);
+            break;
+        case Nlbl:
+            wrstr(fd, n->lbl.name);
+            break;
+        case Ndecl:
+            wrsym(fd, n->decl.sym);
+            wrint(fd, n->decl.flags);
+            pickle(n->decl.init, fd);
+            break;
+        case Nfunc:
+            wrstab(fd, n->func.scope);
+            wrint(fd, n->func.nargs);
+            for (i = 0; i < n->func.nargs; i++)
+                pickle(n->func.args[i], fd);
+            pickle(n->func.body, fd);
+            break;
+        case Nnone:
+            die("Nnone should not be seen as node type!");
+            break;
+    }
+}
+
+Node *unpickle(FILE *fd)
+{
+    int i;
+    Ntype type;
+    Node *n;
+
+    type = rdbyte(fd);
+    if (type == Nnone)
+        return NULL;
+    n = mknode(-1, type);
+    n->line = rdint(fd);
+    switch (n->type) {
+        case Nfile:
+            n->file.name = rdstr(fd);
+            n->file.nuses = rdint(fd);
+            n->file.uses = xalloc(sizeof(Node*)*n->file.nuses);
+            for (i = 0; i < n->file.nuses; i++)
+                n->file.uses[i] = unpickle(fd);
+            n->file.nstmts = rdint(fd);
+            n->file.stmts = xalloc(sizeof(Node*)*n->file.nstmts);
+            for (i = 0; i < n->file.nstmts; i++)
+                n->file.stmts[i] = unpickle(fd);
+            n->file.globls = rdstab(fd);
+            n->file.exports = rdstab(fd);
+            break;
+
+        case Nexpr:
+            n->expr.op = rdbyte(fd);
+            n->expr.type = rdtype(fd);
+            n->expr.isconst = rdbool(fd);
+            n->expr.nargs = rdint(fd);
+            n->expr.args = xalloc(sizeof(Node *)*n->expr.nargs);
+            for (i = 0; i < n->expr.nargs; i++)
+                n->expr.args[i] = unpickle(fd);
+            break;
+        case Nname:
+            n->name.nparts = rdint(fd);
+            n->name.parts = xalloc(sizeof(Node *)*n->name.nparts);
+            for (i = 0; i < n->name.nparts; i++)
+                n->name.parts[i] = rdstr(fd);
+            break;
+        case Nuse:
+            n->use.islocal = rdbool(fd);
+            n->use.name = rdstr(fd);
+            break;
+        case Nlit:
+            n->lit.littype = rdbyte(fd);
+            n->lit.type = rdtype(fd);
+            switch (n->lit.littype) {
+                case Lchr:      n->lit.chrval = rdint(fd);       break;
+                case Lint:      n->lit.intval = rdint(fd);       break;
+                case Lflt:      n->lit.fltval = rdflt(fd);       break;
+                case Lstr:      n->lit.strval = rdstr(fd);       break;
+                case Lbool:     n->lit.boolval = rdbool(fd);     break;
+                case Lfunc:     n->lit.fnval = unpickle(fd);       break;
+                case Larray:    n->lit.arrval = unpickle(fd);      break;
+            }
+            break;
+        case Nloopstmt:
+            n->loopstmt.init = unpickle(fd);
+            n->loopstmt.cond = unpickle(fd);
+            n->loopstmt.step = unpickle(fd);
+            n->loopstmt.body = unpickle(fd);
+            break;
+        case Nifstmt:
+            n->ifstmt.cond = unpickle(fd);
+            n->ifstmt.iftrue = unpickle(fd);
+            n->ifstmt.iffalse = unpickle(fd);
+            break;
+        case Nblock:
+            n->block.scope = rdstab(fd);
+            n->block.nstmts = rdint(fd);
+            n->block.stmts = xalloc(sizeof(Node *)*n->block.nstmts);
+            for (i = 0; i < n->block.nstmts; i++)
+                n->block.stmts[i] = unpickle(fd);
+            break;
+        case Nlbl:
+            n->lbl.name = rdstr(fd);
+            break;
+        case Ndecl:
+            n->decl.sym = rdsym(fd);
+            n->decl.flags = rdint(fd);
+            n->decl.init = unpickle(fd);
+            break;
+        case Nfunc:
+            n->func.scope = rdstab(fd);
+            n->func.nargs = rdint(fd);
+            n->func.args = xalloc(sizeof(Node *)*n->func.nargs);
+            for (i = 0; i < n->func.nargs; i++)
+                n->func.args[i] = unpickle(fd);
+            n->func.body = unpickle(fd);
+            break;
+        case Nnone:
+            die("Nnone should not be seen as node type!");
+            break;
+    }
+    return n;
+}