shithub: mc

Download patch

ref: 6ca71755bfa098a5849753f3aa7512f0b10257aa
parent: 4754ca5116714151571639cff957ee0e18a155cc
author: Ori Bernstein <[email protected]>
date: Sat Jun 16 20:38:06 EDT 2012

Read and write the contents of usefiles properly.

    Still to do: Merge it into the current symbol table.

--- a/parse/dump.c
+++ b/parse/dump.c
@@ -50,7 +50,7 @@
 
 static void outstab(Stab *st, FILE *fd, int depth)
 {
-    int i, n;
+    size_t i, n;
     void **k;
     char *ty;
 
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -124,7 +124,7 @@
     return htidx(ht, k) >= 0;
 }
 
-void **htkeys(Htab *ht, int *nkeys)
+void **htkeys(Htab *ht, size_t *nkeys)
 {
     void **k;
     size_t i, j;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -428,6 +428,7 @@
         case Nfile:
             pushstab(n->file.globls);
             inferstab(n->file.globls);
+	    inferstab(n->file.exports);
 	    for (i = 0; i < n->file.nstmts; i++) {
 		d  = n->file.stmts[i];
 		infernode(d, NULL, sawret);
@@ -434,7 +435,7 @@
 		if (d->type == Ndecl)  {
 		    s = getdcl(file->file.exports, d->decl.sym->name);
 		    if (s)
-			unify(n, type(n), s->type);
+			unify(d, type(d), s->type);
 		}
 	    }
             popstab();
@@ -541,6 +542,28 @@
     }
 }
 
