301 lines · 7.2 KB · C
RawDownload
#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <inttypes.h>#include <ctype.h>#include <string.h>#include <assert.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h> #include "util.h"#include "parse.h" /* outputs a fully qualified name */static voidoutname(Node *n, FILE *fd){	if (n->name.ns)		fprintf(fd, "%s.", n->name.ns);	fprintf(fd, "%s", n->name.name);} /* outputs a sym in a one-line short form (ie, * the initializer is not printed, and the node is not * expressed in indented tree. */static voidoutsym(Node *s, FILE *fd, int depth){	char buf[1024]; 	if (s->decl.isconst)		findentf(fd, depth, "const ");	else		findentf(fd, depth, "var ");	outname(s->decl.name, fd);	fprintf(fd, " : %s\n", tyfmt(buf, 1024, s->decl.type));} voiddumpsym(Node *s, FILE *fd) { outsym(s, fd, 0); } /* Outputs a symbol table, and it's sub-table * recursively, with a sigil describing the symbol * type, as follows: *      T       type *      S       symbol *      N       namespace * * Does not print captured variables. */static voidoutstab(Stab *st, FILE *fd, int depth){	size_t i, n;	char *name;	void **k;	char *ty;	Type *t; 	name = "";	if (st->name)		name = st->name;	findentf(fd, depth, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, name);	if (!st)		return; 	/* print types */	k = htkeys(st->ty, &n);	for (i = 0; i < n; i++) {		findentf(fd, depth + 1, "T ");		/* already indented */		outname(k[i], fd);		t = gettype(st, k[i]);		if (t->nsub)			ty = tystr(t->sub[0]);		else			ty = strdup("none");		fprintf(fd, " = %s [tid=%d]\n", ty, t->tid);		free(ty);	}	free(k); 	/* dump declarations */	k = htkeys(st->dcl, &n);	for (i = 0; i < n; i++) {		findentf(fd, depth + 1, "S ");		/* already indented */		outsym(getdcl(st, k[i]), fd, 0);	}	free(k); 	/* dump closure */	if (st->env) {		k = htkeys(st->env, &n);		for (i = 0; i < n; i++) {			findentf(fd, depth + 1, "U ");			/* already indented */			outsym(getclosed(st, k[i]), fd, 0);		}		free(k);	}} static voidoutenv(Tyenv *e, FILE *fd, int depth){	size_t n, i;	void **k;	Type *t;	char *s; 	k = htkeys(e->tab, &n);	for (i = 0; i < n; i++) {		t = htget(e->tab, k[i]);		s = tystr(t);		findentf(fd, depth + 1, "B %s\n", s);		free(s);	}	free(k);} voiddumpstab(Stab *st, FILE *fd){	outstab(st, fd, 0);} voiddumpenv(Tyenv *e, FILE *fd){	outenv(e, fd, 0);} voiddumpfilestabs(int depth, FILE *fd){	size_t nk, i;	void **k; 	k = htkeys(file.ns, &nk);	for (i = 0; i < nk; i++)		outstab(htget(file.ns, k[i]), fd, depth);	free(k);}  /* Outputs a node in indented tree form. This i * not a full serialization, but mainly an aid for * understanding and debugging. */static voidoutnode(Node *n, FILE *fd, int depth){	size_t i;	char *ty;	char *tr;	int tid;	char buf[1024]; 	if (!n) {		findentf(fd, depth, "Nil\n");		return;	}	findentf(fd, depth, "%s.%zd@%i", nodestr[n->type], n->nid, lnum(n->loc));	switch (n->type) {	case Ndecl:		tr = "";		if (n->decl.trait)			tr = namestr(n->decl.trait->name);		fprintf(fd, "(did = %zd, trait=%s, vis = %d)\n", n->decl.did, tr, n->decl.vis);		findentf(fd, depth + 1, "isglobl=%d\n", n->decl.isglobl);		findentf(fd, depth + 1, "isconst=%d\n", n->decl.isconst);		findentf(fd, depth + 1, "isgeneric=%d\n", n->decl.isgeneric);		findentf(fd, depth + 1, "isextern=%d\n", n->decl.isextern);		findentf(fd, depth + 1, "ispkglocal=%d\n", n->decl.ispkglocal);		findentf(fd, depth + 1, "ishidden=%d\n", n->decl.ishidden);		findentf(fd, depth + 1, "isimport=%d\n", n->decl.isimport);		findentf(fd, depth + 1, "isnoret=%d\n", n->decl.isnoret);		findentf(fd, depth + 1, "isexportval=%d\n", n->decl.isexportval);		findentf(fd, depth, ")\n");		outsym(n, fd, depth + 1);		outnode(n->decl.init, fd, depth + 1);		break;	case Nblock:		fprintf(fd, "\n");		outstab(n->block.scope, fd, depth + 1);		for (i = 0; i < n->block.nstmts; i++)			outnode(n->block.stmts[i], fd, depth + 1);		break;	case Nifstmt:		fprintf(fd, "\n");		outnode(n->ifstmt.cond, fd, depth + 1);		outnode(n->ifstmt.iftrue, fd, depth + 1);		outnode(n->ifstmt.iffalse, fd, depth + 1);		break;	case Nloopstmt:		fprintf(fd, "\n");		outnode(n->loopstmt.init, fd, depth + 1);		outnode(n->loopstmt.cond, fd, depth + 1);		outnode(n->loopstmt.step, fd, depth + 1);		outnode(n->loopstmt.body, fd, depth + 1);		break;	case Niterstmt:		fprintf(fd, "\n");		outnode(n->iterstmt.elt, fd, depth + 1);		outnode(n->iterstmt.seq, fd, depth + 1);		outnode(n->iterstmt.body, fd, depth + 1);		break;	case Nmatchstmt:		fprintf(fd, "\n");		outnode(n->matchstmt.val, fd, depth + 1);		for (i = 0; i < n->matchstmt.nmatches; i++)			outnode(n->matchstmt.matches[i], fd, depth + 1);		break;	case Nmatch:		fprintf(fd, "\n");		outnode(n->match.pat, fd, depth + 1);		outnode(n->match.block, fd, depth + 1);		break;	case Nuse:	fprintf(fd, " (name = %s, islocal = %d)\n", n->use.name, n->use.islocal);	break;	case Nexpr:		   if (exprop(n) == Ovar)			   assert(decls[n->expr.did]->decl.did == n->expr.did);		   ty = tystr(n->expr.type);		   if (n->expr.type)			   tid = n->expr.type->tid;		   else			   tid = -1;		   fprintf(fd, " (type = %s [tid %d], op = %s, isconst = %d, did=%zd)\n", ty, tid,				   opstr[n->expr.op], n->expr.isconst, n->expr.did);		   free(ty);		   outnode(n->expr.idx, fd, depth + 1);		   for (i = 0; i < n->expr.nargs; i++)			   outnode(n->expr.args[i], fd, depth + 1);		   break;	case Nlit:		   switch (n->lit.littype) {		   case Lvoid:	fprintf(fd, " Lvoid\n");	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 %llu\n", n->lit.intval);	break;		   case Lflt:	fprintf(fd, " Lflt %lf\n", n->lit.fltval);	break;		   case Llbl:	fprintf(fd, " Llbl %s\n", n->lit.lblval);	break;		   case Lstr:				fprintf(fd, " Lstr %.*s\n", (int)n->lit.strval.len, n->lit.strval.buf);				break;		   case Lfunc:				fprintf(fd, " lfunc\n");				outnode(n->lit.fnval, fd, depth + 1);				break;		   }		   break;	case Nfunc:		   fprintf(fd, " (args =\n");		   for (i = 0; i < n->func.nargs; i++)			   outnode(n->func.args[i], fd, depth + 1);		   findentf(fd, depth, ")\n");		   outstab(n->func.scope, fd, depth + 1);		   outnode(n->func.body, fd, depth + 1);		   break;	case Nname:		   fprintf(fd, "(");		   if (n->name.ns)			   fprintf(fd, "%s.", n->name.ns);		   fprintf(fd, "%s", n->name.name);		   fprintf(fd, ")\n");		   break;	case Nimpl:		   fprintf(fd, "(name = %s, type = %s)\n", namestr(n->impl.traitname),				   tyfmt(buf, sizeof buf, n->impl.type));		   findentf(fd, depth, "");		   outnode(n->impl.traitname, fd, depth + 1);		   for (i = 0; i < n->impl.ndecls; i++)			   outnode(n->impl.decls[i], fd, depth + 1);		   break;	case Nnone:		   fprintf(stderr, "Nnone not a real node type!");		   fprintf(fd, "Nnone\n");		   break;	}} voiddump(FILE *fd){	size_t i; 	fprintf(fd, "(name = %s)\n", file.files[0]);	dumpfilestabs(1, fd);	for (i = 0; i < file.nuses; i++)		outnode(file.uses[i], fd, 1);	for (i = 0; i < file.nstmts; i++)		outnode(file.stmts[i], fd, 1);} voiddumpn(Node *n, FILE *fd) {	outnode(n, fd, 0);}