shithub: mc

Download patch

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