aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap/dump.c')
-rw-r--r--bootstrap/dump.c177
1 files changed, 102 insertions, 75 deletions
diff --git a/bootstrap/dump.c b/bootstrap/dump.c
index 0ea5c07..ced692d 100644
--- a/bootstrap/dump.c
+++ b/bootstrap/dump.c
@@ -1,47 +1,57 @@
#include "all.h"
#include <stdarg.h>
-static void pri(const char *fmt, ...);
-
static void
pritype(const struct type *ty) {
assert(ty);
if (ty->konst)
- pri("const ");
+ epri("const ");
switch (ty->t) {
case TYvoid:
- pri("void");
+ epri("void");
break;
case TYbool:
- pri("bool");
+ epri("bool");
break;
case TYint:
- pri("%c%z", ty->int_signed ? 'i' : 'u',
+ epri("%c%z", ty->int_signed ? 'i' : 'u',
8 * ty->size);
break;
case TYfloat:
- pri("f%z", 8 * ty->size);
+ epri("f%z", 8 * ty->size);
break;
case TYptr:
- pri("*%t", ty->child);
+ epri("*%t", ty->child);
break;
case TYarr:
assert(ty->length >= 0);
- pri("[%U]%t", ty->length, ty->child);
+ epri("[%U]%t", ty->length, ty->child);
break;
case TYslice:
- pri("[#]%t", ty->child);
+ epri("[#]%t", ty->child);
break;
case TYfn:
- pri("fn(");
+ epri("fn(");
for (int i = 0; i < ty->fn.params.n; ++i) {
- pri("_ %t", ty->fn.params.d[i]);
- pri(", ");
+ epri("_ %t", ty->fn.params.d[i]);
+ epri(", ");
}
if (ty->fn.variadic)
- pri("...");
- pri(") %t", ty->fn.retty);
- default:assert(0);
+ epri("...");
+ epri(") %t", ty->fn.retty);
+ break;
+ case TYenum:
+ epri("%s", ty->enu.name ? ty->enu.name : "(anonymous enum)");
+ break;
+ case TYstruct:
+ epri("%s", ty->agg.name ? ty->agg.name : "(anonymous struct)");
+ break;
+ case TYunion:
+ epri("%s", ty->agg.name ? ty->agg.name : "(anonymous union)");
+ break;
+ case TYeunion:
+ epri("%s", ty->agg.name ? ty->agg.name : "(anonymous tagged union)");
+ break;
}
}
@@ -50,14 +60,14 @@ static void dumpexpr(const struct expr *expr);
static void
pristring(const char *s, u64 n) {
extern int isprint(int);
- pri("\"");
+ epri("\"");
for (int i = 0; i < n; ++i) {
if (isprint(s[i]))
- pri("%c", s[i]);
+ epri("%c", s[i]);
else
fprintf(stderr, "\\%.3o", s[i]);
}
- pri("\"");
+ epri("\"");
}
@@ -148,13 +158,11 @@ pritoktree(struct toktree toks) {
void
-pri(const char *fmt, ...) {
- va_list ap;
+vepri(const char *fmt, va_list ap) {
unsigned ch;
const char *S;
int ws;
- va_start(ap, fmt);
for (char c; (c = *fmt++);) {
if (c != '%') {
fputc(c, stderr);
@@ -186,6 +194,10 @@ pri(const char *fmt, ...) {
case 's':
fprintf(stderr, "%s", va_arg(ap, const char *));
break;
+ case 'q':
+ S = va_arg(ap, const char *);
+ pristring(S, strlen(S));
+ break;
case 'w':
ws = va_arg(ap, int);
for (int i = 0; i < ws; ++i)
@@ -196,7 +208,15 @@ pri(const char *fmt, ...) {
pristring(S, va_arg(ap, u64));
break;
case 't':
+ epri("\x1b[1m");
pritype(va_arg(ap, const struct type *));
+ epri("\x1b[0m");
+ break;
+ case 'T':
+ fprintf(stderr, "%s", tok2str(va_arg(ap, struct tok)));
+ break;
+ case 'k':
+ fprintf(stderr, "%s", tokt2str(va_arg(ap, int)));
break;
case 'e':
dumpexpr(va_arg(ap, const struct expr *));
@@ -207,52 +227,59 @@ pri(const char *fmt, ...) {
break;
}
}
+}
+
+void
+epri(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vepri(fmt, ap);
va_end(ap);
}
static void dumpexpr(const struct expr *expr) {
switch (expr->t) {
case Eintlit:
- pri("%U_%t", expr->i, expr->ty);
+ epri("%U_%t", expr->i, expr->ty);
break;
case Eflolit:
- pri("%f%s", expr->f, expr->ty->size == 4 ? "f" : "");
+ epri("%f%s", expr->f, expr->ty->size == 4 ? "f" : "");
break;
case Estrlit:
- pri("%S", expr->strlit.d, expr->strlit.n);
+ epri("%S", expr->strlit.d, expr->strlit.n);
break;
case Eboolit:
- pri("#%c", expr->i ? 't' : 'f');
+ epri("#%c", expr->i ? 't' : 'f');
break;
case Enullit:
- pri("#null");
+ epri("#null");
break;
case Ename:
- pri("%s", expr->ref->name);
+ epri("%s", expr->ref->name);
break;
case Ebinop:
- pri("(%e %c %e)", expr->binop.lhs, expr->binop.op, expr->binop.rhs);
+ epri("(%e %c %e)", expr->binop.lhs, expr->binop.op, expr->binop.rhs);
break;
case Eprefix:
- pri("%c(%e)", expr->unop.op, expr->unop.child);
+ epri("%c(%e)", expr->unop.op, expr->unop.child);
break;
case Epostfix:
- pri("(%e)%c", expr->unop.child, expr->unop.op);
+ epri("(%e)%c", expr->unop.child, expr->unop.op);
break;
case Econd:
- pri("(%e) ? (%e) : (%e)", expr->cond.test, expr->cond.t, expr->cond.f);
+ epri("(%e) ? (%e) : (%e)", expr->cond.test, expr->cond.t, expr->cond.f);
break;
case Ecall:
- pri("%e(", expr->call.callee);
+ epri("%e(", expr->call.callee);
for (int i = 0; i < expr->call.args.n; ++i) {
- pri("%e", &expr->call.args.d[i]);
+ epri("%e", &expr->call.args.d[i]);
if (i < expr->call.args.n - 1)
- pri(", ");
+ epri(", ");
}
- pri(")");
+ epri(")");
break;
case Eindex:
- pri("%e[%e]", expr->index.lhs, expr->index.rhs);
+ epri("%e[%e]", expr->index.lhs, expr->index.rhs);
break;
default:
assert(0 && "exprbad");
@@ -264,10 +291,10 @@ static void dumpstmt(const struct stmt *stmt, int ws);
static void
dumpblock(const struct blockstmt *block, int ws) {
- pri("%w{\n", ws -1);
+ epri("%w{\n", ws -1);
for (int i = 0; i < block->stmts.n; ++i)
dumpstmt(&block->stmts.d[i], ws + 1);
- pri("%w}\n", ws - 1);
+ epri("%w}\n", ws - 1);
}
static void
@@ -280,101 +307,101 @@ dumpstmt(const struct stmt *stmt, int ws) {
dumpdecl(&stmt->decl, ws);
break;
case Sexpr:
- pri("%w%e\n", ws, &stmt->expr);
+ epri("%w%e\n", ws, &stmt->expr);
break;
case Sifelse:
- pri("%wif (%e)\n", ws, &stmt->ifelse.test);
+ epri("%wif (%e)\n", ws, &stmt->ifelse.test);
dumpblock(&stmt->ifelse.t, ws + 1);
if (stmt->ifelse.f) {
- pri("%welse\n", ws);
+ epri("%welse\n", ws);
dumpstmt(stmt->ifelse.f, ws + 1);
}
break;
case Swhile:
- pri("%wwhile %e\n", ws, &stmt->loop.test);
+ epri("%wwhile %e\n", ws, &stmt->loop.test);
dumpblock(&stmt->loop.body, ws + 1);
break;
case Sfor:
- pri("%wfor \n", ws);
+ epri("%wfor \n", ws);
if (stmt->loop.ini)
dumpstmt(stmt->loop.ini, ws + 1);
- pri("%w; %e; ", ws + 1, &stmt->loop.test);
+ epri("%w; %e; ", ws + 1, &stmt->loop.test);
if (stmt->loop.next)
- pri("%e", stmt->loop.next);
- pri("\n");
+ epri("%e", stmt->loop.next);
+ epri("\n");
dumpblock(&stmt->loop.body, ws + 1);
break;
case Siswitch:
- pri("%wswitch %e {\n", ws, &stmt->iswitch.test);
+ epri("%wswitch %e {\n", ws, &stmt->iswitch.test);
for (int i = 0; i < stmt->iswitch.cs.n; ++i) {
struct iswitchcase *c = &stmt->iswitch.cs.d[i];
- pri("%wcase ", ws);
+ epri("%wcase ", ws);
for (int j = 0; j < c->es.n; ++j)
- pri("%e, ", &c->es.d[j]);
- pri("do\n");
+ epri("%e, ", &c->es.d[j]);
+ epri("do\n");
dumpblock(&c->t, ws + 1);
}
if (stmt->iswitch.f) {
- pri("%wcase else\n", ws);
+ epri("%wcase else\n", ws);
dumpblock(stmt->iswitch.f, ws + 1);
}
- pri("%w}\n", ws);
+ epri("%w}\n", ws);
break;
case Sreturn:
if (stmt->retex)
- pri("%wreturn %e;\n", ws, stmt->retex);
+ epri("%wreturn %e;\n", ws, stmt->retex);
else
- pri("%wreturn;\n", ws);
+ epri("%wreturn;\n", ws);
break;
}
}
static void
dumpdecl(const struct decl *decl, int ws) {
- pri("%w", ws);
- pri("decl %s ", decl->name);
+ epri("%w", ws);
+ epri("decl %s ", decl->name);
switch (decl->t) {
case Dtype:
- pri("<type> %t\n", decl->ty);
+ epri("<type> %t\n", decl->ty);
break;
case Dlet:
case Dstatic:
- pri("<var> %t", decl->var.ty);
+ epri("<var> %t", decl->var.ty);
if (decl->var.ini)
- pri(" = %e", decl->var.ini);
- pri("\n");
+ epri(" = %e", decl->var.ini);
+ epri("\n");
break;
case Dfn:
- pri("<%sfn> (", decl->externp ? "extern " : "");
+ epri("<%sfn> (", decl->externp ? "extern " : "");
for (int i = 0; i < decl->fn.params.n; ++i)
- pri("%s %t, ", decl->fn.params.d[i].name, decl->fn.params.d[i].ty);
+ epri("%s %t, ", decl->fn.params.d[i].name, decl->fn.params.d[i].ty);
if (decl->fn.variadic)
- pri("...");
- pri(") %t", decl->fn.retty);
+ epri("...");
+ epri(") %t", decl->fn.retty);
if (decl->fn.body) {
- pri("\n");
+ epri("\n");
dumpstmt(decl->fn.body, ws + 1);
} else {
- pri(" <...>\n");
+ epri(" <...>\n");
}
break;
case Dmacro:
- pri("<macro> {\n");
+ epri("<macro> {\n");
for (int i = 0; i < decl->macro.cs.n; ++i) {
struct macrocase c = decl->macro.cs.d[i];
- pri("(");
+ epri("(");
for (int j = 0; j < c.params.n; ++j) {
if (j == c.params.n - 1 && c.variadic)
- pri("...");
- pri("%s", c.params.d[j]);
+ epri("...");
+ epri("%s", c.params.d[j]);
if (j < c.params.n - 1)
- pri(", ");
+ epri(", ");
}
- pri(") ");
+ epri(") ");
pritoktree(c.body);
- pri("\n");
+ epri("\n");
}
- pri("}\n");
+ epri("}\n");
break;
}
}