ref: c2086cda32afb3960938a81df6f5a6a209bfaf33
parent: 893a6828d04ad197b2eb773d19bff69ba63af14e
author: Jacob Moody <moody@posixcafe.org>
date: Fri Apr 26 01:22:57 EDT 2024
function calls, refactor tabing in output, start of c output
--- a/dat.h
+++ b/dat.h
@@ -53,6 +53,7 @@
Nsym,
Ndcl,
Nfunc,
+ Ncall,
};
enum {
@@ -135,10 +136,16 @@
Typ *type;
Nod *body;
} func;
+ struct {
+ char *name;
+ Nlst args;
+ } call;
};
};
#pragma varargck type "N" Nod*
+#pragma varargck type "O" Nod*
#pragma varargck type "L" Nlst
+#pragma varargck type "M" Nlst
extern int lexline;
extern char* lexfile;
--- a/fmt.c
+++ b/fmt.c
@@ -34,12 +34,14 @@
nodfmt(Fmt *f)
{
Nod *n;
- int nt;
+ int nt, e;
nt = f->prec;
n = va_arg(f->args, Nod*);
if(n == nil)
return 0;
+ if(nt && n->t != Nblk)
+ fmtprint(f, "%.*s", nt, tabs);
switch(n->t){
default:
return fmtprint(f, "unknown nod type %d", n->t);
@@ -61,11 +63,16 @@
else
return fmtprint(f, "EXPR(%N %s %N)", n->expr.lhs, expoptab[n->expr.op], n->expr.rhs);
case Nblk:
- return fmtprint(f, "{\n%.*L\n%.*s}", nt+1, n->blk.body, nt, tabs);
+ e = nt - 1;
+ if(e < 0)
+ e = 0;
+ return fmtprint(f, "{\n%.*L\n%.*s}", nt, n->blk.body, e, tabs);
case Ndcl:
return fmtprint(f, "DCL %s : %s", n->dcl.name, n->dcl.type->name);
case Nfunc:
- return fmtprint(f, "FN %s (\n%.*L\n) → %N", n->func.name, nt+1, n->func.args, n->func.body);
+ return fmtprint(f, "FN %s (\n%.*L\n) → %.*N", n->func.name, nt+1, n->func.args, nt+1, n->func.body);
+ case Ncall:
+ return fmtprint(f, "CALL %s (\n%.*L\n%.*s)", n->call.name, nt+1, n->call.args, nt, tabs);
}
}
@@ -78,7 +85,7 @@
nt = f->prec;
n = va_arg(f->args, Nlst);
for(i = 0; i < n.nv; i++){
- fmtprint(f, "%.*s%N", nt, tabs, n.v[i]);
+ fmtprint(f, "%.*N", nt, n.v[i]);
if(i != n.nv-1)
fmtprint(f, "\n");
}
@@ -85,6 +92,66 @@
return 0;
}
+int
+cnodfmt(Fmt *f)
+{
+ Nod *n;
+ int nt, e;
+
+ nt = f->prec;
+ n = va_arg(f->args, Nod*);
+ if(n == nil)
+ return 0;
+ if(nt && n->t != Nblk)
+ fmtprint(f, "%.*s", nt, tabs);
+ switch(n->t){
+ default:
+ return fmtprint(f, "unknown nod type %d", n->t);
+ case Nfor:
+ return fmtprint(f, "for(%O; %O; %O) %.*O", n->nfor.init, n->nfor.cond, n->nfor.step, nt+1, n->nfor.body);
+ case Nif:
+ if(n->nif.f)
+ return fmtprint(f, "if(%O)%.*Oelse%.*O", n->nif.cond, nt+1, n->nif.t, nt+1, n->nif.f);
+ return fmtprint(f, "if(%O)%.*O", n->nif.cond, nt+1, n->nif.t);
+ case Nsym:
+ return fmtprint(f, "%s", n->sym.sym);
+ case Nlit:
+ return fmtprint(f, "%lld", n->lit.val);
+ case Nexpr:
+ if(n->expr.op == Olit || n->expr.op == Ovar)
+ return fmtprint(f, "%O", n->expr.lhs);
+ else
+ return fmtprint(f, "%O %s %O", n->expr.lhs, expoptab[n->expr.op], n->expr.rhs);
+ case Nblk:
+ e = nt - 1;
+ if(e < 0)
+ e = 0;
+ return fmtprint(f, "{\n%.*M\n%.*s}", nt, n->blk.body, e, tabs);
+ case Ndcl:
+ return fmtprint(f, "%s %s", n->dcl.type->name, n->dcl.name);
+ case Nfunc:
+ return fmtprint(f, "void\n%s(%M)\n%.*O", n->func.name, n->func.args, nt+1, n->func.body);
+ case Ncall:
+ return fmtprint(f, "%s(%M)", n->call.name, n->call.args);
+ }
+}
+
+int
+cnlstfmt(Fmt *f)
+{
+ int i, nt;
+ Nlst n;
+
+ nt = f->prec;
+ n = va_arg(f->args, Nlst);
+ for(i = 0; i < n.nv; i++){
+ fmtprint(f, "%.*O", nt, n.v[i]);
+ if(i != n.nv-1)
+ fmtprint(f, ", ");
+ }
+ return 0;
+}
+
void
astfmtinstall(void)
{
@@ -92,4 +159,6 @@
tabs[nelem(tabs)-1] = '\0';
fmtinstall('N', nodfmt);
fmtinstall('L', nlstfmt);
+ fmtinstall('O', cnodfmt);
+ fmtinstall('M', cnlstfmt);
}
--- a/fns.h
+++ b/fns.h
@@ -5,6 +5,7 @@
Nod* mkfor(Nod*, Nod*, Nod*, Nod*);
Nod* mkif(Nod*, Nod*, Nod*);
Nod* mkfunc(char*, Nlst, Typ*, Nlst);
+Nod* mkcall(char*, Nlst);
Nod* mklit(vlong);
Nod* mksym(char*);
Nod* mkdecl(char*, Typ*, Nod*);
--- a/n.y
+++ b/n.y
@@ -40,10 +40,10 @@
%token <sval> NAME;
%token <ival> NUM
-%type<nod> arg expr logexpr shifexpr addexpr mulexpr
+%type<nod> defarg expr logexpr shifexpr addexpr mulexpr
%type<nod> unary prefexpr sufexpr compexpr top stmt
%type<nod> decl
-%type<lst> args prog stmts
+%type<lst> defargs prog stmts args
%type<typ> type return
%%
@@ -56,7 +56,7 @@
| top { $$ = append(ZL, $1); }
top
-: FUNC NAME '(' args ')' return '{' stmts '}'
+: FUNC NAME '(' defargs ')' return '{' stmts '}'
{ $$ = mkfunc($2, $4, $6, $8); }
| MOD NAME ';' { $$ = nil; modname = $2; }
| USE NAME ';' { $$ = nil; loaduse($2); }
@@ -85,6 +85,7 @@
: NUM { $$ = mkexpr(Olit, mklit($1), nil); }
| NAME { $$ = mkexpr(Ovar, mksym($1), nil); }
| '(' expr ')' { $$ = $2; }
+| NAME '(' args ')' { $$ = mkcall($1, $3); }
sufexpr
: sufexpr DEC { $$ = mkexpr(Odec, $1, nil); }
@@ -152,13 +153,18 @@
{ $$ = mkif($3, $5, $7); }
| IF '(' expr ')' stmt { $$ = mkif($3, $5, nil); }
-arg
+defarg
: NAME ':' type { $$ = mkdecl($1, $3, nil); }
+defargs
+: { $$ = ZL; }
+| defarg { $$ = append(ZL, $1); }
+| defargs ',' defarg { $$ = append($1, $3); }
+
args
: { $$ = ZL; }
-| arg { $$ = append(ZL, $1); }
-| args ',' arg { $$ = append($1, $3); }
+| expr { $$ = append(ZL, $1); }
+| args ',' expr { $$ = append($1, $3); }
%%
@@ -336,7 +342,13 @@
void
main(int argc, char **argv)
{
+ int ast;
+
+ ast = 0;
ARGBEGIN{
+ case 'a':
+ ast++;
+ break;
case 'd':
debug++;
break;
@@ -352,6 +364,9 @@
while(!goteof)
yyparse();
Bterm(bin);
- print("%L\n", toplevel);
+ if(ast)
+ print("%L\n", toplevel);
+ else
+ print("%M\n", toplevel);
exits(nil);
}
--- a/nod.c
+++ b/nod.c
@@ -104,6 +104,17 @@
}
Nod*
+mkcall(char *s, Nlst args)
+{
+ Nod *n;
+
+ n = new(Ncall);
+ n->call.name = s;
+ n->call.args = args;
+ return n;
+}
+
+Nod*
mklit(vlong v)
{
Nod *n;