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