1041 lines · 15.2 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[] ={	['A'] 4,	['B'] 4,	['C'] 1,	['D'] 4,	['F'] 8,	['G'] 8,	['O'] 4,	['Q'] 4,	['R'] 4,	['S'] 4,	['U'] 4,	['V'] 8,	['W'] 8,	['X'] 4,	['Y'] 8,	['Z'] 8,	['a'] 4,	['b'] 1,	['c'] 1,	['d'] 2,	['f'] 4,	['g'] 4,	['o'] 2,	['q'] 2,	['r'] 2,	['s'] 4,	['u'] 2,	['x'] 2,	['3'] 10,	['8'] 10,}; intfmtsize(Value *v){	int ret; 	switch(v->fmt) {	default:		return  fsize[v->fmt];	case 'i':	case 'I':		if(v->type != TINT || machdata == 0)			error("no size for i fmt pointer ++/--");		ret = (*machdata->instsize)(cormap, v->ival);		if(ret < 0) {			ret = (*machdata->instsize)(symmap, v->ival);			if(ret < 0)				error("%r");		}		return ret;	}} voidchklval(Node *lp){	if(lp->op != ONAME)		error("need l-value");} 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->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->comt = n->sym->lt;	res->fmt = 'a';} voidoindm(Node *n, Node *res){	Map *m;	Node l; 	m = cormap;	if(m == 0)		m = symmap;	expr(n->left, &l);	if(l.type != TINT)		error("bad type for *");	if(m == 0)		error("no map for *");	indir(m, l.ival, l.fmt, res);	res->comt = l.comt;} 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.ival, l.fmt, res);	res->comt = l.comt;} voidoframe(Node *n, Node *res){	char *p;	Node *lp;	uvlong ival;	Frtype *f; 	p = n->sym->name;	while(*p && *p == '$')		p++;	lp = n->left;	if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0)		error("colon: %r"); 	res->ival = ival;	res->op = OCONST;	res->fmt = 'X';	res->type = TINT; 	/* Try and set comt */	for(f = n->sym->local; f; f = f->next) {		if(f->var == lp->sym) {			res->comt = f->type;			res->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.ival+(r.ival*fsize[l.fmt]), l.fmt, res);		res->comt = l.comt;		res->fmt = l.fmt;		break;	case TLIST:		nthelem(l.l, r.ival, res);		break;	case TSTRING:		res->ival = 0;		if(r.ival >= 0 && r.ival < l.string->len) {			int xx8;	/* to get around bug in vc */			xx8 = r.ival;			res->ival = l.string->string[xx8];		}		res->op = OCONST;		res->type = TINT;		res->fmt = 'c';		break;	}} voidoappend(Node *n, Node *res){	Value *v;	Node r, l;	int  empty; 	expr(n->left, &l);	expr(n->right, &r);	if(l.type != TLIST)		error("must append to list");	empty = (l.l == nil && (n->left->op == ONAME));	append(res, &l, &r);	if(empty) {		v = n->left->sym->v;		v->type = res->type;		v->Store = res->Store;		v->comt = res->comt;	}} 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.l, r.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.l) {		res->type = l.l->type;		res->Store = l.l->Store;	}	else {		res->type = TLIST;		res->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.l)		res->l = l.l->next;	else		res->l = 0;} voidoconst(Node *n, Node *res){	res->op = OCONST;	res->type = n->type;	res->Store = n->Store;	res->comt = n->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->comt = v->comt;} voidoctruct(Node *n, Node *res){	res->op = OCONST;	res->type = TLIST;	res->l = construct(n->left);} voidoasgn(Node *n, Node *res){	Node *lp, r;	Value *v; 	lp = n->left;	switch(lp->op) {	case OINDM:		windir(cormap, lp->left, n->right, res);		break;	case OINDC:		windir(symmap, lp->left, n->right, res);		break;	default:		chklval(lp);		v = lp->sym->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->comt = v->comt;	}} voidoadd(Node *n, Node *res){	Node l, r; 	if(n->right == nil){		/* unary + */		expr(n->left, res);		return;	}	expr(n->left, &l);	expr(n->right, &r);	res->fmt = l.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->ival = l.ival+r.ival;			break;		case TFLOAT:			res->fval = l.ival+r.fval;			break;		default:			error("bad rhs type +");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->fval = l.fval+r.ival;			break;		case TFLOAT:			res->fval = l.fval+r.fval;			break;		default:			error("bad rhs type +");		}		break;	case TSTRING:		if(r.type == TSTRING) {			res->type = TSTRING;			res->fmt = 's';			res->string = stradd(l.string, r.string); 			break;		}		if(r.type == TINT) {			res->type = TSTRING;			res->fmt = 's';			res->string = straddrune(l.string, r.ival);			break;		}		error("bad rhs for +");	case TLIST:		res->type = TLIST;		switch(r.type) {		case TLIST:			res->l = addlist(l.l, r.l);			break;		default:			r.left = 0;			r.right = 0;			res->l = addlist(l.l, construct(&r));			break;		}	}} voidosub(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	res->fmt = l.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->ival = l.ival-r.ival;			break;		case TFLOAT:			res->fval = l.ival-r.fval;			break;		default:			error("bad rhs type -");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->fval = l.fval-r.ival;			break;		case TFLOAT:			res->fval = l.fval-r.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->fmt = l.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->ival = l.ival*r.ival;			break;		case TFLOAT:			res->fval = l.ival*r.fval;			break;		default:			error("bad rhs type *");		}		break;	case TFLOAT:		switch(r.type) {		case TINT:			res->fval = l.fval*r.ival;			break;		case TFLOAT:			res->fval = l.fval*r.fval;			break;		default:			error("bad rhs type *");		}		break;	}} voidodiv(Node *n, Node *res){	Node l, r; 	expr(n->left, &l);	expr(n->right, &r);	res->fmt = l.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;

Lines 1–500 of 1041.