ref: 893a6828d04ad197b2eb773d19bff69ba63af14e
parent: 0c8cf4098baef78d7c3da9d3c029cdce5bd8ebb2
author: Jacob Moody <moody@posixcafe.org>
date: Wed Nov 22 01:14:33 EST 2023
ast dumping
--- a/dat.h
+++ b/dat.h
@@ -27,10 +27,20 @@
};
enum {
+ Tunkn,
Tvoid,
+ Tchar,
+ Tuchar,
+ Tshort,
+ Tushort,
+ Tlong,
+ Tulong,
+ Tvlong,
+ Tuvlong,
Tarray,
Tslice,
Tfunc,
+ Tstruct,
};
enum {
@@ -120,6 +130,7 @@
Nlst body;
} blk;
struct {
+ char *name;
Nlst args;
Typ *type;
Nod *body;
@@ -126,6 +137,8 @@
} func;
};
};
+#pragma varargck type "N" Nod*
+#pragma varargck type "L" Nlst
extern int lexline;
extern char* lexfile;
--- /dev/null
+++ b/fmt.c
@@ -1,0 +1,95 @@
+#include <u.h>
+#include <libc.h>
+
+#include "dat.h"
+#include "fns.h"
+
+static char *expoptab[] = {
+ [Olit] "",
+ [Ovar] "",
+ [Oasn] "=",
+ [Oadd] "+",
+ [Osub] "-",
+ [Omul] "*",
+ [Odiv] "/",
+ [Omod] "%",
+ [Oshl] "<<",
+ [Oshr] ">>",
+ [Olor] "||",
+ [Oland] "&&",
+ [Ogt] ">",
+ [Olt] "<",
+ [Oge] ">=",
+ [Ole] "<=",
+ [Oeq] "==",
+ [One] "!=",
+ [Oinc] "++",
+ [Odec] "--",
+ [Orcv] "←"
+};
+
+static char tabs[128];
+
+int
+nodfmt(Fmt *f)
+{
+ Nod *n;
+ int nt;
+
+ nt = f->prec;
+ n = va_arg(f->args, Nod*);
+ if(n == nil)
+ return 0;
+ switch(n->t){
+ default:
+ return fmtprint(f, "unknown nod type %d", n->t);
+ case Niter:
+ return fmtprint(f, "FOR ( %N ← %N ) %.*N", n->iter.idx, n->iter.arg, nt+1, n->iter.body);
+ case Nfor:
+ return fmtprint(f, "FOR ( %N ; %N ; %N ) %.*N", n->nfor.init, n->nfor.cond, n->nfor.step, nt+1, n->nfor.body);
+ case Nif:
+ if(n->nif.f)
+ return fmtprint(f, "IF ( %N ) %.*N ELSE %.*N", n->nif.cond, nt+1, n->nif.t, nt+1, n->nif.f);
+ return fmtprint(f, "IF ( %N ) %.*N", 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, "%N", n->expr.lhs);
+ 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);
+ 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);
+ }
+}
+
+int
+nlstfmt(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, "%.*s%N", nt, tabs, n.v[i]);
+ if(i != n.nv-1)
+ fmtprint(f, "\n");
+ }
+ return 0;
+}
+
+void
+astfmtinstall(void)
+{
+ memset(tabs, '\t', nelem(tabs)-1);
+ tabs[nelem(tabs)-1] = '\0';
+ fmtinstall('N', nodfmt);
+ fmtinstall('L', nlstfmt);
+}
--- a/fns.h
+++ b/fns.h
@@ -9,7 +9,9 @@
Nod* mksym(char*);
Nod* mkdecl(char*, Typ*, Nod*);
Nod* mkblk(Nlst);
-Typ* mktype(int);
+Typ* mktype(char*, int);
Typ* mktyarray(Typ*, Nod*);
Typ* mktyslice(Typ*);
-Typ* mktyfunc(Typ**, int, Typ*);
\ No newline at end of file
+Typ* mktyfunc(Typ**, int, Typ*);
+int nodfmt(Fmt*);
+void astfmtinstall(void);
--- a/mkfile
+++ b/mkfile
@@ -3,8 +3,9 @@
BIN=$home/bin/$objtype
TARG=nl
OFILES=\
- y.tab.$O\
+ fmt.$O\
nod.$O\
+ y.tab.$O\
HFILES=\
dat.h\
--- a/n.y
+++ b/n.y
@@ -15,6 +15,8 @@
int yyparse(void);
void yyerror(char*);
+Nlst toplevel;
+
void
loaduse(char*)
{
@@ -32,7 +34,7 @@
Nlst lst;
}
-%token FUNC DEF IF FOR MOD USE OR AND NOTEQ EQ SHIFTL SHIFTR STRUCT ELSE ARROWR ARROWL GTEQ LTEQ
+%token FUNC DEF IF FOR MOD USE OR AND NOTEQ EQ SHIFTL SHIFTR STRUCT ELSE ARROWR ARROWL GTEQ LTEQ INC DEC
%token TYPE NAME NUM
%token <sval> NAME;
@@ -46,6 +48,9 @@
%%
+file
+: prog { toplevel = $1; }
+
prog
: prog top { $$ = append($1, $2); }
| top { $$ = append(ZL, $1); }
@@ -62,12 +67,12 @@
| sdecls NAME ':' type ';'
def
-: DEF NAME NAME { }
+: DEF NAME type { }
| DEF NAME STRUCT '{' sdecls '}'
{ }
type
-: NAME { $$ = nil; }
+: NAME { $$ = mktype($1, Tunkn); }
| type '[' ']' { $$ = mktyslice($1); }
| type '[' NUM ']' { $$ = mktyarray($1, mklit($3)); }
| type '!' { $$ = $1; $$->linear = 1; }
@@ -74,7 +79,7 @@
return
: ARROWR type { $$ = $2; }
-| { $$ = mktype(Tvoid); }
+| { $$ = mktype("void", Tvoid); }
unary
: NUM { $$ = mkexpr(Olit, mklit($1), nil); }
@@ -82,8 +87,8 @@
| '(' expr ')' { $$ = $2; }
sufexpr
-: sufexpr '--' { $$ = mkexpr(Odec, $1, nil); }
-| sufexpr '++' { $$ = mkexpr(Oinc, $1, nil); }
+: sufexpr DEC { $$ = mkexpr(Odec, $1, nil); }
+| sufexpr INC { $$ = mkexpr(Oinc, $1, nil); }
| unary { $$ = $1; }
prefexpr
@@ -138,7 +143,7 @@
stmt
: expr ';' { $$ = $1; }
| '{' stmts '}' { $$ = mkblk($2); }
-| decl ';' { $$ = $1->dcl.init; }
+| decl ';' { $$ = $1; }
| FOR '(' unary ARROWL expr ')' stmt
{ $$ = mkiter($3, $5, $7); }
| FOR '(' expr ';' expr ';' expr ')' stmt
@@ -157,32 +162,6 @@
%%
-struct {
- char *s;
- int type;
-} keytab[] = {
- "fn", FUNC,
- "type", DEF,
- "if", IF,
- "for", FOR,
- "mod", MOD,
- "use", USE,
- "&&", AND,
- "||", OR,
- "!=", NOTEQ,
- "==", EQ,
- "<=", LTEQ,
- ">=", GTEQ,
- "<<", SHIFTR,
- ">>", SHIFTL,
- "struct", STRUCT,
- "else", ELSE,
- "->", ARROWR,
- "→", ARROWR,
- "<-", ARROWL,
- "←", ARROWL,
-};
-
Biobuf *bin;
int
@@ -234,12 +213,45 @@
exits(s);
}
+struct {
+ int c;
+ struct {
+ int c;
+ int t;
+ } next[3];
+} spectab[] = {
+ '-', { '>', ARROWR, '-', DEC },
+ '=', { '=', EQ },
+ '>', { '>', SHIFTR, '=', GTEQ },
+ '<', { '-', ARROWL, '<', SHIFTL, '=', LTEQ },
+ '!', { '=', NOTEQ },
+ '&', { '&', AND },
+ '|', { '|', OR },
+ '+', { '+', INC },
+};
+
+struct {
+ char *s;
+ int type;
+} keytab[] = {
+ "fn", FUNC,
+ "type", DEF,
+ "if", IF,
+ "for", FOR,
+ "mod", MOD,
+ "use", USE,
+ "struct", STRUCT,
+ "else", ELSE,
+ "→", ARROWR,
+ "←", ARROWL,
+};
+
int
yylex2(void)
{
static char buf[200];
- int c;
- int i;
+ int c, c2;
+ int i, j;
Loop:
c = getch();
@@ -265,18 +277,17 @@
goto Loop;
goto More;
}
-
- switch(c){
- case ';': case '=':
- case '{': case '}':
- case '[': case ']':
- case '(': case ')':
- case '+': case '-':
- case '*': case '/':
- case '%': case ':':
- case '>': case '<':
- case ',': case '.':
+ if(utfrune("\"';{}[]()*/%:,.", c) != nil)
return c;
+ for(i = 0; i < nelem(spectab); i++){
+ if(c != spectab[i].c)
+ continue;
+ c2 = getch();
+ for(j = 0; j < 3; j++)
+ if(c2 == spectab[i].next[j].c)
+ return spectab[i].next[j].t;
+ ungetc();
+ return c;
}
ungetc();
wordlex(buf, sizeof buf);
@@ -335,10 +346,12 @@
}ARGEND;
if(argc > 0)
usage();
+ astfmtinstall();
bin = Bfdopen(0, OREAD);
goteof = 0;
while(!goteof)
yyparse();
Bterm(bin);
+ print("%L\n", toplevel);
exits(nil);
}
--- a/nod.c
+++ b/nod.c
@@ -85,7 +85,7 @@
}
Nod*
-mkfunc(char*, Nlst args, Typ *ret, Nlst body)
+mkfunc(char *s, Nlst args, Typ *ret, Nlst body)
{
Nod *n;
Typ **tv;
@@ -99,6 +99,7 @@
n->func.args = args;
n->func.type = mktyfunc(tv, args.nv, ret);
n->func.body = mkblk(body);
+ n->func.name = s;
return n;
}
@@ -117,7 +118,7 @@
{
Nod *n;
- n = new(Nlit);
+ n = new(Nsym);
n->sym.sym = s;
return n;
@@ -140,14 +141,13 @@
{
Nod *n;
- n = new(Ndcl);
+ n = new(Nblk);
n->blk.body = nl;
return n;
}
-
Typ*
-mktype(int tt)
+mktype(char *s, int tt)
{
Typ *t;
@@ -154,6 +154,7 @@
if((t = mallocz(sizeof(Typ), 1)) == nil)
abort();
t->t = tt;
+ t->name = s;
return t;
}