+static void stabsub(Stab *s)
+{
+    void **k;
+    size_t n, i;
+    Type *t;
+    Sym *d;
+
+    k = htkeys(s->ty, &n);
+    for (i = 0; i < n; i++) {
+        t = tf(gettype(s, k[i]));
+        updatetype(s, k[i], t);
+    }
+    free(k);
+
+    k = htkeys(s->dcl, &n);
+    for (i = 0; i < n; i++) {
+	d = getdcl(s, k[i]);
+	d->type = tyfin(d->name, d->type);
+    }
+    free(k);
+}
+
 static void typesub(Node *n)
 {
     size_t i;
@@ -549,6 +572,8 @@
         return;
     switch (n->type) {
         case Nfile:
+	    stabsub(n->file.globls);
+	    stabsub(n->file.exports);
             for (i = 0; i < n->file.nstmts; i++)
                 typesub(n->file.stmts[i]);
             break;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -1,3 +1,4 @@
+typedef uint8_t         byte;
 typedef uint32_t        unichar;
 typedef unsigned int    uint;
 typedef unsigned long   ulong;
@@ -89,6 +90,7 @@
     long  id;
     int   line;
     int   isconst;
+    int   isgeneric;
     Node *name;
     Type *type;
 };
@@ -246,7 +248,7 @@
 int htput(Htab *ht, void *k, void *v);
 void *htget(Htab *ht, void *k);
 int hthas(Htab *ht, void *k);
-void **htkeys(Htab *ht, int *nkeys);
+void **htkeys(Htab *ht, size_t *nkeys);
 /* useful key types */
 ulong strhash(void *str);
 int streq(void *s1, void *s2);
@@ -363,15 +365,36 @@
 char *litstr(Littype lt);
 char *tidstr(Ty tid);
 
-/* serialization/usefiles */
-void pickle(Node *n, FILE *fd);
-Node *unpickle(FILE *fd);
-
-/* convenience func */
+/* convenience funcs */
 void lappend(void *l, size_t *len, void *n); /* ugly hack; nl is void* because void*** is incompatible with T*** */
 void *lpop(void *l, size_t *len);
 void ldel(void *l, size_t *len, size_t idx);
 void lfree(void *l, size_t *len);
+
+/* serialization/usefiles */
+void typickle(Type *t, FILE *fd);
+void sympickle(Sym *s, FILE *fd);
+void pickle(Node *n, FILE *fd);
+Type *tyunpickle(FILE *fd);
+Sym  *symunpickle(FILE *fd);
+Node *unpickle(FILE *fd);
+
+/* serializing/unserializing */
+void be64(vlong v, byte buf[8]);
+vlong host64(byte buf[8]);
+void be32(long v, byte buf[4]);
+long host32(byte buf[4]);
+
+void wrbyte(FILE *fd, char val);
+char rdbyte(FILE *fd);
+void wrint(FILE *fd, long val);
+long rdint(FILE *fd);
+void wrstr(FILE *fd, char *val);
+char *rdstr(FILE *fd);
+void wrflt(FILE *fd, double val);
+double rdflt(FILE *fd);
+void wrbool(FILE *fd, int val);
+int rdbool(FILE *fd);
 
 /* Options to control the compilation */
 extern int debug;
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -20,160 +20,9 @@
 static void wrsym(FILE *fd, Sym *val);
 static Sym *rdsym(FILE *fd);
 
-static void be64(vlong v, char buf[8])
-{
-    buf[0] = (v >> 56) & 0xff;
-    buf[1] = (v >> 48) & 0xff;
-    buf[2] = (v >> 40) & 0xff;
-    buf[3] = (v >> 32) & 0xff;
-    buf[4] = (v >> 24) & 0xff;
-    buf[5] = (v >> 16) & 0xff;
-    buf[6] = (v >> 8)  & 0xff;
-    buf[7] = (v >> 0)  & 0xff;
-}
-
-static vlong host64(char buf[8])
-{
-    vlong v = 0;
-
-    v |= ((vlong)buf[0] << 56LL) & 0xff;
-    v |= ((vlong)buf[1] << 48LL) & 0xff;
-    v |= ((vlong)buf[2] << 40LL) & 0xff;
-    v |= ((vlong)buf[3] << 32LL) & 0xff;
-    v |= ((vlong)buf[4] << 24LL) & 0xff;
-    v |= ((vlong)buf[5] << 16LL) & 0xff;
-    v |= ((vlong)buf[6] << 8LL)  & 0xff;
-    v |= ((vlong)buf[7] << 0LL)  & 0xff;
-    return v;
-}
-
-static void be32(long v, char buf[4])
-{
-    buf[0] = (v >> 24) & 0xff;
-    buf[1] = (v >> 16) & 0xff;
-    buf[2] = (v >> 8)  & 0xff;
-    buf[3] = (v >> 0)  & 0xff;
-}
-
-static long host32(char buf[4])
-{
-    long v = 0;
-    v |= (buf[4] << 24) & 0xff;
-    v |= (buf[5] << 16) & 0xff;
-    v |= (buf[6] << 8)  & 0xff;
-    v |= (buf[7] << 0)  & 0xff;
-    return v;
-}
-
-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, long val)
-{
-    char buf[4];
-    be32(val, buf);
-    if (fwrite(buf, 4, 1, fd) < 4)
-        die("Unexpected EOF");
-}
-
-static long rdint(FILE *fd)
-{
-    char buf[4];
-    if (fread(buf, 4, 1, fd) < 4)
-        die("Unexpected EOF");
-    return host32(buf);
-}
-
-static void wrstr(FILE *fd, char *val)
-{
-    size_t len;
-    size_t n;
-
-    if (!val) {
-        wrint(fd, -1);
-    } else {
-        wrint(fd, strlen(val));
-        len = strlen(val);
-        n = 0;
-        while (n < len) {
-            n += fwrite(val, len - n, 1, fd);
-            if (feof(fd) || ferror(fd))
-                die("Unexpected EOF");
-        }
-    }
-}
-
-static char *rdstr(FILE *fd)
-{
-    ssize_t len;
-    char *s;
-
-    len = rdint(fd);
-    if (len == -1) {
-        return NULL;
-    } else {
-        s = xalloc(len + 1);
-        if (fread(s, len, 1, fd) != (size_t)len)
-            die("Unexpected EOF");
-        s[len] = '\0';
-        return s;
-    }
-}
-
-static void wrflt(FILE *fd, double val)
-{
-    char buf[8];
-    /* Assumption: We have 'val' in 64 bit IEEE format */
-    union {
-        uvlong ival;
-        double fval;
-    } u;
-
-    u.fval = val;
-    be64(u.ival, buf);
-    if (fwrite(buf, 8, 1, fd) < 8)
-        die("Unexpected EOF");
-}
-
-static double rdflt(FILE *fd)
-{
-    char buf[8];
-    union {
-        uvlong ival;
-        double fval;
-    } u;
-
-    if (fread(buf, 8, 1, fd) < 8)
-        die("Unexpected EOF");
-    u.ival = host64(buf);
-    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 n, i;
+    size_t n, i;
     void **keys;
 
     pickle(val->name, fd);
@@ -252,7 +101,16 @@
     return mksym(line, name, type);
 }
 
+Type *tyunpickle(FILE *fd)
+{
+    return rdtype(fd);
+}
 
+Sym *symunpickle(FILE *fd)
+{
+    return rdsym(fd);
+}
+
 static void wrtype(FILE *fd, Type *ty)
 {
     size_t i;
@@ -261,7 +119,6 @@
         die("trying to pickle null type\n");
         return;
     }
