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;