forsyth20121205-174063a80cc13 years agoHistory
1453 lines · 22.1 KB · C
RawDownload
#define Extern#include "limbo.h"#include "y.tab.h" enum{	Leof		= -1,	Linestart	= 0, 	Mlower		= 1,	Mupper		= 2,	Munder		= 4,	Malpha		= Mupper|Mlower|Munder,	Mdigit		= 8,	Msign		= 16,	Mexp		= 32,	Mhex		= 64,	Mradix		= 128, 	HashSize	= 1024,	MaxPath		= 4096}; typedef	struct Keywd	Keywd;struct	Keywd{	char	*name;	int	token;}; 	File	**files;			/* files making up the module, sorted by absolute line */	int	nfiles;static	int	lenfiles;static	int	lastfile;			/* index of last file looked up */ static	char	*incpath[MaxIncPath];static	Sym	*symbols[HashSize];static	Sym	*strings[HashSize];static	char	map[256];static	Biobuf	*bin;static	Line	linestack[MaxInclude];static	int	lineno;static	int	linepos;static	int	bstack;static	int	ineof;static	int	lasttok;static	YYSTYPE	lastyylval;static	char	srcdir[MaxPath]; static	Keywd	keywords[] ={	"adt",		Ladt,	"alt",		Lalt,	"array",	Larray,	"big",		Ltid,	"break",	Lbreak,	"byte",		Ltid,	"case",		Lcase,	"chan",		Lchan,	"con",		Lcon,	"continue",	Lcont,	"cyclic",	Lcyclic,	"do",		Ldo,	"dynamic",	Ldynamic,	"else",		Lelse,	"exception",	Lexcept,	"exit",		Lexit,	"fixed",	Lfix,	"fn",		Lfn,	"for",		Lfor,	"hd",		Lhd,	"if",		Lif,	"implement",	Limplement,	"import",	Limport,	"include",	Linclude,	"int",		Ltid,	"len",		Llen,	"list",		Llist,	"load",		Lload,	"module",	Lmodule,	"nil",		Lnil,	"of",		Lof,	"or",		Lor,	"pick",		Lpick,	"raise",	Lraise,	"raises",	Lraises,	"real",		Ltid,	"ref",		Lref,	"return",	Lreturn,	"self",		Lself,	"spawn",	Lspawn,	"string",	Ltid,	"tagof",	Ltagof,	"tl",		Ltl,	"to",		Lto,	"type",		Ltype,	"while",	Lwhile,	0,}; static	Keywd	tokwords[] ={	"&=",	Landeq,	"|=",	Loreq,	"^=",	Lxoreq,	"<<=",	Llsheq,	">>=",	Lrsheq,	"+=",	Laddeq,	"-=",	Lsubeq,	"*=",	Lmuleq,	"/=",	Ldiveq,	"%=",	Lmodeq,	"**=", Lexpeq,	":=",	Ldeclas,	"||",	Loror,	"&&",	Landand,	"::",	Lcons,	"==",	Leq,	"!=",	Lneq,	"<=",	Lleq,	">=",	Lgeq,	"<<",	Llsh,	">>",	Lrsh,	"<-",	Lcomm,	"++", Linc,	"--",	Ldec,	"->", Lmdot,	"=>", Llabs,	"**", Lexp,	"EOF",	Leof,	"eof",	Beof,	0,}; voidlexinit(void){	Keywd *k;	int i; 	for(i = 0; i < 256; i++){		if(i == '_' || i > 0xa0)			map[i] |= Munder;		if(i >= 'A' && i <= 'Z')			map[i] |= Mupper;		if(i >= 'a' && i <= 'z')			map[i] |= Mlower;		if(i >= 'A' && i <= 'F' || i >= 'a' && i <= 'f')			map[i] |= Mhex;		if(i == 'e' || i == 'E')			map[i] |= Mexp;		if(i == 'r' || i == 'R')			map[i] |= Mradix;		if(i == '-' || i == '+')			map[i] |= Msign;		if(i >= '0' && i <= '9')			map[i] |= Mdigit;	} 	memset(escmap, -1, sizeof(escmap));	escmap['\''] = '\'';	unescmap['\''] = '\'';	escmap['"'] = '"';	unescmap['"'] = '"';	escmap['\\'] = '\\';	unescmap['\\'] = '\\';	escmap['a'] = '\a';	unescmap['\a'] = 'a';	escmap['b'] = '\b';	unescmap['\b'] = 'b';	escmap['f'] = '\f';	unescmap['\f'] = 'f';	escmap['n'] = '\n';	unescmap['\n'] = 'n';	escmap['r'] = '\r';	unescmap['\r'] = 'r';	escmap['t'] = '\t';	unescmap['\t'] = 't';	escmap['v'] = '\v';	unescmap['\v'] = 'v';	escmap['0'] = '\0';	unescmap['\0'] = '0'; 	for(k = keywords; k->name != nil; k++)		enter(k->name, k->token);} intcmap(int c){	if(c<0)		return 0;	if(c<256)		return map[c];	return Mlower;} voidlexstart(char *in){	char *p; 	ineof = 0;	bstack = 0;	nfiles = 0;	lastfile = 0;	addfile(mkfile(strdup(in), 1, 0, -1, nil, 0, -1));	bin = bins[bstack];	lineno = 1;	linepos = Linestart; 	secpy(srcdir, srcdir+MaxPath, in);	p = strrchr(srcdir, '/');	if(p == nil)		srcdir[0] = '\0';	else		p[1] = '\0';} static intGetc(void){	int c; 	if(ineof)		return Beof;	c = BGETC(bin);	if(c == Beof)		ineof = 1;	linepos++;	return c;} static voidunGetc(void){	if(ineof)		return;	Bungetc(bin);	linepos--;} static intgetrune(void){	int c; 	if(ineof)		return Beof;	c = Bgetrune(bin);	if(c == Beof)		ineof = 1;	linepos++;	return c;} static voidungetrune(void){	if(ineof)		return;	Bungetrune(bin);	linepos--;} voidaddinclude(char *s){	int i; 	for(i = 0; i < MaxIncPath; i++){		if(incpath[i] == 0){			incpath[i] = s;			return;		}	}	fatal("out of include path space");} File*mkfile(char *name, int abs, int off, int in, char *act, int actoff, int sbl){	File *f; 	f = allocmem(sizeof *f);	f->name = name;	f->abs = abs;	f->off = off;	f->in = in;	f->act = act;	f->actoff = actoff;	f->sbl = sbl;	return f;} intaddfile(File *f){	if(nfiles >= lenfiles){		lenfiles = nfiles+32;		files = reallocmem(files, lenfiles*sizeof(File*));	}	files[nfiles] = f;	return nfiles++;} voidincludef(Sym *file){	Biobuf *b;	char *p, buf[MaxPath];	int i; 	linestack[bstack].line = lineno;	linestack[bstack].pos = linepos;	bstack++;	if(bstack >= MaxInclude)		fatal("%L: include file depth too great", curline());	p = "";	if(file->name[0] != '/')		p = srcdir;	seprint(buf, buf+sizeof(buf), "%s%s", p, file->name);	b = Bopen(buf, OREAD);	for(i = 0; b == nil && i < MaxIncPath && incpath[i] != nil && file->name[0] != '/'; i++){		seprint(buf, buf+sizeof(buf), "%s/%s", incpath[i], file->name);		b = Bopen(buf, OREAD);	}	bins[bstack] = b;	if(bins[bstack] == nil){		yyerror("can't include %s: %r", file->name);		bstack--;	}else{		addfile(mkfile(strdup(buf), lineno+1, -lineno, lineno, nil, 0, -1));		lineno++;		linepos = Linestart;	}	bin = bins[bstack];} /* * we hit eof in the current file * revert to the file which included it. */static voidpopinclude(void){	Fline fl;	File *f;	int oline, opos, ln; 	ineof = 0;	bstack--;	bin = bins[bstack];	oline = linestack[bstack].line;	opos = linestack[bstack].pos;	fl = fline(oline);	f =  fl.file;	ln = fl.line;	lineno++;	linepos = opos;	addfile(mkfile(f->name, lineno, ln-lineno, f->in, f->act, f->actoff, -1));} /* * convert an absolute Line into a file and line within the file */Flinefline(int absline){	Fline fl;	int l, r, m, s; 	if(absline < files[lastfile]->abs	|| lastfile+1 < nfiles && absline >= files[lastfile+1]->abs){		lastfile = 0;		l = 0;		r = nfiles - 1;		while(l <= r){			m = (r + l) / 2;			s = files[m]->abs;			if(s <= absline){				l = m + 1;				lastfile = m;			}else				r = m - 1;		}	} 	fl.file = files[lastfile];	fl.line = absline + files[lastfile]->off;	return fl;} /* * read a comment */static intlexcom(void){	File *f;	char buf[StrSize], *s, *t, *act;	int i, n, c, actline; 	i = 0;	while((c = Getc()) != '\n'){		if(c == Beof)			return -1;		if(i < sizeof(buf)-1)			buf[i++] = c;	}	buf[i] = 0; 	lineno++;	linepos = Linestart; 	if(strncmp(buf, "line ", 5) != 0 && strncmp(buf, "line\t", 5) != 0)		return 0;	for(s = buf+5; *s == ' ' || *s == '\t'; s++)		;	if(!(cmap(*s) & Mdigit))		return 0;	n = 0;	for(; cmap(c = *s) & Mdigit; s++)		n = n * 10 + c - '0';	for(; *s == ' ' || *s == '\t'; s++)		;	if(*s != '"')		return 0;	s++;	t = strchr(s, '"');	if(t == nil || t[1] != '\0')		return 0;	*t = '\0'; 	f = files[nfiles - 1];	if(n == f->off+lineno && strcmp(s, f->name) == 0)		return 1;	act = f->name;	actline = lineno + f->off;	if(f->act != nil){		actline += f->actoff;		act = f->act;	}	addfile(mkfile(strdup(s), lineno, n-lineno, f->in, act, actline - n, -1)); 	return 1;} Linecurline(void){	Line line; 	line.line = lineno;	line.pos = linepos;	return line;} intlineconv(Fmt *f){	Fline fl;	File *file;	Line inl, line;	char buf[StrSize], *s; 	line = va_arg(f->args, Line); 	if(line.line < 0)		return fmtstrcpy(f, "<noline>");	fl = fline(line.line);	file = fl.file; 	s = seprint(buf, buf+sizeof(buf), "%s:%d", file->name, fl.line);	if(file->act != nil)		s = seprint(s, buf+sizeof(buf), " [ %s:%d ]", file->act, file->actoff+fl.line);	if(file->in >= 0){		inl.line = file->in;		inl.pos = 0;		seprint(s, buf+sizeof(buf), ": %L", inl);	}	return fmtstrcpy(f, buf);} static char*posconv(char *s, char *e, Line line){	Fline fl; 	if(line.line < 0)		return secpy(s, e, "nopos"); 	fl = fline(line.line);	return seprint(s, e, "%s:%d.%d", fl.file->name, fl.line, line.pos);} intsrcconv(Fmt *f){	Src src;

Lines 1–500 of 1453.