ref: d3793273ebda652a2805567bda50f3082c5f514e
parent: b5bfdc4046312756d217fade2fb7ec63de568ff0
parent: 8dbc15066f3576d63ee6f29824b4abeeaaa51e20
author: Ori Bernstein <[email protected]>
date: Thu Dec 15 16:56:16 EST 2011
Merge branch 'master' of git+ssh://eigenstate.org/git/ori/mc2
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -146,6 +146,10 @@
indent(fd, depth);
fprintf(fd, ")\n");
outnode(n->func.body, fd, depth+1);
+ break;
+ case Nlbl:
+ fprintf(fd, "(lbl = %s)\n", n->lbl.name);
+ break;
case Nname:
fprintf(fd, "(");
for (i = 0; i < n->name.nparts; i++) {
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -18,6 +18,7 @@
int yylex(void);
Op binop(int toktype);
Stab *curscope;
+int n = 0;
%}
%token<tok> TError
@@ -121,7 +122,7 @@
%type <node> decl declbody declcore structelt enumelt unionelt
%type <node> ifstmt forstmt whilestmt elifs optexprln
-%type <nodelist> arglist argdefs structbody enumbody unionbody params
+%type <nodelist> arglist argdefs structbody enumbody unionbody params
%union {
struct {
@@ -155,10 +156,10 @@
;
toplev
- : decl
+ : decl
{nlappend(&file->file.stmts, &file->file.nstmts, $1);
def(file->file.globls, $1);}
- | use
+ | use
{nlappend(&file->file.uses, &file->file.nuses, $1);}
| package
| tydef
@@ -169,10 +170,10 @@
decl : TVar declbody TEndln
{$2->decl.flags = 0;
$$ = $2;}
- | TConst declbody TEndln
+ | TConst declbody TEndln
{$2->decl.flags = Dclconst;
$$ = $2;}
- | TExtern TVar declbody TEndln
+ | TExtern TVar declbody TEndln
{$3->decl.flags = Dclextern;
$$ = $3;}
| TExtern TConst declbody TEndln
@@ -180,9 +181,9 @@
$$ = $3;}
;
-use : TUse TIdent TEndln
+use : TUse TIdent TEndln
{$$ = mkuse($1->line, $2->str, 0);}
- | TUse TStrlit TEndln
+ | TUse TStrlit TEndln
{$$ = mkuse($1->line, $2->str, 1);}
;
@@ -210,7 +211,7 @@
| declcore
;
-declcore: name
+declcore: name
{$$ = mkdecl($1->line, mksym($1->line, $1, mktyvar($1->line)));}
| name TColon type
{$$ = mkdecl($1->line, mksym($1->line, $1, $3));}
@@ -222,7 +223,7 @@
{$$ = $3; setns($3, $1->str);}
;
-tydef : TType TIdent TAsn type TEndln
+tydef : TType TIdent TAsn type TEndln
{$$.line = $1->line;
$$.name = $2->str;
$$.type = $4;}
@@ -250,22 +251,22 @@
functype: TOparen funcsig TCparen {$$ = $2;}
;
-funcsig : argdefs
+funcsig : argdefs
{$$ = mktyfunc($1.line, $1.nl, $1.nn, mktyvar($1.line));}
- | argdefs TRet type
+ | argdefs TRet type
{$$ = mktyfunc($1.line, $1.nl, $1.nn, $3);}
;
-argdefs : declcore
+argdefs : declcore
{$$.line = $1->line;
$$.nl = NULL;
$$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
- | argdefs TComma declcore
+ | argdefs TComma declcore
{nlappend(&$$.nl, &$$.nn, $3);}
;
structdef
- : TStruct structbody TEndblk
+ : TStruct structbody TEndblk
{$$ = mktystruct($1->line, $2.nl, $2.nn);}
;
@@ -272,14 +273,14 @@
structbody
: structelt
{$$.nl = NULL; $$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
- | structbody structelt
+ | structbody structelt
{if ($2) {nlappend(&$$.nl, &$$.nn, $2);}}
;
structelt
- : declcore TEndln
+ : declcore TEndln
{$$ = $1;}
- | visdef TEndln
+ | visdef TEndln
{$$ = NULL;}
| TEndln
{$$ = NULL;}
@@ -286,21 +287,21 @@
;
uniondef
- : TUnion unionbody TEndblk
+ : TUnion unionbody TEndblk
{$$ = mktyunion($1->line, $2.nl, $2.nn);}
;
unionbody
- : unionelt
+ : unionelt
{$$.nl = NULL; $$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
- | unionbody unionelt
+ | unionbody unionelt
{if ($2) {nlappend(&$$.nl, &$$.nn, $2);}}
;
unionelt
- : TIdent type TEndln
+ : TIdent type TEndln
{$$ = NULL; die("unionelt impl");}
- | visdef TEndln
+ | visdef TEndln
{$$ = NULL;}
| TEndln
{$$ = NULL;}
@@ -310,9 +311,9 @@
{$$ = mktyenum($1->line, $2.nl, $2.nn);}
;
-enumbody: enumelt
+enumbody: enumelt
{$$.nl = NULL; $$.nn = 0; if ($1) nlappend(&$$.nl, &$$.nn, $1);}
- | enumbody enumelt
+ | enumbody enumelt
{if ($2) {nlappend(&$$.nl, &$$.nn, $2);}}
;
@@ -358,22 +359,22 @@
| landexpr
;
-landexpr: landexpr TLand borexpr
+landexpr: landexpr TLand borexpr
{$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
| borexpr
;
-borexpr : borexpr TBor bandexpr
+borexpr : borexpr TBor bandexpr
{$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
| bandexpr
;
-bandexpr: bandexpr TBand cmpexpr
+bandexpr: bandexpr TBand cmpexpr
{$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
| cmpexpr
;
-cmpexpr : cmpexpr cmpop addexpr
+cmpexpr : cmpexpr cmpop addexpr
{$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
| addexpr
;
@@ -380,7 +381,7 @@
cmpop : TEq | TGt | TLt | TGe | TLe | TNe ;
-addexpr : addexpr addop mulexpr
+addexpr : addexpr addop mulexpr
{$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
| mulexpr
;
@@ -416,24 +417,24 @@
;
postfixexpr
- : postfixexpr TDot TIdent
+ : postfixexpr TDot TIdent
{$$ = mkexpr($1->line, Omemb, $1, mkname($3->line, $3->str), NULL);}
- | postfixexpr TInc
+ | postfixexpr TInc
{$$ = mkexpr($1->line, Opostinc, $1, NULL);}
- | postfixexpr TDec
+ | postfixexpr TDec
{$$ = mkexpr($1->line, Opostdec, $1, NULL);}
- | postfixexpr TOsqbrac expr TCsqbrac
+ | postfixexpr TOsqbrac expr TCsqbrac
{$$ = mkexpr($1->line, Oidx, $1, $3);}
- | postfixexpr TOsqbrac expr TComma expr TCsqbrac
+ | postfixexpr TOsqbrac expr TComma expr TCsqbrac
{$$ = mkexpr($1->line, Oslice, $1, $3, $5, NULL);}
- | postfixexpr TOparen arglist TCparen
+ | postfixexpr TOparen arglist TCparen
{$$ = mkcall($1->line, $1, $3.nl, $3.nn);}
| atomicexpr
;
-arglist : asnexpr
+arglist : asnexpr
{$$.nl = NULL; $$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
- | arglist TComma asnexpr
+ | arglist TComma asnexpr
{nlappend(&$$.nl, &$$.nn, $3);}
| /* empty */
{$$.nl = NULL; $$.nn = 0;}
@@ -440,10 +441,10 @@
;
atomicexpr
- : TIdent
+ : TIdent
{$$ = mkexpr($1->line, Ovar, mkname($1->line, $1->str), NULL);}
| literal
- | TOparen expr TCparen
+ | TOparen expr TCparen
{$$ = $2;}
| TSizeof atomicexpr
{$$ = mkexpr($1->line, Osize, $2, NULL);}
@@ -458,17 +459,19 @@
| TBoollit {$$ = mkbool($1->line, !strcmp($1->str, "true"));}
;
-funclit : TObrace params TEndln blockbody TCbrace
+funclit : TObrace params TEndln blockbody TCbrace
{$$ = mkfunc($1->line, $2.nl, $2.nn, $4);}
;
params : declcore
{$$.nl = NULL; $$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
- | params TComma declcore
+ | params TComma declcore
{nlappend(&$$.nl, &$$.nn, $3);}
+ | /* empty */
+ {$$.nl = NULL; $$.nn = 0;}
;
-arraylit : TOsqbrac arraybody TCsqbrac
+arraylit : TOsqbrac arraybody TCsqbrac
{$$ = NULL; die("Unimpl arraylit");}
;
@@ -486,7 +489,7 @@
| TEndln {$$ = NULL;}
;
-forstmt : TFor optexprln optexprln optexprln block
+forstmt : TFor optexprln optexprln optexprln block
{$$ = mkloop($1->line, $2, $3, $4, $5);}
| TFor decl optexprln optexprln block
{$$ = mkloop($1->line, $2, $3, $4, $5);}
@@ -517,16 +520,16 @@
;
blockbody
- : stmt
+ : stmt
{
- $$ = mkblock(line, NULL);
+ $$ = mkblock(line, NULL);
nlappend(&$$->block.stmts, &$$->block.nstmts, $1);
}
- | blockbody stmt
+ | blockbody stmt
{nlappend(&$$->block.stmts, &$$->block.nstmts, $2);}
;
-label : TColon TIdent
+label : TColon TIdent
{$$ = mklabel($1->line, $1->str);}
;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -8,6 +8,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <assert.h>
#include "parse.h"
@@ -16,25 +17,169 @@
int i;
/* uses only allowed at top level. Do we want to keep it this way? */
for (i = 0; i < n->file.nuses; i++)
- readuse(n->file.uses[i], n->file.globls);
+ fprintf(stderr, "INTERNAL: implement use loading\n");
+ /* readuse(n->file.uses[i], n->file.globls); */
}
-static void inferdecl(Node *n)
+/* a => b */
+static void settype(Node *n, Type *t)
{
}
-static void inferexpr(Node *n)
+static Op exprop(Node *e)
{
+ assert(e->type == Nexpr);
+ return e->expr.op;
}
-static void inferlit(Node *n)
+static Type *type(Node *n)
{
+ die("Unimplemented type()");
+ return NULL;
}
+static Type *littype(Node *lit)
+{
+ return NULL;
+}
+
+static Type *unify(Type *a, Type *b)
+{
+ die("Unimplemented unify");
+ return NULL;
+}
+
+static Type *tyfind(Type *t)
+{
+ die("Unimplemented tyfind");
+ return t;
+}
+
+static void unifycall(Node *n)
+{
+}
+
+static void inferexpr(Node *n, Type *ret)
+{
+ Node **args;
+ int nargs;
+ Type *t;
+ int i;
+
+ assert(n->type == Nexpr);
+ args = n->expr.args;
+ nargs = n->expr.nargs;
+ switch (exprop(n)) {
+ /* all operands are same type */
+ case Oadd: /* @a + @a -> @a */
+ case Osub: /* @a - @a -> @a */
+ case Omul: /* @a * @a -> @a */
+ case Odiv: /* @a / @a -> @a */
+ case Omod: /* @a % @a -> @a */
+ case Oneg: /* -@a -> @a */
+ case Obor: /* @a | @a -> @a */
+ case Oband: /* @a & @a -> @a */
+ case Obxor: /* @a ^ @a -> @a */
+ case Obsl: /* @a << @a -> @a */
+ case Obsr: /* @a >> @a -> @a */
+ case Obnot: /* ~@a -> @a */
+ case Opreinc: /* ++@a -> @a */
+ case Opredec: /* --@a -> @a */
+ case Opostinc: /* @a++ -> @a */
+ case Opostdec: /* @a-- -> @a */
+ case Oasn: /* @a = @a -> @a */
+ case Oaddeq: /* @a += @a -> @a */
+ case Osubeq: /* @a -= @a -> @a */
+ case Omuleq: /* @a *= @a -> @a */
+ case Odiveq: /* @a /= @a -> @a */
+ case Omodeq: /* @a %= @a -> @a */
+ case Oboreq: /* @a |= @a -> @a */
+ case Obandeq: /* @a &= @a -> @a */
+ case Obxoreq: /* @a ^= @a -> @a */
+ case Obsleq: /* @a <<= @a -> @a */
+ case Obsreq: /* @a >>= @a -> @a */
+ t = type(args[0]);
+ for (i = 1; i < nargs; i++)
+ t = unify(t, type(args[i]));
+ settype(n, tyfind(t));
+ break;
+
+ /* operands same type, returning bool */
+ case Olor: /* @a || @b -> bool */
+ case Oland: /* @a && @b -> bool */
+ case Olnot: /* !@a -> bool */
+ case Oeq: /* @a == @a -> bool */
+ case One: /* @a != @a -> bool */
+ case Ogt: /* @a > @a -> bool */
+ case Oge: /* @a >= @a -> bool */
+ case Olt: /* @a < @a -> bool */
+ case Ole: /* @a <= @b -> bool */
+ t = type(args[0]);
+ for (i = 1; i < nargs; i++)
+ unify(t, type(args[i]));
+ settype(n, mkty(-1, Tybool));
+ break;
+
+ /* reach into a type and pull out subtypes */
+ case Oaddr: /* &@a -> @a* */
+ settype(n, mktyptr(n->line, type(args[0])));
+ break;
+ case Oderef: /* *@a* -> @a */
+ t = unify(type(args[0]), mktyptr(n->line, mktyvar(n->line)));
+ settype(n, t);
+ break;
+ case Oidx: /* @a[@b::tcint] -> @a */
+ die("inference of indexes not done yet");
+ break;
+ case Oslice: /* @a[@b::tcint,@b::tcint] -> @a[,] */
+ die("inference of slices not done yet");
+ break;
+
+ /* special cases */
+ case Omemb: /* @a.Ident -> @b, verify type(@a.Ident)==@b later */
+ die("members not done yet");
+ break;
+ case Osize: /* sizeof @a -> size */
+ die("inference of sizes not done yet");
+ break;
+ case Ocall: /* (@a, @b, @c, ... -> @r)(@a,@b,@c, ... -> @r) -> @r */
+ unifycall(n);
+ break;
+ case Ocast: /* cast(@a, @b) -> @b */
+ die("casts not implemented");
+ break;
+ case Oret: /* -> @a -> void */
+ settype(n, mkty(-1, Tyvoid));
+ break;
+ case Ogoto: /* goto void* -> void */
+ settype(n, mkty(-1, Tyvoid));
+ break;
+ case Ovar: /* a:@a -> @a */
+ settype(n, decltype(n));
+ break;
+ case Olit: /* <lit>:@a::tyclass -> @a */
+ settype(n, littype(n));
+ break;
+ case Olbl: /* :lbl -> void* */
+ settype(n, mktyptr(n->line, mkty(-1, Tyvoid)));
+ case Obad: /* error! */
+ break;
+ }
+}
+
static void inferfunc(Node *n)
{
}
+static void inferdecl(Node *n)
+{
+ Type *t;
+
+ t = decltype(n);
+ settype(n, t);
+ inferexpr(n->decl.init, NULL);
+}
+
static void infernode(Node *n)
{
int i;
@@ -41,8 +186,6 @@
switch (n->type) {
case Nfile:
- for (i = 0; i < n->file.nuses; i++)
- infernode(n->file.uses[i]);
for (i = 0; i < n->file.nstmts; i++)
infernode(n->file.stmts[i]);
break;
@@ -65,13 +208,13 @@
infernode(n->loopstmt.body);
break;
case Nexpr:
- inferexpr(n);
- case Nlit:
- inferlit(n);
+ inferexpr(n, NULL);
case Nfunc:
inferfunc(n);
case Nname:
+ case Nlit:
case Nuse:
+ case Nlbl:
break;
}
}
@@ -91,6 +234,7 @@
void infer(Node *file)
{
assert(file->type == Nfile);
+
loaduses(file);
infernode(file);
infercompn(file);
--- a/parse/main.c
+++ b/parse/main.c
@@ -50,6 +50,8 @@
file->file.globls = mkstab(NULL);
yyparse();
dump(file, stdout);
+ infer(file);
+ dump(file, stdout);
gen();
}
--- a/parse/node.c
+++ b/parse/node.c
@@ -195,6 +195,7 @@
Type *decltype(Node *n)
{
+ assert(n->type == Ndecl);
return n->decl.sym->type;
}
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -17,7 +17,6 @@
O(Opostdec)
O(Oaddr)
O(Oderef)
-O(Onegl)
O(Olor)
O(Oland)
O(Olnot)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -99,7 +99,7 @@
struct Node {
int line;
- int type;
+ Ntype type;
union {
struct {
char *name;
@@ -211,8 +211,8 @@
/* type creation */
void tyinit(); /* sets up built in types */
-Type *optype(Op o);
+Type *mkty(int line, Ty ty);
Type *mktyvar(int line);
Type *mktyparam(int line, char *name);
Type *mktynamed(int line, Node *name);
@@ -223,9 +223,9 @@
Type *mktystruct(int line, Node **decls, size_t ndecls);
Type *mktyunion(int line, Node **decls, size_t ndecls);
Type *mktyenum(int line, Node **decls, size_t ndecls);
-
Cstr *mkcstr(int line, char *name, Node **reqmemb, size_t nreqmemb, Node **reqdecl, size_t nreqdecl);
+/* type manipulation */
int hascstr(Type *t, Cstr *c);
char *tyfmt(char *buf, size_t len, Type *t);
char *tystr(Type *t);
@@ -232,7 +232,7 @@
void tlappend(Type ***tl, int *len, Type *t);
-/* tree creation */
+/* node creation */
Node *mkfile(char *name);
Node *mkuse(int line, char *use, int islocal);
Node *mkexpr(int line, Op op, ...); /* NULL terminated */
@@ -253,6 +253,7 @@
Node *mkdecl(int line, Sym *sym);
Node *mklabel(int line, char *lbl);
+/* node util functions */
Type *decltype(Node *n);
void addstmt(Node *file, Node *stmt);
void setns(Node *n, char *name);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -452,7 +452,6 @@
if (!t || t->type == TError)
fatal(line, "Unable to parse token starting with %c", c);
-
return t;
}
@@ -470,7 +469,7 @@
nread = 0;
fbuf = malloc(4096);
while (1) {
- n = read(fd, fbuf, 4096);
+ n = read(fd, fbuf + nread, 4096);
if (n < 0)
fatal(errno, "Error reading file %s", file);
if (n == 0)
--- a/parse/type.c
+++ b/parse/type.c
@@ -40,7 +40,7 @@
int ncstr;
static int nexttid = 0;
-static Type *mktype(Ty ty)
+Type *mkty(int line, Ty ty)
{
Type *t;
@@ -54,7 +54,7 @@
{
Type *t;
- t = mktype(Tyvar);
+ t = mkty(line, Tyvar);
return t;
}
@@ -62,7 +62,7 @@
{
Type *t;
- t = mktype(Tyvar);
+ t = mkty(line, Tyvar);
t->pname = strdup(name);
return t;
}
@@ -76,10 +76,10 @@
if (name->name.nparts == 1)
for (i = 0; typenames[i].name; i++)
if (!strcmp(typenames[i].name, name->name.parts[0]))
- return mktype(typenames[i].ty);
+ return mkty(line, typenames[i].ty);
/* if not, resolve it in the type inference stage */
- t = mktype(Tyname);
+ t = mkty(line, Tyname);
t->name = name;
return t;
}
@@ -88,7 +88,7 @@
{
Type *t;
- t = mktype(Tyarray);
+ t = mkty(line, Tyarray);
t->abase = base;
t->asize = sz;
@@ -99,7 +99,7 @@
{
Type *t;
- t = mktype(Tyslice);
+ t = mkty(line, Tyslice);
t->sbase = base;
return t;
}
@@ -108,7 +108,7 @@
{
Type *t;
- t = mktype(Typtr);
+ t = mkty(line, Typtr);
t->pbase = base;
return t;
}
@@ -118,7 +118,7 @@
Type *t;
int i;
- t = mktype(Tyfunc);
+ t = mkty(line, Tyfunc);
t->nsub = nargs + 1;
t->fnsub = xalloc((1 + nargs)*sizeof(Type));
t->fnsub[0] = ret;
@@ -131,7 +131,7 @@
{
Type *t;
- t = mktype(Tystruct);
+ t = mkty(line, Tystruct);
t->nsub = ndecls;
t->sdecls = memdup(decls, ndecls*sizeof(Node *));
return t;
@@ -141,7 +141,7 @@
{
Type *t;
- t = mktype(Tyunion);
+ t = mkty(line, Tyunion);
t->udecls = decls;
return t;
}
@@ -150,7 +150,7 @@
{
Type *t;
- t = mktype(Tyenum);
+ t = mkty(line, Tyenum);
t->edecls = decls;
return t;
}