1178 lines · 19.4 KB · Brainfuck
RawDownload
Leof:		con -1;Linestart:	con 0; Mlower,Mupper,Munder,Mdigit,Msign,Mexp,Mhex,Mradix:		con byte 1 << iota;Malpha:		con Mupper|Mlower|Munder; HashSize:	con 1024; Keywd: adt{	name:	string;	token:	int;}; ## internals#savec:		int;files:		array of ref File;			# files making up the module, sorted by absolute linenfiles:		int;lastfile := 0;						# index of last file looked upincpath :=	array[MaxIncPath] of string;symbols :=	array[HashSize] of ref Sym;strings :=	array[HashSize] of ref Sym;map :=		array[256] of byte;bins :=		array [MaxInclude] of ref Iobuf;bin:		ref Iobuf;linestack :=	array[MaxInclude] of (int, int);lineno:		int;linepos:	int;bstack:		int;lasttok:	int;lastyylval:	YYSTYPE;dowarn:		int;maxerr:		int;dosym:		int;toterrors:	int;fabort:		int;srcdir:		string;outfile:	string;stderr:		ref Sys->FD;dontinline:	int; escmap :=	array[256] of{	'\'' =>		'\'',	'"' =>		'"',	'\\' =>		'\\',	'a' =>		'\a',	'b' =>		'\b',	'f' =>			'\f',	'n' =>		'\n',	'r' =>		'\r',	't' =>		'\t',	'v' =>		'\v',	'0' =>		'\u0000', 	* =>		-1};unescmap :=	array[256] of {	'\'' =>		'\'',	'"' =>		'"',	'\\' =>		'\\',	'\a' =>		'a',	'\b' =>		'b',	'\f' =>		'f',	'\n' =>		'n',	'\r' =>		'r',	'\t' =>		't',	'\v' =>		'v',	'\u0000' =>	'0', 	* =>		0}; keywords := array [] of{	Keywd("adt",		Ladt),	Keywd("alt",		Lalt),	Keywd("array",		Larray),	Keywd("big",		Ltid),	Keywd("break",		Lbreak),	Keywd("byte",		Ltid),	Keywd("case",		Lcase),	Keywd("chan",		Lchan),	Keywd("con",		Lcon),	Keywd("continue",	Lcont),	Keywd("cyclic",		Lcyclic),	Keywd("do",		Ldo),	Keywd("dynamic",	Ldynamic),	Keywd("else",		Lelse),	Keywd("exception",	Lexcept),	Keywd("exit",		Lexit),	Keywd("fixed",	Lfix),	Keywd("fn",		Lfn),	Keywd("for",		Lfor),	Keywd("hd",		Lhd),	Keywd("if",		Lif),	Keywd("implement",	Limplement),	Keywd("import",		Limport),	Keywd("include",	Linclude),	Keywd("int",		Ltid),	Keywd("len",		Llen),	Keywd("list",		Llist),	Keywd("load",		Lload),	Keywd("module",		Lmodule),	Keywd("nil",		Lnil),	Keywd("of",		Lof),	Keywd("or",		Lor),	Keywd("pick",		Lpick),	Keywd("raise",	Lraise),	Keywd("raises",	Lraises),	Keywd("real",		Ltid),	Keywd("ref",		Lref),	Keywd("return",		Lreturn),	Keywd("self",		Lself),	Keywd("spawn",		Lspawn),	Keywd("string",		Ltid),	Keywd("tagof",		Ltagof),	Keywd("tl",		Ltl),	Keywd("to",		Lto),	Keywd("type",		Ltype),	Keywd("while",		Lwhile),}; tokwords := array[] of{	Keywd("&=",	Landeq),	Keywd("|=",	Loreq),	Keywd("^=",	Lxoreq),	Keywd("<<=",	Llsheq),	Keywd(">>=",	Lrsheq),	Keywd("+=",	Laddeq),	Keywd("-=",	Lsubeq),	Keywd("*=",	Lmuleq),	Keywd("/=",	Ldiveq),	Keywd("%=",	Lmodeq),	Keywd("**=",	Lexpeq),	Keywd(":=",	Ldeclas),	Keywd("||",	Loror),	Keywd("&&",	Landand),	Keywd("::",	Lcons),	Keywd("==",	Leq),	Keywd("!=",	Lneq),	Keywd("<=",	Lleq),	Keywd(">=",	Lgeq),	Keywd("<<",	Llsh),	Keywd(">>",	Lrsh),	Keywd("<-",	Lcomm),	Keywd("++", 	Linc),	Keywd("--",	Ldec),	Keywd("->", 	Lmdot),	Keywd("=>", 	Llabs),	Keywd("**",	Lexp),	Keywd("EOF",	Leof),}; lexinit(){	for(i := 0; i < 256; i++){		map[i] = byte 0;		if(i == '_' || i > 16ra0)			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;	} 	for(i = 0; i < len keywords; i++)		enter(keywords[i].name, keywords[i].token);} cmap(c: int): byte{	if(c<0)		return byte 0;	if(c<256)		return map[c];	return Mlower;} lexstart(in: string){	savec = 0;	bstack = 0;	nfiles = 0;	addfile(ref File(in, 1, 0, -1, nil, 0, -1));	bin = bins[bstack];	lineno = 1;	linepos = Linestart; 	(srcdir, nil) = str->splitr(in, "/");} getc(): int{	if(c := savec){		if(savec >= 0){			linepos++;			savec = 0;		}		return c;	}	c = bin.getc();	if(c < 0){		savec = -1;		return savec;	}	linepos++;	return c;} ## dumps '\u0000' chararcters#ungetc(c: int){	if(c > 0)		linepos--;	savec = c;} addinclude(s: string){	for(i := 0; i < MaxIncPath; i++){		if(incpath[i] == nil){			incpath[i] = s;			return;		}	}	fatal("out of include path space");} addfile(f: ref File): int{	if(lastfile >= nfiles)		lastfile = 0;	if(nfiles >= len files){		nf := array[nfiles+32] of ref File;		nf[0:] = files;		files = nf;	}	files[nfiles] = f;	return nfiles++;} ## include a new file#includef(file: ref Sym){	linestack[bstack] = (lineno, linepos);	bstack++;	if(bstack >= MaxInclude)		fatal(lineconv(lineno<<PosBits)+": include file depth too great");	buf := file.name;	if(buf[0] != '/')		buf = srcdir+buf;	b := bufio->open(buf, Bufio->OREAD);	for(i := 0; b == nil && i < MaxIncPath && incpath[i] != nil && file.name[0] != '/'; i++){		buf = incpath[i] + "/" + file.name;		b = bufio->open(buf, Bufio->OREAD);	}	bins[bstack] = b;	if(bins[bstack] == nil){		yyerror("can't include "+file.name+": "+sprint("%r"));		bstack--;	}else{		addfile(ref File(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.#popinclude(){	savec = 0;	bstack--;	bin = bins[bstack];	(oline, opos) := linestack[bstack];	(f, ln) := fline(oline);	lineno++;	linepos = opos;	addfile(ref File(f.name, lineno, ln-lineno, f.in, f.act, f.actoff, -1));} ## convert an absolute Line into a file and line within the file#fline(absline: int): (ref File, int){	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;		}	}	return (files[lastfile], absline + files[lastfile].off);} ## read a comment; process #line file renamings#lexcom(): int{	i := 0;	buf := "";	while((c := getc()) != '\n'){		if(c == Bufio->EOF)			return -1;		buf[i++] = c;	} 	lineno++;	linepos = Linestart; 	if(len buf < 6	|| buf[len buf - 1] != '"'	|| buf[:5] != "line " && buf[:5] != "line\t")		return 0;	for(s := 5; buf[s] == ' ' || buf[s] == '\t'; s++)		;	if((cmap(buf[s]) & Mdigit) == byte 0)		return 0;	n := 0;	for(; (cmap(c = buf[s]) & Mdigit) != byte 0; s++)		n = n * 10 + c - '0';	for(; buf[s] == ' ' || buf[s] == '\t'; s++)		;	if(buf[s++] != '"')		return 0;	buf = buf[s:len buf - 1];	f := files[nfiles - 1];	if(n == f.off+lineno && buf == f.name)		return 1;	act := f.name;	actline := lineno + f.off;	if(f.act != nil){		actline += f.actoff;		act = f.act;	}	addfile(ref File(buf, lineno, n-lineno, f.in, act, actline - n, -1)); 	return 1;} curline(): Line{	return (lineno << PosBits) | (linepos & PosMask);} lineconv(line: Line): string{	line >>= PosBits;	if(line < 0)		return "<noline>";	(f, ln) := fline(line);	s := "";	if(f.in >= 0){		s = ": " + lineconv(f.in << PosBits);	}	if(f.act != nil)		s = " [ " + f.act + ":" + string(f.actoff+ln) + " ]" + s;	return f.name + ":" + string ln + s;} posconv(s: Line): string{	if(s < 0)		return "nopos";	spos := s & PosMask;	s >>= PosBits;	(f, ln) := fline(s);	return f.name + ":" + string ln + "." + string spos;} srcconv(src: Src): string{	s := posconv(src.start);	s[len s] = ',';	s += posconv(src.stop);	return s;} lexid(c: int): int{	id := "";	i := 0;	for(;;){		if(i < StrSize)			id[i++] = c;		c = getc();		if(c == Bufio->EOF		|| (cmap(c) & (Malpha|Mdigit)) == byte 0){			ungetc(c);			break;		}	}	sym := enter(id, Lid);	t := sym.token;	if(t == Lid || t == Ltid)		yyctxt.lval.tok.v.idval = sym;	return t;} maxfast := array[37] of{	2 =>	31,	4 =>	15,	8 =>	10,	10 =>	9,	16 =>	7,	32 =>	6,	* =>	0,}; strtoi(t: string, bbase: big): big{	#	# do the first part in ints	#	v := 0;	bv: big;	base := int bbase;	n := maxfast[base]; 	neg := 0;	i := 0;	if(i < len t && t[i] == '-'){		neg = 1;		i++;	}else if(i < len t && t[i] == '+')		i++; 	for(; i < len t; i++){		c := t[i];		if(c >= '0' && c <= '9')			c -= '0';		else if(c >= 'a' && c <= 'z')			c -= 'a' - 10;		else			c -= 'A' - 10;		if(c >= base){			yyerror("digit '"+t[i:i+1]+"' is not radix "+string base);			return big -1;		}		if(i < n)			v = v * base + c;		else{			if(i == n)				bv = big v;			bv = bv * bbase + big c;		}	}	if(i <= n)		bv = big v;	if(neg)		return -bv;	return bv;} digit(c: int, base: int): int{	ck: byte;	cc: int; 	cc = c;

Lines 1–500 of 1178.