shithub: mc

Download patch

ref: e773fcec6b88e367ac70c2e528d0a52ee0ddf85a
parent: 45c4886b0fa21533658807dba33a030b37337c8d
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Nov 8 18:58:47 EST 2011

Fix up parsing func lits

--- a/parse/dump.c
+++ b/parse/dump.c
@@ -18,6 +18,20 @@
         fprintf(fd, " ");
 }
 
+static void dumpsym(Sym *s, FILE *fd, int depth)
+{
+    int i;
+
+    indent(fd, depth);
+    fprintf(fd, "Sym ");
+    for (i = 0; i < s->name->name.nparts; i++) {
+        fprintf(fd, "%s", s->name->name.parts[i]);
+        if (i != s->name->name.nparts - 1)
+            fprintf(fd, ".");
+    }
+    fprintf(fd, " : TYPE\n");
+}
+
 static void dumpnode(Node *n, FILE *fd, int depth)
 {
     int i;
@@ -24,11 +38,20 @@
 
 
     indent(fd, depth);
+    if (!n) {
+        fprintf(fd, "Nil\n");
+        return;
+    }
     fprintf(fd, "%s", nodestr(n->type));
     switch(n->type) {
         case Nfile:
             fprintf(fd, "(name = %s)\n", n->file.name);
             break;
+        case Ndecl:
+            fprintf(fd, "\n");
+            dumpsym(n->decl.sym, fd, depth + 1);
+            dumpnode(n->decl.init, fd, depth + 1);
+            break;
         case Nblock:
             for (i = 0; i < n->block.nstmts; i++)
                 dumpnode(n->block.stmts[i], fd, depth+1);
@@ -53,19 +76,29 @@
                 dumpnode(n->expr.args[i], fd, depth+1);
             break;
         case Nlit:
-            indent(fd, depth);
             switch (n->lit.littype) {
-                case Lchr:      fprintf(fd, "Lchr %c\n", n->lit.chrval); break;
-                case Lbool:     fprintf(fd, "Lbool %s\n", n->lit.boolval ? "true" : "false"); break;
-                case Lint:      fprintf(fd, "Lint %ld\n", n->lit.intval); break;
-                case Lflt:      fprintf(fd, "Lflt %lf\n", n->lit.fltval); break;
-                /*
-                case Lfunc:     fprintf("Lfunc %s\n", n->lit.chrval); break;
-                case Larray:    fprintf("Larray %c\n", n->lit.chrval); break;
-                */
+                case Lchr:      fprintf(fd, " Lchr %c\n", n->lit.chrval); break;
+                case Lbool:     fprintf(fd, " Lbool %s\n", n->lit.boolval ? "true" : "false"); break;
+                case Lint:      fprintf(fd, " Lint %ld\n", n->lit.intval); break;
+                case Lflt:      fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
+                case Lfunc:
+                    fprintf(fd, " Lfunc\n");
+                    dumpnode(n->lit.fnval, fd, depth+1);
+                    break;
+                case Larray:
+                    fprintf(fd, " Larray\n");
+                    dumpnode(n->lit.arrval, fd, depth+1);
+                    break;
                 default: die("Bad literal type"); break;
             }
             break;
+        case Nfunc:
+            fprintf(fd, " (args =\n");
+            for (i = 0; i < n->func.nargs; i++)
+                dumpnode(n->func.args[i], fd, depth+1);
+            indent(fd, depth);
+            fprintf(fd, ")\n");
+            dumpnode(n->func.body, fd, depth+1);
         case Nname:
             fprintf(fd, "(");
             for (i = 0; i < n->name.nparts; i++) {
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -115,10 +115,11 @@
 
 %type <node> exprln retexpr expr atomicexpr literal asnexpr lorexpr landexpr borexpr
 %type <node> bandexpr cmpexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
-%type <node> funclit arraylit name
+%type <node> funclit arraylit name block blockbody stmt label
 %type <node> decl declvariants declbody declcore structelt enumelt unionelt
+%type <node> ifstmt falsebranch
 
-%type <nodelist> arglist argdefs structbody enumbody unionbody
+%type <nodelist> arglist argdefs structbody enumbody unionbody params
 
 %union {
     struct {
@@ -152,7 +153,7 @@
         | TEndln
         ;
 
-decl    : declvariants TEndln
+decl    : declvariants TEndln {dump($1, stdout);}
         ;
 
 use     : TUse TIdent TEndln
@@ -273,7 +274,7 @@
 exprln  : expr TEndln
         ;
 
-expr    : asnexpr{dump($1, stdout);}
+expr    : asnexpr
         ;
 
 asnexpr : lorexpr asnop asnexpr {$$ = mkexpr($1->line, binop($2->type), $1, $3, NULL);}
@@ -382,11 +383,11 @@
         | TBoollit      {$$ = mkbool($1->line, !strcmp($1->str, "true"));}
         ;
 
-funclit : TObrace params TEndln blockbody TCbrace {$$ = NULL; die("unimpl funclit");}
+funclit : TObrace params TEndln blockbody TCbrace {$$ = mkfunc($1->line, $2.nl, $2.nn, $4);}
         ;
 
-params  : declcore
-        | params TComma declcore
+params  : declcore {$$.nl = NULL; $$.nn = 0; nlappend(&$$.nl, &$$.nn, $1);}
+        | params TComma declcore {nlappend(&$$.nl, &$$.nn, $3);}
         ;
 
 arraylit : TOsqbrac arraybody TCsqbrac {$$ = NULL; die("Unimpl arraylit");}
@@ -402,12 +403,17 @@
         | ifstmt
         ;
 
-ifstmt  : TIf exprln blockbody elifblocks TElse block
-        | TIf exprln blockbody elifblocks TEndblk
-        | TIf exprln blockbody TElse block
-        | TIf exprln block
+ifstmt  : TIf exprln blockbody falsebranch {$$ = mkif($1->line, $2, $3, $4);}
         ;
 
+falsebranch
+        : elifblocks TEndblk {$$ = NULL;}
+        | elifblocks TElse  block {$$ = NULL;}
+        | TElse block {$$ = $2;}
+        | TEndblk {$$ = NULL;}
+        ;
+        
+
 elifblocks
         : TElif exprln blockbody
         | elifblocks TElif exprln blockbody
@@ -417,11 +423,11 @@
         ;
 
 blockbody
-        : stmt
-        | blockbody stmt
+        : stmt {$$ = mkblock(line, NULL); nlappend(&$$->block.stmts, &$$->block.nstmts, $1);}
+        | blockbody stmt {nlappend(&$$->block.stmts, &$$->block.nstmts, $2);}
         ;
 
-label   : TColon TIdent
+label   : TColon TIdent {$$ = mklabel($1->line, $1->str);}
         ;
 
 %%
--- a/parse/node.c
+++ b/parse/node.c
@@ -94,6 +94,40 @@
     return n;
 }
 
+Node *mkfunc(int line, Node **args, size_t nargs, Node *body)
+{
+    Node *n;
+    Node *f;
+
+    f = mknode(line, Nfunc);
+    f->func.args = args;
+    f->func.nargs = nargs;
+    f->func.body = body;
+
+    n = mknode(line, Nlit);
+    n->lit.littype = Lfunc;
+    n->lit.fnval = f;
+    return n;
+}
+
+Node *mkblock(int line, Stab *scope)
+{
+    Node *n;
+
+    n = mknode(line, Nblock);
+    n->block.scope = scope;
+    return n;
+}
+
+Node *mklabel(int line, char *lbl)
+{
+    Node *n;
+
+    n = mknode(line, Nlbl);
+    n->lbl.name = strdup(lbl);
+    return n;
+}
+
 Node *mkstr(int line, char *val)
 {
     Node *n;
--- a/parse/nodes.def
+++ b/parse/nodes.def
@@ -7,3 +7,5 @@
 N(Nlit)
 N(Nname)
 N(Ndecl)
+N(Nfunc)
+N(Nlbl)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -106,6 +106,8 @@
                 uint32_t chrval;
                 char    *strval;
                 int      boolval;
+                Node    *fnval;
+                Node    *arrval;
             };
         } lit;
 
@@ -129,10 +131,21 @@
         } block;
 
         struct {
+            char *name;
+        } lbl;
+
+        struct {
             Sym *sym;
             Node *init;
             int isconst;
         } decl;
+
+        struct {
+            Stab *scope;
+            Node **args;
+            size_t nargs;
+            Node *body;
+        } func;
     };
 };
 
@@ -183,6 +196,7 @@
 Node *mklit(int line, Littype lt, void *val);
 Node *mkif(int line, Node *cond, Node *iftrue, Node *iffalse);
 Node *mkloop(int line, Node *init, Node *cond, Node *incr, Node *body);
+Node *mkblock(int line, Stab *scope);
 
 Node *mkbool(int line, int val);
 Node *mkint(int line, uint64_t val);
@@ -189,10 +203,11 @@
 Node *mkchar(int line, uint32_t val);
 Node *mkstr(int line, char *s);
 Node *mkfloat(int line, double flt);
-Node *mkfunc(int line, Node **args, Node *body);
+Node *mkfunc(int line, Node **args, size_t nargs, Node *body);
 Node *mkarray(int line, Node **vals);
 Node *mkname(int line, char *name);
 Node *mkdecl(int line, Sym *sym);
+Node *mklabel(int line, char *lbl);
 
 
 void addstmt(Node *file, Node *stmt);