Charles.Forsyth20070302a issue 173e1be5319 years agoHistory
5115 lines · 80.7 KB · C
RawDownload
#define EXTERN #include "cc.h" /* *	locals, parameters, globals etc of the same name should work ok without having *	to duplicate Syms because the details are on the containing Nodes */ #define SZ_CHAR	1#define SZ_SHORT	2#define SZ_INT	4#define SZ_LONG	4#define SZ_FLOAT	4#define SZ_IND	4#define SZ_VLONG	8#define SZ_DOUBLE	8 char buf[128], mbuf[128];static Sym *sysop, *bioop, *libcop;static int again; #define	STAR	0x80#define	RET		0x80 #define	LARR	(-1729) static void swalk(void);static int isdec(Node*);static int isconst(Node*, vlong);static int cktype(Node*, Node*, int, int);static void addnode(int, Node*);static int argpos(Node*, Node*);static void setdec(Sym*, Type*);static Type* tcp(Type*);static int isadt(Type*);static void aargs(Node*);static int iteq(Type*, Type*);static Node* arg(Node*, int);static void etgen2(Sym*);static Node* ckneg(Node*);static Sym* suename(Type*);static int isnil(Node*);static void sliceasgn(Node*);static Node* lastn(Node*);static char* hasm(void);static void prn(Node*, int);static int isfn(Type*); schar	ewidth[NTYPE] ={	-1,		/* [TXXX] */	SZ_CHAR,	/* [TCHAR] */	SZ_CHAR,	/* [TUCHAR] */	SZ_SHORT,	/* [TSHORT] */	SZ_SHORT,	/* [TUSHORT] */	SZ_INT,		/* [TINT] */	SZ_INT,		/* [TUINT] */	SZ_LONG,	/* [TLONG] */	SZ_LONG,	/* [TULONG] */	SZ_VLONG,	/* [TVLONG] */	SZ_VLONG,	/* [TUVLONG] */	SZ_FLOAT,	/* [TFLOAT] */	SZ_DOUBLE,	/* [TDOUBLE] */	SZ_IND,		/* [TIND] */	0,		/* [TFUNC] */	-1,		/* [TARRAY] */	0,		/* [TVOID] */	-1,		/* [TSTRUCT] */	-1,		/* [TUNION] */	SZ_INT,		/* [TENUM] */}; long	ncast[NTYPE] ={	0,				/* [TXXX] */	BCHAR|BUCHAR,			/* [TCHAR] */	BCHAR|BUCHAR,			/* [TUCHAR] */	BSHORT|BUSHORT,			/* [TSHORT] */	BSHORT|BUSHORT,			/* [TUSHORT] */	BINT|BUINT|BLONG|BULONG|BIND,	/* [TINT] */	BINT|BUINT|BLONG|BULONG|BIND,	/* [TUINT] */	BINT|BUINT|BLONG|BULONG|BIND,	/* [TLONG] */	BINT|BUINT|BLONG|BULONG|BIND,	/* [TULONG] */	BVLONG|BUVLONG,			/* [TVLONG] */	BVLONG|BUVLONG,			/* [TUVLONG] */	BFLOAT,				/* [TFLOAT] */	BDOUBLE,			/* [TDOUBLE] */	BLONG|BULONG|BIND,		/* [TIND] */	0,				/* [TFUNC] */	0,				/* [TARRAY] */	0,				/* [TVOID] */	BSTRUCT,			/* [TSTRUCT] */	BUNION,				/* [TUNION] */	0,				/* [TENUM] */}; enum{	TCFD = 1,	TCFC = 2,	TCPC = 4,	TCAR = 8,	TCIN = 16,	TCGEN = TCFD|TCFC|TCPC|TCAR,	TCALL = TCFD|TCFC|TCPC|TCAR|TCIN,}; enum{	SGLOB,	SPARM,	SAUTO,}; typedef struct Scope Scope; struct Scope{	Node *n;	int	k;	Scope *nxt;}; static voidprtyp(Type *t, char *s, int nl){	print("%s: ", s);	if(t == T){		print("nil");		if(nl)			print("\n");		return;	}	while(t != T){		print("%d(%d)[%x] ", t->etype, t->mark, (int)t);		if(isadt(t))			break;		t = t->link;	}	if(nl)		print("\n");} static Node*func(Node *n){	while(n != Z && n->op != OFUNC)		n = n->left;	return n;} static voidsetmain(Node *n){	inmain |= n->left->op == ONAME && strcmp(n->left->sym->name, "main") == 0;} static Node*protoname(Node *n){	do		n = n->left;	while(n != Z && n->op != ONAME && n->op != ODOTDOT);	return n;} static Type*prototype(Node *n, Type *t){	for( ; n != Z ; n = n->left){		switch(n->op){		case OARRAY:			t = typ(TARRAY, t);			t->width = 0;			break;		case OIND:			t = typ(TIND, t);			break;		case OFUNC:			t = typ(TFUNC, t);			t->down = fnproto(n);			break;		}	}	return t;} static Scope *scopes, *freescopes; static voidpushdcl(Node *n, int c){	Sym *s; 	if(passes){		s = n->sym;		push1(s);		if(c != CAUTO || s->class != CSTATIC)			s->class = c;		s->type = n->type;	}} static voidpushparams(Node *n){	if(n == Z)		return;	if(passes){		if(n->op == OLIST){			pushparams(n->left);			pushparams(n->right);		}		else if(n->op == OPROTO){			n = protoname(n);			if(n != Z && n->op == ONAME)				pushdcl(n, CPARAM);		}		else if(n->op == ONAME){			addnode(OPROTO, n);			pushdcl(n, CPARAM);		}		else if(n->op != ODOTDOT)			diag(Z, "bad op in pushparams");	}} static voidpushscope(Node *n, int k){	Scope *s; 	if(freescopes != nil){		s = freescopes;		freescopes = freescopes->nxt;	}	else		s = (Scope*)malloc(sizeof(Scope));	s->n = n;	s->k = k;	s->nxt = scopes;	scopes = s;	if(passes && (k == SPARM || k == SAUTO))		markdcl();	if(k == SPARM)		pushparams(n->right);} static voidpopscope(void){	int k;	Scope *s; 	s = scopes;	k = s->k;	scopes = scopes->nxt;	s->nxt = freescopes;	freescopes = s;	if(passes && (k == SPARM || k == SAUTO))		revertdcl();} static Node*curfn(void){	Scope *s; 	for(s = scopes; s != nil; s = s->nxt)		if(s->k == SPARM)			return s->n;	return Z;} static voidmarktype(Type *t, int tc){	t->mark = tc;} static intmarked(Type *t){	return t == T ? 0 :  t->mark;} static Sym*decsym(Node *n){	if(n == Z)		return S;	if(n->op == OFUNC){		if(n->left->op == ONAME)			return n->left->sym;		return S;	}	if(n->op == ODAS)		return n->left->sym;	return n->sym;} static voidtrep(Type *t1, Type *t){	int l;	Sym *s;	Type *t2; 	if(t1 != T){		l = t1->lineno;		s = t1->sym;		t2 = t1->down;		*t1 = *t;		t1->down = t2;		t1->sym = s;		t1->lineno = l;	}} static voidtind(Node *n){	if(n == Z)		return;	n = protoname(n);	if(n != Z && n->type != T){		n->type = tcp(n->type->link);		marktype(n->type, TCIN);	}} static voidtcon(Node *n, Type *t){	Type *tt; 	if(n->garb)		return;	n->garb = 1;	again = 1;	switch(n->op){		case OCONST:			if(t->mark == TCFD && !isnil(n))				addnode(OFILDES, n);			n->type = t;			break;		case OCAST:			tcon(n->left, t);			*n = *n->left;			n->type = t;			break;		case ONAME:			n->sym->type = t;			n->type = t;			setdec(n->sym, t);			break;		case ODOT:		case ODOTIND:			trep(n->type, t);			n->type = t;			break;		case OARRIND:			tt = n->left->type;			if(tt != T)				tt->link = t;			n->type = t;			break;		case OFUNC:			n->left->type->link = t;			if(n->left->op == ONAME)				n->left->sym->type->link = t;			n->type = t;			break;	}} static Node*retval(Node *n){	int i;	Type *t;	Node *a, *l, *cf; 	cf = curfn();	t = cf->left->type->link;	if(t->mark&(TCPC|TCFC) && (n == Z || !(n->type->mark&(TCPC|TCFC)))){		if(n == Z)			n = new1(ORETURN, Z, Z);		l = n->left;		for(i = 0; ; i++){			a = arg(cf->right, i);			if(a == Z)				break;			a = protoname(a);			if(a == Z || a->op != ONAME)				break;			if(a->type->mark == TCIN){				if(l == Z)					l = ncopy(a);				else					l = new1(OTUPLE, l, ncopy(a));			}		}		n->left = l;		n->type = l->type = t;	}	return n;} static voidsube(Node *n){	Node *l, *r, *nn;	Type *tt;	static Node *gn;	int p; 	if(n == Z)		return;	l = n->left;	r = n->right;	switch(n->op){		default:			sube(l);			sube(r);			break;		case OIND:			if(l == Z)				return;			tt = l->type;			sube(l);			if(cktype(l, n, TCIN, 0) && iteq(tt, l->type))				*n = *n->left;			break;		case OARRIND:			tt = l->type;			sube(l);			sube(r);			if(!isconst(r, 0))				break;			if(cktype(l, n, TCIN, 0) && iteq(tt, l->type))				*n = *n->left;			break;		case ONAME:			if(cktype(n, n, TCALL, 0))				setdec(n->sym, n->type);			break;		case OCAST:			sube(l);			if(cktype(l, n, TCALL, 0))				n->type = l->type;			break;		case OPROTO:			sube(l);			sube(r);			nn = protoname(n);			if(nn != Z && cktype(nn, n, TCALL, 0)){				n->type = nn->type;				p = argpos(n, gn->right);				for(tt = gn->left->type->down; tt != T && p >= 0; tt = tt->down){					if(p == 0){						trep(tt, nn->type);						break;					}					--p;				}			}			break;		case OFUNC:			if(n->kind == KEXP)				aargs(n);			if(n->left->op == ONAME)				gn = n;			sube(l);			sube(r);			if(l != Z && cktype(n, n, TCGEN, 0))				l->type->link = n->type;			break;		case OAS:			sube(l);			sube(r);			if(r->op == ORETV){				n->left = new1(OTUPLE, l, r->right);				n->right = r->left;				n->left->type = n->type;				break;			}			if(cktype(r, n, TCGEN, 0)){				tcon(l, r->type);				n->type = r->type;			}			if(cktype(l, n, TCGEN, 1)){				tcon(r, l->type);				n->type = l->type;			}			break;		case OLT:		case OGE:			sube(l);			sube(r);			if(cktype(l, n, TCFD, 0) && isconst(r, 0)){				n->op = n->op == OLT ? OEQ : ONE;

Lines 1–500 of 5115.