Sigrid Solveig Haflínudóttirmerge4efd2053 years agoHistory
1409 lines · 24.5 KB · C
RawDownload
#include "all.h" enum {	Ksb = 4, /* matches Oarg/Opar/Jret */	Kub,	Ksh,	Kuh,	Kc,	K0, 	Ke = -2, /* erroneous mode */	Km = Kl, /* memory pointer */}; Op optab[NOp] = {#define O(op, t, cf) [O##op]={#op, t, cf},	#include "ops.h"}; typedef enum {	PXXX,	PLbl,	PPhi,	PIns,	PEnd,} PState; enum Token {	Txxx = 0, 	/* aliases */	Tloadw = NPubOp,	Tloadl,	Tloads,	Tloadd,	Talloc1,	Talloc2, 	Tblit,	Tcall,	Tenv,	Tphi,	Tjmp,	Tjnz,	Tret,	Thlt,	Texport,	Tthread,	Tfunc,	Ttype,	Tdata,	Tsection,	Talign,	Tl,	Tw,	Tsh,	Tuh,	Th,	Tsb,	Tub,	Tb,	Td,	Ts,	Tz, 	Tint,	Tflts,	Tfltd,	Ttmp,	Tlbl,	Tglo,	Ttyp,	Tstr, 	Tplus,	Teq,	Tcomma,	Tlparen,	Trparen,	Tlbrace,	Trbrace,	Tnl,	Tdots,	Teof, 	Ntok}; static char *kwmap[Ntok] = {	[Tloadw] = "loadw",	[Tloadl] = "loadl",	[Tloads] = "loads",	[Tloadd] = "loadd",	[Talloc1] = "alloc1",	[Talloc2] = "alloc2",	[Tblit] = "blit",	[Tcall] = "call",	[Tenv] = "env",	[Tphi] = "phi",	[Tjmp] = "jmp",	[Tjnz] = "jnz",	[Tret] = "ret",	[Thlt] = "hlt",	[Texport] = "export",	[Tthread] = "thread",	[Tfunc] = "function",	[Ttype] = "type",	[Tdata] = "data",	[Tsection] = "section",	[Talign] = "align",	[Tsb] = "sb",	[Tub] = "ub",	[Tsh] = "sh",	[Tuh] = "uh",	[Tb] = "b",	[Th] = "h",	[Tw] = "w",	[Tl] = "l",	[Ts] = "s",	[Td] = "d",	[Tz] = "z",	[Tdots] = "...",}; enum {	NPred = 63, 	TMask = 16383, /* for temps hash */	BMask = 8191, /* for blocks hash */ 	K = 9583425, /* found using tools/lexh.c */	M = 23,}; static uchar lexh[1 << (32-M)];static FILE *inf;static char *inpath;static int thead;static struct {	char chr;	double fltd;	float flts;	int64_t num;	char *str;} tokval;static int lnum; static Fn *curf;static int tmph[TMask+1];static Phi **plink;static Blk *curb;static Blk **blink;static Blk *blkh[BMask+1];static int nblk;static int rcls;static uint ntyp; voiderr(char *s, ...){	va_list ap; 	va_start(ap, s);	fprintf(stderr, "qbe:%s:%d: ", inpath, lnum);	vfprintf(stderr, s, ap);	fprintf(stderr, "\n");	va_end(ap);	exit(1);} static voidlexinit(void){	static int done;	int i;	long h; 	if (done)		return;	for (i=0; i<NPubOp; ++i)		if (optab[i].name)			kwmap[i] = optab[i].name;	assert(Ntok <= UCHAR_MAX);	for (i=0; i<Ntok; ++i)		if (kwmap[i]) {			h = hash(kwmap[i])*K >> M;			assert(lexh[h] == Txxx);			lexh[h] = i;		}	done = 1;} static int64_tgetint(void){	uint64_t n;	int c, m; 	n = 0;	c = fgetc(inf);	m = (c == '-');	if (m || c == '+')		c = fgetc(inf);	do {		n = 10*n + (c - '0');		c = fgetc(inf);	} while ('0' <= c && c <= '9');	ungetc(c, inf);	if (m)		n = 1 + ~n;	return *(int64_t *)&n;} static intlex(void){	static char tok[NString];	int c, i, esc;	int t; 	do		c = fgetc(inf);	while (isblank(c));	t = Txxx;	tokval.chr = c;	switch (c) {	case EOF:		return Teof;	case ',':		return Tcomma;	case '(':		return Tlparen;	case ')':		return Trparen;	case '{':		return Tlbrace;	case '}':		return Trbrace;	case '=':		return Teq;	case '+':		return Tplus;	case 's':		if (fscanf(inf, "_%f", &tokval.flts) != 1)			break;		return Tflts;	case 'd':		if (fscanf(inf, "_%lf", &tokval.fltd) != 1)			break;		return Tfltd;	case '%':		t = Ttmp;		c = fgetc(inf);		goto Alpha;	case '@':		t = Tlbl;		c = fgetc(inf);		goto Alpha;	case '$':		t = Tglo;		if ((c = fgetc(inf)) == '"')			goto Quoted;		goto Alpha;	case ':':		t = Ttyp;		c = fgetc(inf);		goto Alpha;	case '#':		while ((c=fgetc(inf)) != '\n' && c != EOF)			;		/* fall through */	case '\n':		lnum++;		return Tnl;	}	if (isdigit(c) || c == '-' || c == '+') {		ungetc(c, inf);		tokval.num = getint();		return Tint;	}	if (c == '"') {		t = Tstr;	Quoted:		tokval.str = vnew(2, 1, PFn);		tokval.str[0] = c;		esc = 0;		for (i=1;; i++) {			c = fgetc(inf);			if (c == EOF)				err("unterminated string");			vgrow(&tokval.str, i+2);			tokval.str[i] = c;			if (c == '"' && !esc) {				tokval.str[i+1] = 0;				return t;			}			esc = (c == '\\' && !esc);		}	}Alpha:	if (!isalpha(c) && c != '.' && c != '_')		err("invalid character %c (%d)", c, c);	i = 0;	do {		if (i >= NString-1)			err("identifier too long");		tok[i++] = c;		c = fgetc(inf);	} while (isalpha(c) || c == '$' || c == '.' || c == '_' || isdigit(c));	tok[i] = 0;	ungetc(c, inf);	tokval.str = tok;	if (t != Txxx) {		return t;	}	t = lexh[hash(tok)*K >> M];	if (t == Txxx || strcmp(kwmap[t], tok) != 0) {		err("unknown keyword %s", tok);		return Txxx;	}	return t;} static intpeek(void){	if (thead == Txxx)		thead = lex();	return thead;} static intnext(void){	int t; 	t = peek();	thead = Txxx;	return t;} static intnextnl(void){	int t; 	while ((t = next()) == Tnl)		;	return t;} static voidexpect(int t){	static char *ttoa[] = {		[Tlbl] = "label",		[Tcomma] = ",",		[Teq] = "=",		[Tnl] = "newline",		[Tlparen] = "(",		[Trparen] = ")",		[Tlbrace] = "{",		[Trbrace] = "}",		[Teof] = 0,	};	char buf[128], *s1, *s2;	int t1; 	t1 = next();	if (t == t1)		return;	s1 = ttoa[t] ? ttoa[t] : "??";	s2 = ttoa[t1] ? ttoa[t1] : "??";	sprintf(buf, "%s expected, got %s instead", s1, s2);	err(buf);} static Reftmpref(char *v){	int t, *h; 	h = &tmph[hash(v) & TMask];	t = *h;	if (t) {		if (strcmp(curf->tmp[t].name, v) == 0)			return TMP(t);		for (t=curf->ntmp-1; t>=Tmp0; t--)			if (strcmp(curf->tmp[t].name, v) == 0)				return TMP(t);	}	t = curf->ntmp;	*h = t;	newtmp(0, Kx, curf);	strcpy(curf->tmp[t].name, v);	return TMP(t);} static Refparseref(void){	Con c; 	memset(&c, 0, sizeof c);	switch (next()) {	default:		return R;	case Ttmp:		return tmpref(tokval.str);	case Tint:		c.type = CBits;		c.bits.i = tokval.num;		break;	case Tflts:		c.type = CBits;		c.bits.s = tokval.flts;		c.flt = 1;		break;	case Tfltd:		c.type = CBits;		c.bits.d = tokval.fltd;		c.flt = 2;		break;	case Tthread:		c.sym.type = SThr;		expect(Tglo);		/* fall through */	case Tglo:		c.type = CAddr;		c.sym.id = intern(tokval.str);		break;	}	return newcon(&c, curf);} static intfindtyp(int i){	while (--i >= 0)		if (strcmp(tokval.str, typ[i].name) == 0)			return i;	err("undefined type :%s", tokval.str);	return -1;} static intparsecls(int *tyn){	switch (next()) {	default:		err("invalid class specifier");	case Ttyp:		*tyn = findtyp(ntyp);		return Kc;	case Tsb:		return Ksb;	case Tub:		return Kub;	case Tsh:		return Ksh;	case Tuh:		return Kuh;	case Tw:		return Kw;	case Tl:		return Kl;	case Ts:		return Ks;	case Td:		return Kd;	}} static intparserefl(int arg){	int k, ty, env, hasenv, vararg;	Ref r; 	hasenv = 0;	vararg = 0;	expect(Tlparen);	while (peek() != Trparen) {		if (curi - insb >= NIns)			err("too many instructions");		if (!arg && vararg)			err("no parameters allowed after '...'");		switch (peek()) {		case Tdots:			if (vararg)				err("only one '...' allowed");			vararg = 1;			if (arg) {				memset(curi, 0, sizeof(*curi));				curi->op = Oargv;				curi++;			}			next();			goto Next;		case Tenv:

Lines 1–500 of 1409.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t