shithub: hammer

Download patch

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