Charles.Forsyth20060303644188019 years agoHistory
444 lines · 7.1 KB · C
RawDownload
#include <lib9.h>#include <bio.h>#include <ctype.h>#include "mach.h"#define Extern extern#include "acid.h" static char *binop[] ={	0,	0,	"*",	/* [OMUL]	"*", */	"/",	/* [ODIV]	"/", */	"%",	/* [OMOD]	"%", */	"+",	/* [OADD]	"+", */	"-",	/* [OSUB]	"-", */	">>",	/* [ORSH]	">>", */	"<<",	/* [OLSH]	"<<", */	"<",	/* [OLT]	"<", */	">",	/* [OGT]	">", */	"<=",	/* [OLEQ]	"<=", */	">=",	/* [OGEQ]	">=", */	"==",	/* [OEQ]	"==", */	"!=",	/* [ONEQ]	"!=", */	"&",	/* [OLAND]	"&", */	"^",	/* [OXOR]	"^", */	"|",	/* [OLOR]	"|", */	"&&",	/* [OCAND]	"&&", */	"||",	/* [OCOR]	"||", */	" = ",	/* [OASGN]	" = ", */}; static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";char *typenames[] ={	"integer",	/* [TINT]	"integer", */	"float",	/* [TFLOAT]	"float", */	"string",	/* [TSTRING]	"string", */	"list",		/* [TLIST]	"list", */	"code",		/* [TCODE]	"code", */}; intcmp(const void *a, const void *b){	return strcmp(*(char**)a, *(char**)b);} voidfundefs(void){	Lsym *l;	char **vec;	int i, j, n, max, col, f, g, s; 	max = 0;	f = 0;	g = 100;	vec = gmalloc(sizeof(char*)*g);	if(vec == 0)		fatal("out of memory"); 	for(i = 0; i < Hashsize; i++) {		for(l = hash[i]; l; l = l->hash) {			if(l->proc == 0 && l->builtin == 0)				continue;			n = strlen(l->name);			if(n > max)				max = n;			if(f >= g) {				g *= 2;				vec = realloc(vec, sizeof(char*)*g);				if(vec == 0)					fatal("out of memory");			}			vec[f++] = l->name;		}	}        qsort(vec, f, sizeof(char*), cmp);	max++;	col = 60/max;	s = (f+col-1)/col; 	for(i = 0; i < s; i++) {		for(j = i; j < f; j += s)			Bprint(bout, "%-*s", max, vec[j]);		Bprint(bout, "\n");	}} voidwhatis(Lsym *l){	int t;	int def;	Type *ti; 	if(l == 0) {		fundefs();		return;	} 	def = 0;	if(l->v->set) {		t = l->v->type;		Bprint(bout, "%s variable", typenames[t]);		if(t == TINT || t == TFLOAT)			Bprint(bout, " format %c", l->v->vstore.fmt);		if(l->v->vstore.comt)			Bprint(bout, " complex %s",						l->v->vstore.comt->base->name);		Bputc(bout, '\n');		def = 1;	}	if(l->lt) {		Bprint(bout, "complex %s {\n", l->name);		for(ti = l->lt; ti; ti = ti->next) {			if(ti->type) {				if(ti->fmt == 'a') {					Bprint(bout, "\t%s %d %s;\n",					ti->type->name, ti->offset,					ti->tag->name);				}				else {					Bprint(bout, "\t'%c' %s %d %s;\n",					ti->fmt, ti->type->name, ti->offset,					ti->tag->name);				}			}			else				Bprint(bout, "\t'%c' %d %s;\n",				ti->fmt, ti->offset, ti->tag->name);		}		Bprint(bout, "};\n");		def = 1;	}	if(l->proc) {		Bprint(bout, "defn %s(", l->name);		pexpr(l->proc->left);		Bprint(bout, ") {\n");		pcode(l->proc->right, 1);		Bprint(bout, "}\n");		def = 1;	}	if(l->builtin) {		Bprint(bout, "builtin function\n");		def = 1;	}	if(def == 0)		Bprint(bout, "%s is undefined\n", l->name);} voidslist(Node *n, int d){	if(n == 0)		return;	if(n->op == OLIST)		Bprint(bout, "%.*s{\n", d-1, tabs);	pcode(n, d);	if(n->op == OLIST)		Bprint(bout, "%.*s}\n", d-1, tabs);} voidpcode(Node *n, int d){	Node *r, *l; 	if(n == 0)		return; 	r = n->right;	l = n->left; 	switch(n->op) {	default:		Bprint(bout, "%.*s", d, tabs);		pexpr(n);		Bprint(bout, ";\n");		break;	case OLIST:		pcode(n->left, d);		pcode(n->right, d);		break;	case OLOCAL:		Bprint(bout, "%.*slocal", d, tabs);		while(l) {			Bprint(bout, " %s", l->sym->name);			l = l->left;			if(l == 0)				Bprint(bout, ";\n");			else				Bprint(bout, ",");		}		break;	case OCOMPLEX:		Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);		break;	case OIF:		Bprint(bout, "%.*sif ", d, tabs);		pexpr(l);		d++;		Bprint(bout, " then\n", d, tabs);		if(r && r->op == OELSE) {			slist(r->left, d);			Bprint(bout, "%.*selse\n", d-1, tabs, d, tabs);			slist(r->right, d);		}		else			slist(r, d);		break;	case OWHILE:		Bprint(bout, "%.*swhile ", d, tabs);		pexpr(l);		d++;		Bprint(bout, " do\n", d, tabs);		slist(r, d);		break;	case ORET:		Bprint(bout, "%.*sreturn ", d, tabs);		pexpr(l);		Bprint(bout, ";\n");		break;	case ODO:		Bprint(bout, "%.*sloop ", d, tabs);		pexpr(l->left);		Bprint(bout, ", ");		pexpr(l->right);		Bprint(bout, " do\n");		slist(r, d+1);	}} voidpexpr(Node *n){	Node *r, *l; 	if(n == 0)		return; 	r = n->right;	l = n->left; 	switch(n->op) {	case ONAME:		Bprint(bout, "%s", n->sym->name);		break;	case OCONST:		switch(n->type) {		case TINT:			Bprint(bout, "%d", (int)n->nstore.u0.sival);			break;		case TFLOAT:			Bprint(bout, "%g", n->nstore.u0.sfval);			break;		case TSTRING:			pstr(n->nstore.u0.sstring);			break;		case TLIST:			break;		}		break;	case OMUL:	case ODIV:	case OMOD:	case OADD:	case OSUB:	case ORSH:	case OLSH:	case OLT:	case OGT:	case OLEQ:	case OGEQ:	case OEQ:	case ONEQ:	case OLAND:	case OXOR:	case OLOR:	case OCAND:	case OCOR:		Bputc(bout, '(');		pexpr(l);		Bprint(bout, binop[n->op]);		pexpr(r);		Bputc(bout, ')');		break;	case OASGN:		pexpr(l);		Bprint(bout, binop[n->op]);		pexpr(r);		break;	case OINDM:		Bprint(bout, "*");		pexpr(l);		break;	case OEDEC:		Bprint(bout, "--");		pexpr(l);		break;	case OEINC:		Bprint(bout, "++");		pexpr(l);		break;	case OPINC:		pexpr(l);		Bprint(bout, "++");		break;	case OPDEC:		pexpr(l);		Bprint(bout, "--");		break;	case ONOT:		Bprint(bout, "!");		pexpr(l);		break;	case OLIST:		pexpr(l);		if(r) {			Bprint(bout, ",");			pexpr(r);		}		break;	case OCALL:		pexpr(l);		Bprint(bout, "(");		pexpr(r);		Bprint(bout, ")");		break;	case OCTRUCT:		Bprint(bout, "{");		pexpr(l);		Bprint(bout, "}");		break;	case OHEAD:		Bprint(bout, "head ");		pexpr(l);		break;	case OTAIL:		Bprint(bout, "tail ");		pexpr(l);		break;	case OAPPEND:		Bprint(bout, "append ");		pexpr(l);		Bprint(bout, ",");		pexpr(r);		break;	case ODELETE:		Bprint(bout, "delete ");		pexpr(l);		Bprint(bout, ",");		pexpr(r);		break;	case ORET:		Bprint(bout, "return ");		pexpr(l);		break;	case OINDEX:		pexpr(l);		Bprint(bout, "[");		pexpr(r);		Bprint(bout, "]");		break;	case OINDC:		Bprint(bout, "@");		pexpr(l);		break;	case ODOT:		pexpr(l);		Bprint(bout, ".%s", n->sym->name);		break;	case OFRAME:		Bprint(bout, "%s:%s", n->sym->name, l->sym->name);		break;	case OCAST:		Bprint(bout, "(%s)", n->sym->name);		pexpr(l);		break;	case OFMT:		pexpr(l);		Bprint(bout, "\\%c", (int)r->nstore.u0.sival);		break;	case OEVAL:		Bprint(bout, "eval ");		pexpr(l);		break;	case OWHAT:		Bprint(bout, "whatis", n->sym->name);		if(n->sym)			Bprint(bout, " %s", n->sym->name);		break;	}} voidpstr(String *s){	int i, c; 	Bputc(bout, '"');	for(i = 0; i < s->len; i++) {		c = s->string[i];		switch(c) {		case '\0':			c = '0';			break;		case '\n':			c = 'n';			break;		case '\r':			c = 'r';			break;		case '\t':			c = 't';			break;		case '\b':			c = 'b';			break;		case '\f':			c = 'f';			break;		case '\a':			c = 'a';			break;		case '\v':			c = 'v';			break;		case '\\':			c = '\\';			break;		case '"':			c = '"';			break;		default:			Bputc(bout, c);			continue;		}		Bputc(bout, '\\');		Bputc(bout, c);	}	Bputc(bout, '"');}