1121 lines · 18.9 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include <mach.h>#define Extern extern#include "acid.h" static int fsize[256]; static voidinitfsize(void){	fsize['A'] = 4;	fsize['B'] = 4;	fsize['C'] = 1;	fsize['D'] = 4;	fsize['F'] = 8;	fsize['G'] = 8;	fsize['O'] = 4;	fsize['Q'] = 4;	fsize['R'] = 4;	fsize['S'] = 4;	fsize['U'] = 4;	fsize['V'] = 8;	fsize['X'] = 4;	fsize['Y'] = 8;	fsize['W'] = 8;	fsize['Z'] = 8;	fsize['a'] = 4;	fsize['b'] = 1;	fsize['c'] = 1;	fsize['d'] = 2;	fsize['f'] = 4;	fsize['g'] = 4;	fsize['o'] = 2;	fsize['q'] = 2;	fsize['r'] = 2;	fsize['s'] = 4;	fsize['u'] = 2;	fsize['x'] = 2;} intfmtsize(Value *v){	int ret; 	switch(v->store.fmt) {	default:		return  fsize[(unsigned char)v->store.fmt];	case 'i':	case 'I':		if(v->type != TINT || mach == 0)			error("no size for i fmt pointer ++/--");		ret = (*mach->instsize)(symmap, v->store.u.ival);		if(ret < 0) {			ret = (*mach->instsize)(symmap, v->store.u.ival);			if(ret < 0)				error("%r");		}		return ret;	}} Lsym*chklval(Node *lp){	Node res;	Lsym *s; 	if(lp->op == ONAME)		return lp->sym; 	if(lp->op == OCALL){		s = chklval(lp->left);		if(strcmp(s->name, "var") == 0			&& (lp->builtin || s->proc == 0)){			if(lp->right == 0)				error("var(string): arg count");			expr(lp->right, &res);			if(res.type != TSTRING)				error("var(string): arg type");			return mkvar(res.store.u.string->string);		}	}	error("need l-value");	return nil;	} voidolist(Node *n, Node *res){	expr(n->left, res);	expr(n->right, res);} voidoeval(Node *n, Node *res){	expr(n->left, res);	if(res->type != TCODE)		error("bad type for eval");	expr(res->store.u.cc, res);} voidocast(Node *n, Node *res){	if(n->sym->lt == 0)		error("%s is not a complex type", n->sym->name); 	expr(n->left, res);	res->store.comt = n->sym->lt;	res->store.fmt = 'a';} voidoindm(Node *n, Node *res){	Map *m;	Node l; 	m = cormap;	if(m == 0)		m = symmap;	expr(n->left, &l);	switch(l.type){	default:		error("bad type for *");	case TINT:		if(m == 0)			error("no map for *");		indir(m, l.store.u.ival, l.store.fmt, res);		res->store.comt = l.store.comt;		break;	case TREG:		indirreg(correg, l.store.u.reg.name, l.store.fmt, res);		res->store.comt = l.store.comt;		break;	case TCON:		*res = *l.store.u.con;		res->store.comt = l.store.comt;		break;	}} voidoindc(Node *n, Node *res){	Map *m;	Node l; 	m = symmap;	if(m == 0)		m = cormap;	expr(n->left, &l);	if(l.type != TINT)		error("bad type for @");	if(m == 0)		error("no map for @");	indir(m, l.store.u.ival, l.store.fmt, res);	res->store.comt = l.store.comt;} voidoframe(Node *n, Node *res){	char *p;	Node *lp;	ulong ival;	Frtype *f; 	p = n->sym->name;	while(*p && *p == '$')		p++;	lp = n->left;	if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0)		error("colon: %r");			res->store.u.ival = ival;	res->op = OCONST;	res->store.fmt = 'X';	res->type = TINT; 	/* Try and set comt */	for(f = n->sym->local; f; f = f->next) {		if(f->var == lp->sym) {			res->store.comt = f->type;			res->store.fmt = 'a';			break;		}	}} voidoindex(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r); 	if(r.type != TINT)		error("bad type for []"); 	switch(l.type) {	default:		error("lhs[] has bad type");	case TINT:		indir(cormap, l.store.u.ival+(r.store.u.ival*fsize[(unsigned char)l.store.fmt]), l.store.fmt, res);		res->store.comt = l.store.comt;		res->store.fmt = l.store.fmt;		break;	case TLIST:		nthelem(l.store.u.l, r.store.u.ival, res);		break;	case TSTRING:		res->store.u.ival = 0;		if(r.store.u.ival >= 0 && r.store.u.ival < l.store.u.string->len) {			int xx8;	/* to get around bug in vc */			xx8 = r.store.u.ival;			res->store.u.ival = l.store.u.string->string[xx8];		}		res->op = OCONST;		res->type = TINT;		res->store.fmt = 'c';		break;	}} voidoappend(Node *n, Node *res){	Node r, l; 	expr(n->left, &l);	expr(n->right, &r);	if(l.type != TLIST)		error("must append to list");	append(res, &l, &r);} voidodelete(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	if(l.type != TLIST)		error("must delete from list");	if(r.type != TINT)		error("delete index must be integer"); 	delete(l.store.u.l, r.store.u.ival, res);} voidohead(Node *n, Node *res){	Node l; 	expr(n->left, &l);	if(l.type != TLIST)		error("head needs list");	res->op = OCONST;	if(l.store.u.l) {		res->type = l.store.u.l->type;		res->store = l.store.u.l->store;	}	else {		res->type = TLIST;		res->store.u.l = 0;	}} voidotail(Node *n, Node *res){	Node l; 	expr(n->left, &l);	if(l.type != TLIST)		error("tail needs list");	res->op = OCONST;	res->type = TLIST;	if(l.store.u.l)		res->store.u.l = l.store.u.l->next;	else		res->store.u.l = 0;} voidoconst(Node *n, Node *res){	res->op = OCONST;	res->type = n->type;	res->store = n->store;	res->store.comt = n->store.comt;} voidoname(Node *n, Node *res){	Value *v; 	v = n->sym->v;	if(v->set == 0)		error("%s used but not set", n->sym->name);	res->op = OCONST;	res->type = v->type;	res->store = v->store;	res->store.comt = v->store.comt;} voidoctruct(Node *n, Node *res){	res->op = OCONST;	res->type = TLIST;	res->store.u.l = construct(n->left);} voidoasgn(Node *n, Node *res){	Node *lp, r;	Node aes;	Value *v; 	lp = n->left;	switch(lp->op) {	case OINDM:		expr(lp->left, &aes);		if(aes.type == TREG)			windirreg(correg, aes.store.u.reg.name, n->right, res);		else			windir(cormap, aes, n->right, res);		break;	case OINDC:		expr(lp->left, &aes);		windir(symmap, aes, n->right, res);		break;	default:		v = chklval(lp)->v;		expr(n->right, &r);		v->set = 1;		v->type = r.type;		v->store = r.store;		res->op = OCONST;		res->type = v->type;		res->store = v->store;		res->store.comt = v->store.comt;	}} voidoadd(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	res->store.fmt = l.store.fmt;	res->op = OCONST;	res->type = TFLOAT;	switch(l.type) {	default:		error("bad lhs type +");	case TINT:		switch(r.type) {		case TINT:			res->type = TINT;			res->store.u.ival = l.store.u.ival+r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.ival+r.store.u.fval;			break;		default:			error("bad rhs type +");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->store.u.fval = l.store.u.fval+r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.fval+r.store.u.fval;			break;		default:			error("bad rhs type +");		}		break;	case TSTRING:		if(r.type == TSTRING) {			res->type = TSTRING;			res->store.fmt = 's';			res->store.u.string = stradd(l.store.u.string, r.store.u.string); 			break;		}		error("bad rhs for +");	case TLIST:		res->type = TLIST;		switch(r.type) {		case TLIST:			res->store.u.l = addlist(l.store.u.l, r.store.u.l);			break;		default:			r.left = 0;			r.right = 0;			res->store.u.l = addlist(l.store.u.l, construct(&r));			break;		}	}} voidosub(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	res->store.fmt = l.store.fmt;	res->op = OCONST;	res->type = TFLOAT;	switch(l.type) {	default:		error("bad lhs type -");	case TINT:		switch(r.type) {		case TINT:			res->type = TINT;			res->store.u.ival = l.store.u.ival-r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.ival-r.store.u.fval;			break;		default:			error("bad rhs type -");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->store.u.fval = l.store.u.fval-r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.fval-r.store.u.fval;			break;		default:			error("bad rhs type -");		}		break;	}} voidomul(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	res->store.fmt = l.store.fmt;	res->op = OCONST;	res->type = TFLOAT;	switch(l.type) {	default:		error("bad lhs type *");	case TINT:		switch(r.type) {		case TINT:			res->type = TINT;			res->store.u.ival = l.store.u.ival*r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.ival*r.store.u.fval;			break;		default:			error("bad rhs type *");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->store.u.fval = l.store.u.fval*r.store.u.ival;			break;		case TFLOAT:			res->store.u.fval = l.store.u.fval*r.store.u.fval;			break;		default:			error("bad rhs type *");		}		break;	}} 

Lines 1–500 of 1121.