-    printf("Writing %s\n", tystr(ty));
     wrbyte(fd, ty->type);
     /* tid is generated; don't write */
     /* cstrs are left out for now: FIXME */
@@ -355,8 +212,17 @@
                 ty->sub[i] = rdtype(fd);
             break;
     }
-    printf("Read %s\n", tystr(ty));
     return ty;
+}
+
+void typickle(Type *t, FILE *fd)
+{
+    wrtype(fd, t);
+}
+
+void sympickle(Sym *s, FILE *fd)
+{
+    wrsym(fd, s);
 }
 
 /* pickle format:
--- a/parse/use.c
+++ b/parse/use.c
@@ -11,8 +11,29 @@
 
 #include "parse.h"
 
-int loaduse(FILE *fd, Stab *st)
+int loaduse(FILE *f, Stab *st)
 {
+    char *pkg;
+    int c;
+
+    if (fgetc(f) != 'U')
+	return 0;
+    pkg = rdstr(f);
+    /* if the package names match up, or the usefile has no declared
+     * package, then we simply add to the current stab. Otherwise,
+     * we add a new stab under the current one */
+    if (pkg) {
+	printf("package name %s\n", pkg);
+    }
+    while ((c = fgetc(f)) != 'Z') {
+	switch(c) {
+	    case 'G': die("We didn't implement generics yet!"); break;
+	    case 'D': dumpsym(symunpickle(f), stdout); break;
+	    case 'T': fprintf(stdout, "%s\n", tystr(tyunpickle(f))); break;
+	    case EOF:
+		break;
+	}
+    }
     return 1;
 }
 
@@ -38,11 +59,49 @@
 	}
     }
 
-    if (loaduse(fd, st))
+    if (!loaduse(fd, st))
 	die("Could not load usefile %s", use->use.name);
 }
 
-void writeuse(Node *file, FILE *out)
+/* Usefile format:
+ * U<pkgname>
+ * T<typename><pickled-type>
+ * D<picled-decl>
+ * G<pickled-decl><pickled-initializer>
+ * Z
+ */
+void writeuse(Node *file, FILE *f)
 {
+    Stab *st;
+    void **k;
+    Type *t;
+    Sym *s;
+    size_t i, n;
+
+    st = file->file.exports;
+    wrbyte(f, 'U');
+    if (st->name)
+	wrstr(f, namestr(st->name));
+    else
+	wrstr(f, NULL);
+
+    k = htkeys(st->ty, &n);
+    for (i = 0; i < n; i++) {
+	t = htget(st->ty, k[i]);
+	wrbyte(f, 'T');
+	typickle(t, f);
+    }
+    free(k);
+    k = htkeys(st->dcl, &n);
+    for (i = 0; i < n; i++) {
+	s = getdcl(st, k[i]);
+	if (s->isgeneric)
+	    wrbyte(f, 'G');
+	else
+	    wrbyte(f, 'D');
+	sympickle(s, f);
+    }
+    free(k);
+    wrbyte(f, 'Z');
 }
 
--- a/parse/util.c
+++ b/parse/util.c
@@ -154,3 +154,173 @@
     *pl = NULL;
     *len = 0;
 }
