aijuprogress!93d470012 years agoHistory
1322 lines · 25.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "dat.h"#include "fns.h" SymTab global;SymTab *scope = &global;int curlevel; Type types[NTYPE] = {	{TXXX, 0, 0, 0},	{TUCHAR, 0, 1, 0},	{TCHAR, 1, 1, 0},	{TUSHORT, 0, 2, 2},	{TSHORT, 1, 2, 2},	{TUINT, 0, 4, 4},	{TINT, 1, 4, 4},	{TUVLONG, 0, 8, 4},	{TVLONG, 1, 8, 4},	{TFLOAT, 1, 4, 4},	{TDOUBLE, 1, 8, 4},	{TVOID, 0},};Type *typelist;static char *astname[] = {	"ASTCLONG",	"ASTBIN",	"ASTASS",	"ASTTERN",	"ASTDEREF",	"ASTADDROF",	"ASTUN",	"ASTINC",	"ASTIF",	"ASTSYM",	"ASTARRAY",	"ASTFUNCTYPE",	"ASTCAST",	"ASTCOMMA",	"ASTBLOCK",	"ASTWHILE",	"ASTDOWHILE",	"ASTFOR",	"ASTBREAK",	"ASTCONTINUE",	"ASTRETURN",	"ASTLABEL",	"ASTGOTO",	"ASTMEMB",	"ASTCALL",};static char *copname[] = {	[OPMOV] "MOV",	[OPUPLUS] "unary +",	[OPNEG] "unary -",	[OPISZ] "!",	[OPADD] "+",	[OPSUB] "-",	[OPMUL] "*",	[OPDIV] "/",	[OPMOD] "%",	[OPEQ] "==",	[OPNE] "!=",	[OPLT] "<",	[OPLE] "<=",	[OPGT] ">",	[OPGE] ">=",	[OPB] "unsigned <",	[OPBE] "unsigned <=",	[OPA] "unsigned >",	[OPAE] "unsigned >=",	[OPAND] "&",	[OPOR] "|",	[OPXOR] "^",	[OPLSH] "<<",	[OPRSH] "unsigned >>",	[OPASR] "signed >>",	[OPCOM] "~",	[OPLOR] "||",	[OPLAND] "&&",};static char *iropname[] = {	[OPMOV] "MOV",	[OPNEG] "NEG",	[OPISZ] "ISZ",	[OPTST] "TST",	[OPLD] "LD",	[OPST] "ST",	[OPLDB] "LDB",	[OPLDSB] "LDSB",	[OPSTB] "STB",	[OPLDH] "LDH",	[OPLDSH] "LDSH",	[OPSTH] "STH",	[OPLDD] "LDD",	[OPSTD] "STD",	[OPADD] "ADD",	[OPSUB] "SUB",	[OPRSB] "RSB",	[OPMUL] "MUL",	[OPDIV] "DIV",	[OPMOD] "MOD",	[OPCMP] "CMP",	[OPEQ] "BEQ",	[OPNE] "BNE",	[OPLT] "BLT",	[OPLE] "BLE",	[OPGT] "BGT",	[OPGE] "BGE",	[OPB] "BB",	[OPBE] "BBE",	[OPA] "BA",	[OPAE] "BAE",	[OPAND] "AND",	[OPOR] "OR",	[OPXOR] "XOR",	[OPLSH] "LSH",	[OPRSH] "RSH",	[OPASR] "ASR",	[OPCOM] "COM",	[OPSXTB] "SXTB",	[OPSXTH] "SXTH",	[OPSXTW] "SXTW",	[OPZXTB] "ZXTB",	[OPZXTH] "ZXTH",	[OPZXTW] "ZXTW",	[OPPHI] "φ",	[OPCALL] "CALL",	[OPFADD] "FADD",	[OPFSUB] "FSUB",	[OPFMUL] "FMUL",	[OPFDIV] "FDIV",	[OPFCMP] "FCMP",};static char *typename[] = {	"XXX",	"uchar",	"char",	"ushort",	"short",	"uint",	"int",	"uvlong",	"vlong",	"float",	"double",	"void",}; static uinthash(char *s){	uint c; 	c = 0;	while(*s != 0)		c += *s++;	return c;} static Symbol *makesym(char *n){	SymTab *st;	Symbol *s;	int h; 	if(curlevel != scope->level){		st = emalloc(sizeof(*st));		st->up = scope;		scope = st;	}	s = emalloc(sizeof(*s));	s->num = -1;	s->name = strdup(n);	h = hash(n) % SYMHASH;	s->next = scope->sym[h];	s->Line = curline;	s->level = curlevel;	scope->sym[h] = s;	return s;} Symbol *getsym(char *n){	SymTab *st;	Symbol *s;	int h;		h = hash(n) % SYMHASH;	for(st = scope; st != nil; st = st->up)		for(s = st->sym[h]; s != nil; s = s->next)			if(strcmp(s->name, n) == 0)				return s;	return makesym(n);} voidchecksym(Symbol *s){	if(s->t == nil){		error(nil, "'%s' undeclared", s->name);		s->t = &types[TINT];	}} static voidfuncparams(void){	Member *m, *me;	Symbol *s, **sp;		me = curfunc->type->memb + curfunc->type->nmemb;	curfunc->arg = sp = emalloc(sizeof(Member *) * curfunc->type->nmemb);	for(m = curfunc->type->memb; m < me; m++, sp++)		if(m->name != nil){			s = makesym(m->name);			s->t = m->type;			s->off = m->off;			*sp = s;		}} voidlevelch(int n){	SymTab *st, *stn;		curlevel += n;	if(curlevel == 1 && n > 0)		funcparams();	assert(curlevel >= 0);	if(n < 0){		st = scope;		while(st->level > curlevel){			stn = st->up;			free(st);			st = stn;			assert(st != nil);		}		scope = st;	}} intopfmt(Fmt *f){	int t;		t = va_arg(f->args, int);	if(t >= nelem(copname) || copname[t] == nil)		return fmtprint(f, "??? (%d)", t);	return fmtstrcpy(f, copname[t]);} intastfmt(Fmt *f){	int t;		t = va_arg(f->args, int);	if(t >= nelem(astname))		return fmtprint(f, "??? (%d)", t);	return fmtstrcpy(f, astname[t]);} inttypefmtrec(Fmt *f, Type *t){	int rc, i; 	if(t == nil)		return fmtstrcpy(f, "??? (nil)");	switch(t->t){	case TIND:		rc = typefmtrec(f, t->link);		rc += fmtstrcpy(f, "*");		return rc;	case TFUNC:		rc = typefmtrec(f, t->link);		rc += fmtstrcpy(f, "()(");		if(t->nmemb != 0)			for(i = 0;;){				rc += typefmtrec(f, t->memb[i].type);				if(++i != t->nmemb)					rc += fmtstrcpy(f, ", ");				else					break;			}		rc += fmtstrcpy(f, ")");		return rc;	case TSTRUCT:		if(t->tag != nil)			rc = fmtprint(f, "struct %s", t->tag);		else			rc = fmtprint(f, "struct %p", t);		return rc;	case TUNION:		if(t->tag != nil)			rc = fmtprint(f, "union %s", t->tag);		else			rc = fmtprint(f, "union %p", t);		return rc;	}	if(t->t >= nelem(typename))		return fmtprint(f, "??? (%d)", t->t);	return fmtstrcpy(f, typename[t->t]);} inttypefmt(Fmt *f){	return typefmtrec(f, va_arg(f->args, Type *));} intirtargfmt(Fmt *f){	Targ *t;	int rc;		t = va_arg(f->args, Targ *);	if(t == nil)		return fmtstrcpy(f, "nil");	switch(t->t){	case TARGSYM:		rc = fmtstrcpy(f, t->sym->name);		break;	case TARGSSA:		rc = fmtprint(f, "%s:%d", t->sym->name, t->n);		break;	case TARGTEMP:		rc = fmtprint(f, "t%d", t->tn);		if(t->type != nil)			switch(t->type->t){			case TFLOAT: rc += fmtrune(f, 'f'); break;			case TDOUBLE: rc += fmtrune(f, 'd'); break;			}		break;	case TARGCONST:		rc = fmtprint(f, "$%#ux", t->lval);		break;	case TARGRETV:		rc = fmtprint(f, t->type == &types[TFLOAT] || t->type == &types[TDOUBLE] ? "F0" : "R0");		break;	case TARGFP:		rc = fmtprint(f, "FP(%d)", t->off);		break;	case TARGARG:		rc =fmtprint(f, "ARG(%d)", t->off);		break;	case TARGIND:		rc = fmtprint(f, "(%J)", t->link);		break;	case TARGADDR:		rc = fmtprint(f, "&%s%+d", t->sym->name, t->n);		break;	case TARGSH:		rc = fmtprint(f, "%s(%J, %J)", iropname[t->op], t->a, t->b);		break;	default:		return fmtprint(f, "???(%d)", t->t);	}	if(t->Rn >= 32)		rc += fmtprint(f, "<F%d>", t->Rn - 32);	else if(t->Rn >= 0)		rc += fmtprint(f, "<R%d>", t->Rn);	return rc;} intirfmt(Fmt *f){	IR *i;	int rc, j, fi;		i = va_arg(f->args, IR *);	if(i->op >= nelem(iropname) || iropname[i->op] == nil)		rc = fmtprint(f, "???(%#x)", i->op);	else		rc = fmtstrcpy(f, iropname[i->op]);	switch(OPTYPE(i->op)){	case OPNORM:		if(i->a != nil)			rc += fmtprint(f, " %J", i->a);		if(i->b != nil && i->a != nil)			rc += fmtrune(f, ',');		if(i->b != nil)			rc += fmtprint(f, " %J", i->b);		if((i->a != nil || i->b != nil) && i->r != nil)			rc += fmtrune(f, ',');		if(i->r != nil)			rc += fmtprint(f, " %J", i->r);		return rc;	case OPBRANCH:		rc += fmtprint(f, " %p", i->targ);		return rc;	case OPPHI:		fi = 0;		if(i->r != nil){			rc += fmtprint(f, " %J", i->r);			fi++;		}		for(j = 0; j < i->φ.n; j++){			if(fi++ != 0)				rc += fmtrune(f, ',');			rc += fmtprint(f, " %J", i->φ.a[j]);		}		return rc;	default:		rc += fmtprint(f, " ???(%#x)", OPTYPE(i->op));		return rc;	}} ASTNode*node(int type, ...){	va_list va;	ASTNode *n, *l, *m;	int i; 	n = emalloc(sizeof(*n));	n->t = type;	n->Line = curline;	va_start(va, type);	switch(type){	case ASTCLONG:		n->lval = va_arg(va, vlong);		break;	case ASTSYM:	case ASTGOTO:	case ASTLABEL:		n->sym = va_arg(va, Symbol *);		break;	case ASTBIN:	case ASTASS:		n->op = va_arg(va, int);	case ASTARRAY:	case ASTCOMMA:		n->n1 = va_arg(va, ASTNode *);		n->n2 = va_arg(va, ASTNode *);		break;	case ASTMEMB:		n->mb.n = va_arg(va, ASTNode *);		n->mb.name = va_arg(va, char *);		break;	case ASTUN:	case ASTINC:		n->op = va_arg(va, int);		n->n1 = va_arg(va, ASTNode *);		break;	case ASTFUNCTYPE:		n->name = va_arg(va, ASTNode *);		n->memb = va_arg(va, Member *);		n->nmemb = va_arg(va, int);		break;	case ASTDEREF:	case ASTRETURN:	case ASTADDROF:		n->n = va_arg(va, ASTNode *);		break;	case ASTBLOCK:		n->last = &n->first;		break;	case ASTTERN:	case ASTIF:		n->cond = va_arg(va, ASTNode *);		n->block = va_arg(va, ASTNode *);		n->elsebl = va_arg(va, ASTNode *);		break;	case ASTWHILE:	case ASTDOWHILE:		n->cond = va_arg(va, ASTNode *);		n->block = va_arg(va, ASTNode *);		n->elsebl = nil;		break;	case ASTFOR:		n->forl.once = va_arg(va, ASTNode*);		n->forl.cond = va_arg(va, ASTNode*);		n->forl.iter = va_arg(va, ASTNode*);		n->forl.block = va_arg(va, ASTNode*);		break;	case ASTCAST:		n->cast.n = va_arg(va, ASTNode *);		n->cast.t = va_arg(va, Type *);		break;	case ASTBREAK:	case ASTCONTINUE:		break;	case ASTCALL:		n->func.n = va_arg(va, ASTNode *);		l = va_arg(va, ASTNode *);		for(i = 0, m = l; m != nil; i++)			m = m->next;		n->func.argn = i;		n->func.args = emalloc(sizeof(ASTNode *) * i);		for(i = 0, m = l; m != nil; i++){			l = m->next;

Lines 1–500 of 1322.