ref: e4b256232bcc27fcc73a80d0b5e1400c5624889d
parent: e24bcc37239283534785e2e2a31393f20ae6c9b7
author: Ori Bernstein <[email protected]>
date: Wed Aug 15 08:01:25 EDT 2012
More comments.
--- a/6/simp.c
+++ b/6/simp.c
@@ -114,6 +114,7 @@
{
Node *n;
+ assert(exprop(a) != Oload);
n = mkexpr(a->line, Oaddr, a, NULL);
if (!bt)
n->expr.type = mktyptr(a->line, a->expr.type);
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -20,6 +20,9 @@
static void wrsym(FILE *fd, Node *val);
static Node *rdsym(FILE *fd);
+/* Outputs a symbol table to file in a way that can be
+ * read back usefully. Only writes declarations, types
+ * and sub-namespaces. Captured variables are ommitted. */
static void wrstab(FILE *fd, Stab *val)
{
size_t n, i;
@@ -51,6 +54,8 @@
free(keys);
}
+/* Reads a symbol table from file. The converse
+ * of wrstab. */
static Stab *rdstab(FILE *fd)
{
Stab *st;
@@ -109,6 +114,10 @@
return uc;
}
+/* Writes the name and type of a variable,
+ * but only writes its intializer for things
+ * we want to inline cross-file (currently,
+ * the only cross-file inline is generics) */
static void wrsym(FILE *fd, Node *val)
{
/* sym */
@@ -157,6 +166,9 @@
return rdsym(fd);
}
+/* Writes types to a file. Errors on
+ * internal only types like Tyvar that
+ * will not be meaningful in another file */
static void wrtype(FILE *fd, Type *ty)
{
size_t i;
@@ -207,6 +219,9 @@
}
}
+/* Writes types to a file. Errors on
+ * internal only types like Tyvar that
+ * will not be meaningful in another file */
static Type *rdtype(FILE *fd)
{
Type *ty;
@@ -268,12 +283,12 @@
wrsym(fd, s);
}
-/* pickle format:
- * type:byte
- * node-attrs: string|size|
- * nsub:int32_be
- * sub:node[,]
- */
+/* Pickles a node to a file. The format
+ * is more or less equivalen to to
+ * simplest serialization of the
+ * in-memory representation. Minimal
+ * checking is done, so a bad type can
+ * crash the compiler */
void pickle(Node *n, FILE *fd)
{
size_t i;
@@ -390,6 +405,9 @@
}
}
+/* Unpickles a node from a file. Minimal checking
+ * is done. Specifically, no checks are done for
+ * sane arities, a bad file can crash the compiler */
Node *unpickle(FILE *fd)
{
size_t i;
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -11,23 +11,30 @@
#include "parse.h"
-static ulong tyhash(void *p)
+static ulong typaramhash(void *p)
{
Type *t;
t = p;
+ assert(t->type == Typaram);
return strhash(t->pname);
}
-static int tyeq(void *pa, void *pb)
+static int typarameq(void *pa, void *pb)
{
Type *a, *b;
a = pa;
b = pb;
+ assert(a->type == Typaram);
+ assert(b->type == Typaram);
return streq(a->pname, b->pname);
}
+/*
+ * Checks if a type contains any type
+ * parameers at all (ie, if it generic).
+ */
static int hasparams(Type *t)
{
size_t i;
@@ -40,6 +47,11 @@
return 0;
}
+/*
+ * Duplicates the type 't', with all bound type
+ * parameters substituted with the substitions
+ * described in 'tsmap'
+ */
static Type *dosubst(Type *t, Htab *tsmap)
{
Type *ret;
@@ -56,6 +68,9 @@
return ret;
}
+/* Checks if the type 't' is generic, and if it is
+ * substitutes the types. This is here for efficiency,
+ * so we don't gratuitously duplicate types */
static Type *tysubst(Type *t, Htab *tsmap)
{
if (hasparams(t))
@@ -64,6 +79,10 @@
return t;
}
+/*
+ * Fills the substitution map with a mapping from
+ * the type parameter 'from' to it's substititon 'to'
+ */
static void fillsubst(Htab *tsmap, Type *to, Type *from)
{
size_t i;
@@ -77,6 +96,10 @@
fillsubst(tsmap, to->sub[i], from->sub[i]);
}
+/*
+ * Fixes up nodes. This involves fixing up the
+ * declaration identifiers once we specialize
+ */
static void fixup(Node *n)
{
size_t i;
@@ -148,6 +171,12 @@
}
}
+
+/*
+ * Duplicates a node, replacing all things that
+ * need to be specialized to make it concrete
+ * instead of generic, and returns it.
+ */
static Node *specializenode(Node *n, Htab *tsmap)
{
Node *r;
@@ -287,6 +316,11 @@
return mkname(n->line, buf);
}
+/*
+ * Takes a generic declaration, and creates a specialized
+ * duplicate of it with type 'to'. It also generates
+ * a name for this specialized node, and returns it in '*name'.
+ */
Node *specializedcl(Node *n, Type *to, Node **name)
{
Htab *tsmap;
@@ -309,9 +343,8 @@
pushstab(st);
}
-
-
- tsmap = mkht(tyhash, tyeq);
+ /* specialize */
+ tsmap = mkht(typaramhash, typarameq);
fillsubst(tsmap, to, n->decl.type);
d = mkdecl(n->line, *name, tysubst(n->decl.type, tsmap));
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -12,6 +12,7 @@
#include "parse.h"
+/* Allows us to look up types/cstrs by name nodes */
typedef struct Tydefn Tydefn;
typedef struct Cstrdefn Cstrdefn;
struct Tydefn {
@@ -29,6 +30,8 @@
#define Maxstabdepth 128
static Stab *stabstk[Maxstabdepth];
static int stabstkoff;
+
+/* scope management */
Stab *curstab()
{
return stabstk[stabstkoff - 1];
@@ -36,6 +39,7 @@
void pushstab(Stab *st)
{
+ assert(stabstkoff < Maxstabdepth);
stabstk[stabstkoff++] = st;
}
@@ -44,6 +48,7 @@
stabstkoff--;
}
+/* name hashing */
static ulong namehash(void *n)
{
return strhash(namestr(n));
@@ -66,7 +71,16 @@
return st;
}
-/* FIXME: do namespaces */
+/*
+ * Searches for declarations from current
+ * scope, and all enclosing scopes. Does
+ * not resolve namespaces -- that is the job
+ * of the caller of this function.
+ *
+ * If a resoved name is not global, and is
+ * not in the current scope, it is recorded
+ * in the scope's closure.
+ */
Node *getdcl(Stab *st, Node *n)
{
Node *s;
@@ -199,6 +213,11 @@
htput(st->ns, scope->name, scope);
}
+/*
+ * Sets the namespace of a symbol table, and
+ * changes the namespace of all contained symbols
+ * to match it.
+ */
void updatens(Stab *st, char *name)
{
void **k;
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -15,11 +15,14 @@
#include "gram.h"
+#define End (-1)
+
char *filename;
int line;
int ignorenl;
Tok *curtok;
+/* the file contents are stored globally */
static int fidx;
static int fbufsz;
static char *fbuf;
@@ -27,7 +30,7 @@
static int peekn(int n)
{
if (fidx + n >= fbufsz)
- return '\0';
+ return End;
else
return fbuf[fidx + n];
}
@@ -102,7 +105,7 @@
case '\n':
line++;
break;
- case '\0':
+ case End:
fatal(line, "File ended within comment starting at line %d", startln);
break;
}
@@ -276,7 +279,7 @@
/* we don't unescape here, but on output */
if (c == '"')
break;
- else if (c == '\0')
+ else if (c == End)
fatal(line, "Unexpected EOF within string");
else if (c == '\n')
fatal(line, "Newlines not allowed in strings");
@@ -309,7 +312,7 @@
/* we don't unescape here, but on output */
if (c == '\'')
break;
- else if (c == '\0')
+ else if (c == End)
fatal(line, "Unexpected EOF within char lit");
else if (c == '\n')
fatal(line, "Newlines not allowed in char lit");
@@ -553,7 +556,7 @@
eatspace();
c = peek();
- if (c == '\0') {
+ if (c == End) {
t = mktok(0);
} else if (c == '\n') {
line++;