+
+void be64(vlong v, byte buf[8])
+{
+    buf[0] = (v >> 56) & 0xff;
+    buf[1] = (v >> 48) & 0xff;
+    buf[2] = (v >> 40) & 0xff;
+    buf[3] = (v >> 32) & 0xff;
+    buf[4] = (v >> 24) & 0xff;
+    buf[5] = (v >> 16) & 0xff;
+    buf[6] = (v >> 8)  & 0xff;
+    buf[7] = (v >> 0)  & 0xff;
+}
+
+vlong host64(byte buf[8])
+{
+    vlong v = 0;
+
+    v |= ((vlong)buf[0] << 56LL);
+    v |= ((vlong)buf[1] << 48LL);
+    v |= ((vlong)buf[2] << 40LL);
+    v |= ((vlong)buf[3] << 32LL);
+    v |= ((vlong)buf[4] << 24LL);
+    v |= ((vlong)buf[5] << 16LL);
+    v |= ((vlong)buf[6] << 8LL);
+    v |= ((vlong)buf[7] << 0LL);
+    return v;
+}
+
+void be32(long v, byte buf[4])
+{
+    buf[0] = (v >> 24) & 0xff;
+    buf[1] = (v >> 16) & 0xff;
+    buf[2] = (v >> 8)  & 0xff;
+    buf[3] = (v >> 0)  & 0xff;
+}
+
+long host32(byte buf[4])
+{
+    int32_t v = 0;
+    v |= ((long)buf[0] << 24);
+    v |= ((long)buf[1] << 16);
+    v |= ((long)buf[2] << 8);
+    v |= ((long)buf[3] << 0);
+    return v;
+}
+
+void wrbuf(FILE *fd, void *buf, size_t sz)
+{
+    size_t n;
+
+    n = 0;
+    while (n < sz) {
+	n += fwrite(buf + n, 1, sz - n, fd);
+	if (feof(fd))
+	    die("Unexpected EOF");
+	if (ferror(fd))
+	    die("Error writing");
+    }
+}
+
+void rdbuf(FILE *fd, void *buf, size_t sz)
+{
+    size_t n;
+
+    n = sz;
+    while (n > 0) {
+	n -= fread(buf, 1, n, fd);
+	if (feof(fd))
+	    die("Unexpected EOF");
+	if (ferror(fd))
+	    die("Error writing");
+    }
+}
+
+void wrbyte(FILE *fd, char val)
+{
+    if (fputc(val, fd) == EOF)
+        die("Unexpected EOF");
+}
+
+char rdbyte(FILE *fd)
+{
+    int c;
+    c = fgetc(fd);
+    if (c == EOF)
+        die("Unexpected EOF");
+    return c;
+}
+
+void wrint(FILE *fd, long val)
+{
+    byte buf[4];
+    be32(val, buf);
+    wrbuf(fd, buf, 4);
+}
+
+long rdint(FILE *fd)
+{
+    byte buf[4];
+    rdbuf(fd, buf, 4);
+    return host32(buf);
+}
+
+void wrstr(FILE *fd, char *val)
+{
+    size_t len;
+
+    if (!val) {
+        wrint(fd, -1);
+    } else {
+        wrint(fd, strlen(val));
+        len = strlen(val);
+	wrbuf(fd, val, len);
+    }
+}
+
+char *rdstr(FILE *fd)
+{
+    ssize_t len;
+    char *s;
+
+    len = rdint(fd);
+    if (len == -1) {
+        return NULL;
+    } else {
+        s = xalloc(len + 1);
+	rdbuf(fd, s, len);
+        s[len] = '\0';
+        return s;
+    }
+}
+
+void wrflt(FILE *fd, double val)
+{
+    byte buf[8];
+    /* Assumption: We have 'val' in 64 bit IEEE format */
+    union {
+        uvlong ival;
+        double fval;
+    } u;
+
+    u.fval = val;
+    be64(u.ival, buf);
+    wrbuf(fd, buf, 8);
+}
+
+double rdflt(FILE *fd)
+{
+    byte buf[8];
+    union {
+        uvlong ival;
+        double fval;
+    } u;
+
+    if (fread(buf, 8, 1, fd) < 8)
+        die("Unexpected EOF");
+    u.ival = host64(buf);
+    return u.fval;
+}
+
+void wrbool(FILE *fd, int val)
+{
+    wrbyte(fd, val);
+}
+
+int rdbool(FILE *fd)
+{
+    return rdbyte(fd);
+}
+
--- a/util/muse.c
+++ b/util/muse.c
@@ -27,6 +27,7 @@
     printf("\t-o\tOutput to outfile\n");
 }
 
+
 int main(int argc, char **argv)
 {
     int opt;
@@ -34,6 +35,7 @@
     Stab *globls;
     Node *rdback;
     FILE *tmp;
+    FILE *f;
 
     while ((opt = getopt(argc, argv, "dho:")) != -1) {
         switch (opt) {
@@ -44,6 +46,9 @@
             case 'd':
                 debug++;
                 break;
+	    case 'I':
+		lappend(&incpaths, &nincpaths, optarg);
+		break;
             default:
                 usage(argv[0]);
                 exit(0);
@@ -60,6 +65,8 @@
         file->file.globls = globls;
         yyparse();
 
+        infer(file);
+	/* before we do anything to the parse */
         if (debug) {
             /* test storing tree to file */
             tmp = fopen("a.pkl", "w");
@@ -71,12 +78,15 @@
             rdback = unpickle(tmp);
             dump(rdback, stdout);
             fclose(tmp);
-
-            /* before we do anything to the parse */
-            dump(file, stdout);
+	    dump(file, stdout);
         }
-        infer(file);
-        die("FIXME: IMPLEMENT ME!");
+	if (!outfile)
+	    die("need output file name right now. FIX THIS.");
+	f = fopen(outfile, "w");
+	writeuse(file, f);
+	fclose(f);
+	readuse(mkuse(-1, outfile, 1), file->file.globls);
+
     }
 
     return 0;