3096 lines · 80.8 KB · Brainfuck
RawDownload
implement Limbo; #line	2	"limbo.y"include "limbo.m"; Limbo: module { 	init:		fn(argv: list of string); 	YYSTYPE: adt{		tok:	Tok;		ids:	ref Decl;		node:	ref Node;		ty:	ref Type;		types:	ref Typelist;	}; 	YYLEX: adt {		lval: YYSTYPE;		lex: fn(nil: self ref YYLEX): int;		error: fn(nil: self ref YYLEX, err: string);	};Landeq: con	57346;Loreq: con	57347;Lxoreq: con	57348;Llsheq: con	57349;Lrsheq: con	57350;Laddeq: con	57351;Lsubeq: con	57352;Lmuleq: con	57353;Ldiveq: con	57354;Lmodeq: con	57355;Lexpeq: con	57356;Ldeclas: con	57357;Lload: con	57358;Loror: con	57359;Landand: con	57360;Lcons: con	57361;Leq: con	57362;Lneq: con	57363;Lleq: con	57364;Lgeq: con	57365;Llsh: con	57366;Lrsh: con	57367;Lexp: con	57368;Lcomm: con	57369;Linc: con	57370;Ldec: con	57371;Lof: con	57372;Lref: con	57373;Lif: con	57374;Lelse: con	57375;Lfn: con	57376;Lexcept: con	57377;Lraises: con	57378;Lmdot: con	57379;Lto: con	57380;Lor: con	57381;Lrconst: con	57382;Lconst: con	57383;Lid: con	57384;Ltid: con	57385;Lsconst: con	57386;Llabs: con	57387;Lnil: con	57388;Llen: con	57389;Lhd: con	57390;Ltl: con	57391;Ltagof: con	57392;Limplement: con	57393;Limport: con	57394;Linclude: con	57395;Lcon: con	57396;Ltype: con	57397;Lmodule: con	57398;Lcyclic: con	57399;Ladt: con	57400;Larray: con	57401;Llist: con	57402;Lchan: con	57403;Lself: con	57404;Ldo: con	57405;Lwhile: con	57406;Lfor: con	57407;Lbreak: con	57408;Lalt: con	57409;Lcase: con	57410;Lpick: con	57411;Lcont: con	57412;Lreturn: con	57413;Lexit: con	57414;Lspawn: con	57415;Lraise: con	57416;Lfix: con	57417;Ldynamic: con	57418; }; #line	27	"limbo.y"	#	# lex.b	#	signdump:	string;			# name of function for sig debugging	superwarn:	int;	debug:		array of int;	noline:		Line;	nosrc:		Src;	arrayz:		int;	oldcycles:	int;	emitcode:	string;			# emit stub routines for system module functions	emitdyn: int;				# emit as above but for dynamic modules	emitsbl:	string;			# emit symbol file for sysm modules	emitstub:	int;			# emit type and call frames for system modules	emittab:	string;			# emit table of runtime functions for this module	errors:		int;	mustcompile:	int;	dontcompile:	int;	asmsym:		int;			# generate symbols in assembly language?	bout:		ref Bufio->Iobuf;	# output file	bsym:		ref Bufio->Iobuf;	# symbol output file; nil => no sym out	gendis:		int;			# generate dis or asm?	fixss:		int;	newfnptr:	int;		# ISELF and -ve indices	optims: int; 	#	# decls.b	#	scope:		int;	# impmod:		ref Sym;		# name of implementation module	impmods:		ref Decl;		# name of implementation module(s)	nildecl:	ref Decl;		# declaration for limbo's nil	selfdecl:	ref Decl;		# declaration for limbo's self 	#	# types.b	#	tany:		ref Type;	tbig:		ref Type;	tbyte:		ref Type;	terror:		ref Type;	tint:		ref Type;	tnone:		ref Type;	treal:		ref Type;	tstring:	ref Type;	texception:	ref Type;	tunknown:	ref Type;	tfnptr:	ref Type;	rtexception:	ref Type;	descriptors:	ref Desc;		# list of all possible descriptors	tattr:		array of Tattr; 	#	# nodes.b	#	opcommute:	array of int;	oprelinvert:	array of int;	isused:		array of int;	casttab:	array of array of int;	# instruction to cast from [1] to [2] 	nfns:		int;			# functions defined	nfnexp:		int;	fns:		array of ref Decl;	# decls for fns defined	tree:		ref Node;		# root of parse tree 	parset:		int;			# time to parse	checkt:		int;			# time to typecheck	gent:		int;			# time to generate code	writet:		int;			# time to write out code	symt:		int;			# time to write out symbolsYYEOFCODE: con 1;YYERRCODE: con 2;YYMAXDEPTH: con 200; #line	1632	"limbo.y"  sys:	Sys;	print, fprint, sprint: import sys; bufio:	Bufio;	Iobuf: import bufio; str:		String; math:	Math;	import_real, export_real, isnan: import math; yyctxt: ref YYLEX; canonnan: real; debug	= array[256] of {* => 0}; noline	= -1;nosrc	= Src(-1, -1); infile:	string; # front endinclude "arg.m";include "lex.b";include "types.b";include "nodes.b";include "decls.b"; include "typecheck.b"; # back endinclude "gen.b";include "ecom.b";include "asm.b";include "dis.b";include "sbl.b";include "stubs.b";include "com.b";include "optim.b"; init(argv: list of string){	s: string; 	sys = load Sys Sys->PATH;	math = load Math Math->PATH;	bufio = load Bufio Bufio->PATH;	if(bufio == nil){		sys->print("can't load %s: %r\n", Bufio->PATH);		raise("fail:bad module");	}	str = load String String->PATH;	if(str == nil){		sys->print("can't load %s: %r\n", String->PATH);		raise("fail:bad module");	} 	stderr = sys->fildes(2);	yyctxt = ref YYLEX; 	math->FPcontrol(0, Math->INVAL|Math->ZDIV|Math->OVFL|Math->UNFL|Math->INEX);	na := array[1] of {0.};	import_real(array[8] of {byte 16r7f, * => byte 16rff}, na);	canonnan = na[0];	if(!isnan(canonnan))		fatal("bad canonical NaN"); 	lexinit();	typeinit();	optabinit(); 	gendis = 1;	asmsym = 0;	maxerr = 20;	ofile := "";	ext := ""; 	arg := Arg.init(argv);	while(c := arg.opt()){		case c{		'Y' =>			emitsbl = arg.arg();			if(emitsbl == nil)				usage();		'C' =>			dontcompile = 1;		'D' =>			#			# debug flags:			#			# a	alt compilation			# A	array constructor compilation			# b	boolean and branch compilation			# c	case compilation			# d	function declaration			# D	descriptor generation			# e	expression compilation			# E	addressable expression compilation			# f	print arguments for compiled functions			# F	constant folding			# g	print out globals			# m	module declaration and type checking			# n	nil references			# s	print sizes of output file sections			# S	type signing			# t	type checking function bodies			# T	timing			# v	global var and constant compilation			# x	adt verification			# Y	tuple compilation			# z Z	bug fixes			#			s = arg.arg();			for(i := 0; i < len s; i++){				c = s[i];				if(c < len debug)					debug[c] = 1;			}		'I' =>			s = arg.arg();			if(s == "")				usage();			addinclude(s);		'G' =>			asmsym = 1;		'S' =>			gendis = 0;		'a' =>			emitstub = 1;		'A' =>			emitstub = emitdyn = 1;		'c' =>			mustcompile = 1;		'e' =>			maxerr = 1000;		'f' =>			fabort = 1;		'F' =>			newfnptr = 1;		'g' =>			dosym = 1;		'i' =>			dontinline = 1;		'o' =>			ofile = arg.arg();		'O' =>			optims = 1;		's' =>			s = arg.arg();			if(s != nil)				fixss = int s;		't' =>			emittab = arg.arg();			if(emittab == nil)				usage();		'T' =>			emitcode = arg.arg();			if(emitcode == nil)				usage();		'd' =>			emitcode = arg.arg();			if(emitcode == nil)				usage();			emitdyn = 1;		'w' =>			superwarn = dowarn;			dowarn = 1;		'x' =>			ext = arg.arg();		'X' =>			signdump = arg.arg();		'z' =>			arrayz = 1;		'y' =>			oldcycles = 1;		* =>			usage();		}	} 	addinclude("/module"); 	argv = arg.argv;	arg = nil; 	if(argv == nil){		usage();	}else if(ofile != nil){		if(len argv != 1)			usage();		translate(hd argv, ofile, mkfileext(ofile, ".dis", ".sbl"));	}else{		pr := len argv != 1;		if(ext == ""){			ext = ".s";			if(gendis)				ext = ".dis";		}		for(; argv != nil; argv = tl argv){			file := hd argv;			(nil, s) = str->splitr(file, "/");			if(pr)				print("%s:\n", s);			out := mkfileext(s, ".b", ext);			translate(file, out, mkfileext(out, ext, ".sbl"));		}	}	if (toterrors > 0)		raise("fail:errors");} usage(){	fprint(stderr, "usage: limbo [-GSagwe] [-I incdir] [-o outfile] [-{T|t|d} module] [-D debug] file ...\n");	raise("fail:usage");} mkfileext(file, oldext, ext: string): string{	n := len file;	n2 := len oldext;	if(n >= n2 && file[n-n2:] == oldext)		file = file[:n-n2];	return file + ext;} translate(in, out, dbg: string){	infile = in;	outfile = out;	errors = 0;	bins[0] = bufio->open(in, Bufio->OREAD);	if(bins[0] == nil){		fprint(stderr, "can't open %s: %r\n", in);		toterrors++;		return;	}	doemit := emitcode != "" || emitstub || emittab != "" || emitsbl != "";	if(!doemit){		bout = bufio->create(out, Bufio->OWRITE, 8r666);		if(bout == nil){			fprint(stderr, "can't open %s: %r\n", out);			toterrors++;			bins[0].close();			return;		}		if(dosym){			bsym = bufio->create(dbg, Bufio->OWRITE, 8r666);			if(bsym == nil)				fprint(stderr, "can't open %s: %r\n", dbg);		}	} 	lexstart(in); 	popscopes();	typestart();	declstart();	nfnexp = 0; 	parset = sys->millisec();	yyparse(yyctxt);	parset = sys->millisec() - parset; 	checkt = sys->millisec();	entry := typecheck(!doemit);	checkt = sys->millisec() - checkt; 	modcom(entry); 	fns = nil;	nfns = 0;	descriptors = nil; 	if(debug['T'])		print("times: parse=%d type=%d: gen=%d write=%d symbols=%d\n",			parset, checkt, gent, writet, symt); 	if(bout != nil)		bout.close();	if(bsym != nil)		bsym.close();	toterrors += errors;	if(errors && bout != nil)		sys->remove(out);	if(errors && bsym != nil)		sys->remove(dbg);} pwd(): string{	workdir := load Workdir Workdir->PATH;	if(workdir == nil)		cd := "/";	else		cd = workdir->init();	# sys->print("pwd: %s\n", cd);	return cd;} cleanname(s: string): string{	ls, path: list of string; 	if(s == nil)		return nil;	if(s[0] != '/' && s[0] != '\\')		(nil, ls) = sys->tokenize(pwd(), "/\\");	for( ; ls != nil; ls = tl ls)		path = hd ls :: path;	(nil, ls) = sys->tokenize(s, "/\\");	for( ; ls != nil; ls = tl ls){		n := hd ls;		if(n == ".")			;		else if (n == ".."){			if(path != nil)				path = tl path;		}		else			path = n :: path;	}

Lines 1–500 of 3096.