Charles.Forsyth20060303644188019 years agoHistory
688 lines · 9.0 KB · Text
RawDownload
/* * common code for all the assemblers */ voidpragpack(void){	while(getnsc() != '\n')		;} voidpragvararg(void){	while(getnsc() != '\n')		;} voidpragfpround(void){	while(getnsc() != '\n')		;} voidpragprofile(void){	while(getnsc() != '\n')		;} voidpragincomplete(void){	while(getnsc() != '\n')		;} /* * real allocs */void*alloc(long n){	void *p; 	while((uintptr)hunk & MAXALIGN) {		hunk++;		nhunk--;	}	while(nhunk < n)		gethunk();	p = hunk;	nhunk -= n;	hunk += n;	return p;} void*allocn(void *p, long on, long n){	void *q; 	q = (uchar*)p + on;	if(q != hunk || nhunk < n) {		while(nhunk < on+n)			gethunk();		memmove(hunk, p, on);		p = hunk;		hunk += on;		nhunk -= on;	}	hunk += n;	nhunk -= n;	return p;} voidsetinclude(char *p){	int i; 	if(p == 0)		return;	for(i=1; i < ninclude; i++)		if(strcmp(p, include[i]) == 0)			return; 	if(ninclude >= nelem(include)) {		yyerror("ninclude too small %d", nelem(include));		exits("ninclude");	}	include[ninclude++] = p;} voiderrorexit(void){ 	if(outfile)		remove(outfile);	exits("error");} voidpushio(void){	Io *i; 	i = iostack;	if(i == I) {		yyerror("botch in pushio");		errorexit();	}	i->p = fi.p;	i->c = fi.c;} voidnewio(void){	Io *i;	static int pushdepth = 0; 	i = iofree;	if(i == I) {		pushdepth++;		if(pushdepth > 1000) {			yyerror("macro/io expansion too deep");			errorexit();		}		i = alloc(sizeof(*i));	} else		iofree = i->link;	i->c = 0;	i->f = -1;	ionext = i;} voidnewfile(char *s, int f){	Io *i; 	i = ionext;	i->link = iostack;	iostack = i;	i->f = f;	if(f < 0)		i->f = open(s, 0);	if(i->f < 0) {		yyerror("%ca: %r: %s", thechar, s);		errorexit();	}	fi.c = 0;	linehist(s, 0);} Sym*slookup(char *s){ 	strcpy(symb, s);	return lookup();} Sym*lookup(void){	Sym *s;	long h;	char *p;	int c, l; 	h = 0;	for(p=symb; c = *p; p++)		h = h+h+h + c;	l = (p - symb) + 1;	if(h < 0)		h = ~h;	h %= NHASH;	c = symb[0];	for(s = hash[h]; s != S; s = s->link) {		if(s->name[0] != c)			continue;		if(memcmp(s->name, symb, l) == 0)			return s;	}	s = alloc(sizeof(*s));	s->name = alloc(l);	memmove(s->name, symb, l); 	s->link = hash[h];	hash[h] = s;	syminit(s);	return s;} longyylex(void){	int c, c1;	char *cp;	Sym *s; 	c = peekc;	if(c != IGN) {		peekc = IGN;		goto l1;	}l0:	c = GETC(); l1:	if(c == EOF) {		peekc = EOF;		return -1;	}	if(isspace(c)) {		if(c == '\n') {			lineno++;			return ';';		}		goto l0;	}	if(isalpha(c))		goto talph;	if(isdigit(c))		goto tnum;	switch(c)	{	case '\n':		lineno++;		return ';'; 	case '#':		domacro();		goto l0; 	case '.':		c = GETC();		if(isalpha(c)) {			cp = symb;			*cp++ = '.';			goto aloop;		}		if(isdigit(c)) {			cp = symb;			*cp++ = '.';			goto casedot;		}		peekc = c;		return '.'; 	talph:	case '_':	case '@':		cp = symb; 	aloop:		*cp++ = c;		c = GETC();		if(isalpha(c) || isdigit(c) || c == '_' || c == '$')			goto aloop;		*cp = 0;		peekc = c;		s = lookup();		if(s->macro) {			newio();			cp = ionext->b;			macexpand(s, cp);			pushio();			ionext->link = iostack;			iostack = ionext;			fi.p = cp;			fi.c = strlen(cp);			if(peekc != IGN) {				cp[fi.c++] = peekc;				cp[fi.c] = 0;				peekc = IGN;			}			goto l0;		}		if(s->type == 0)			s->type = LNAME;		if(s->type == LNAME ||		   s->type == LVAR ||		   s->type == LLAB) {			yylval.sym = s;			return s->type;		}		yylval.lval = s->value;		return s->type; 	tnum:		cp = symb;		if(c != '0')			goto dc;		*cp++ = c;		c = GETC();		c1 = 3;		if(c == 'x' || c == 'X') {			c1 = 4;			c = GETC();		} else		if(c < '0' || c > '7')			goto dc;		yylval.lval = 0;		for(;;) {			if(c >= '0' && c <= '9') {				if(c > '7' && c1 == 3)					break;				yylval.lval <<= c1;				yylval.lval += c - '0';				c = GETC();				continue;			}			if(c1 == 3)				break;			if(c >= 'A' && c <= 'F')				c += 'a' - 'A';			if(c >= 'a' && c <= 'f') {				yylval.lval <<= c1;				yylval.lval += c - 'a' + 10;				c = GETC();				continue;			}			break;		}		goto ncu; 	dc:		for(;;) {			if(!isdigit(c))				break;			*cp++ = c;			c = GETC();		}		if(c == '.')			goto casedot;		if(c == 'e' || c == 'E')			goto casee;		*cp = 0;		if(sizeof(yylval.lval) == sizeof(vlong))			yylval.lval = strtoll(symb, nil, 10);		else			yylval.lval = strtol(symb, nil, 10); 	ncu:		while(c == 'U' || c == 'u' || c == 'l' || c == 'L')			c = GETC();		peekc = c;		return LCONST; 	casedot:		for(;;) {			*cp++ = c;			c = GETC();			if(!isdigit(c))				break;		}		if(c == 'e' || c == 'E')			goto casee;		goto caseout; 	casee:		*cp++ = 'e';		c = GETC();		if(c == '+' || c == '-') {			*cp++ = c;			c = GETC();		}		while(isdigit(c)) {			*cp++ = c;			c = GETC();		} 	caseout:		*cp = 0;		peekc = c;		if(FPCHIP) {			yylval.dval = atof(symb);			return LFCONST;		}		yyerror("assembler cannot interpret fp constants");		yylval.lval = 1L;		return LCONST; 	case '"':		memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));		cp = yylval.sval;		c1 = 0;		for(;;) {			c = escchar('"');			if(c == EOF)				break;			if(c1 < sizeof(yylval.sval))				*cp++ = c;			c1++;		}		if(c1 > sizeof(yylval.sval))			yyerror("string constant too long");		return LSCONST; 	case '\'':		c = escchar('\'');		if(c == EOF)			c = '\'';		if(escchar('\'') != EOF)			yyerror("missing '");		yylval.lval = c;		return LCONST; 	case '/':		c1 = GETC();		if(c1 == '/') {			for(;;) {				c = GETC();				if(c == '\n') {					lineno++;					goto l0;				}				if(c == EOF) {					yyerror("eof in comment");					errorexit();				}			}		}		if(c1 == '*') {			for(;;) {				c = GETC();				while(c == '*') {					c = GETC();					if(c == '/')						goto l0;				}				if(c == EOF) {					yyerror("eof in comment");					errorexit();				}				if(c == '\n')					lineno++;			}		}		break; 	default:		return c;	}	peekc = c1;	return c;} intgetc(void){	int c; 	c = peekc;	if(c != IGN) {		peekc = IGN;		return c;	}	c = GETC();	if(c == '\n')		lineno++;	if(c == EOF) {		yyerror("End of file");		errorexit();	}	return c;} intgetnsc(void){	int c; 	for(;;) {		c = getc();		if(!isspace(c) || c == '\n')			return c;	}} voidunget(int c){ 	peekc = c;	if(c == '\n')		lineno--;} intescchar(int e){	int c, l; 

Lines 1–500 of 688.