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;
+}