1970 lines · 31.4 KB · Text
RawDownload
%{include "limbo.m"; %} %module Limbo{	init:		fn(ctxt: ref Draw->Context, 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);	};} %{	#	# 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 symbols%} %type	<ty>	type fnarg fnargret fnargretp adtk fixtype iditype dotiditype%type	<ids>	ids rids nids nrids tuplist forms ftypes ftype		bclab bctarg ptags rptags polydec%type	<node>	zexp exp monexp term elist zelist celist		idatom idterms idterm idlist		initlist elemlist elem qual		decl topdecls topdecl fndef fbody stmt stmts qstmts qbodies cqstmts cqbodies		mdecl adtdecl mfield mfields field fields fnname		pstmts pbodies pqual pfields pfbody pdecl dfield dfields		eqstmts eqbodies idexc edecl raises tpoly tpolys texp export exportlist forpoly%type	<types>	types %right	<tok.src>	'=' Landeq Loreq Lxoreq Llsheq Lrsheq			Laddeq Lsubeq Lmuleq Ldiveq Lmodeq Lexpeq Ldeclas%left	<tok.src>	Lload%left	<tok.src>	Loror%left	<tok.src>	Landand%right	<tok.src>	Lcons%left	<tok.src>	'|'%left	<tok.src>	'^'%left	<tok.src>	'&'%left	<tok.src>	Leq Lneq%left	<tok.src>	'<' '>' Lleq Lgeq%left	<tok.src>	Llsh Lrsh%left	<tok.src>	'+' '-'%left	<tok.src>	'*' '/' '%'%right <tok.src> Lexp%right	<tok.src>	Lcomm %left	<tok.src>	'(' ')' '[' ']' Linc Ldec Lof Lref%right	<tok.src>	Lif Lelse Lfn ':' Lexcept Lraises%left	<tok.src>	Lmdot%left	<tok.src>	'.' %left	<tok.src>	Lto%left	<tok.src>	Lor  %nonassoc	<tok.v.rval>	Lrconst%nonassoc	<tok.v.ival>	Lconst%nonassoc	<tok.v.idval>	Lid Ltid Lsconst%nonassoc	<tok.src>	Llabs Lnil			'!' '~' Llen Lhd Ltl Ltagof			'{' '}' ';'			Limplement Limport Linclude			Lcon Ltype Lmodule Lcyclic			Ladt Larray Llist Lchan Lself			Ldo Lwhile Lfor Lbreak			Lalt Lcase Lpick Lcont			Lreturn Lexit Lspawn Lraise Lfix			Ldynamic%%prog	: Limplement ids ';'	{		impmods = $2;	} topdecls	{		tree = rotater($5);	}	| topdecls	{		impmods = nil;		tree = rotater($1);	}	; topdecls: topdecl	| topdecls topdecl	{		if($1 == nil)			$$ = $2;		else if($2 == nil)			$$ = $1;		else			$$ = mkbin(Oseq, $1, $2);	}	; topdecl	: error ';'	{		$$ = nil;	}	| decl	| fndef	| adtdecl ';'	| mdecl ';'	| idatom '=' exp ';'	{		$$ = mkbin(Oas, $1, $3);	}	| idterm '=' exp ';'	{		$$ = mkbin(Oas, $1, $3);	}	| idatom Ldeclas exp ';'	{		$$ = mkbin(Odas, $1, $3);	}	| idterm Ldeclas exp ';'	{		$$ = mkbin(Odas, $1, $3);	}	| idterms ':' type ';'	{		yyerror("illegal declaration");		$$ = nil;	}	| idterms ':' type '=' exp ';'	{		yyerror("illegal declaration");		$$ = nil;	}	; idterms : idterm	| idterms ',' idterm	{		$$ = mkbin(Oseq, $1, $3);	}	; decl	: Linclude Lsconst ';'	{		includef($2);		$$ = nil;	}	| ids ':' Ltype type ';'	{		$$ = typedecl($1, $4);	}	| ids ':' Limport exp ';'	{		$$ = importdecl($4, $1);		$$.src.start = $1.src.start;		$$.src.stop = $5.stop;	}	| ids ':' type ';'	{		$$ = vardecl($1, $3);	}	| ids ':' type '=' exp ';'	{		$$ = mkbin(Ovardecli, vardecl($1, $3), varinit($1, $5));	}	| ids ':' Lcon exp ';'	{		$$ = condecl($1, $4);	}	| edecl	; edecl	: ids ':' Lexcept ';'	{		$$ = exdecl($1, nil);	}	| ids ':' Lexcept '(' tuplist ')' ';'	{		$$ = exdecl($1, revids($5));	}	; mdecl	: ids ':' Lmodule '{' mfields '}'	{		$1.src.stop = $6.stop;		$$ = moddecl($1, rotater($5));	}	; mfields	:	{		$$ = nil;	}	| mfields mfield	{		if($1 == nil)			$$ = $2;		else if($2 == nil)			$$ = $1;		else			$$ = mkn(Oseq, $1, $2);	}	| error	{		$$ = nil;	}	; mfield	: ids ':' type ';'	{		$$ = fielddecl(Dglobal, typeids($1, $3));	}	| adtdecl ';'	| ids ':' Ltype type ';'	{		$$ = typedecl($1, $4);	}	| ids ':' Lcon exp ';'	{		$$ = condecl($1, $4);	}	| edecl	; adtdecl	: ids ':' Ladt polydec '{' fields '}' forpoly	{		$1.src.stop = $7.stop;		$$ = adtdecl($1, rotater($6));		$$.ty.polys = $4;		$$.ty.val = rotater($8);	}	| ids ':' Ladt polydec Lfor '{' tpolys '}' '{' fields '}'	{		$1.src.stop = $11.stop;		$$ = adtdecl($1, rotater($10));		$$.ty.polys = $4;		$$.ty.val = rotater($7);	}	; forpoly	:	{		$$ = nil;	}	| Lfor '{' tpolys '}'	{		$$ = $3;	}	; fields	:	{		$$ = nil;	}	| fields field	{		if($1 == nil)			$$ = $2;		else if($2 == nil)			$$ = $1;		else			$$ = mkn(Oseq, $1, $2);	}	| error	{		$$ = nil;	}	; field	: dfield	| pdecl	| ids ':' Lcon exp ';'	{		$$ = condecl($1, $4);	}	; dfields	:	{		$$ = nil;	}	| dfields dfield	{		if($1 == nil)			$$ = $2;		else if($2 == nil)			$$ = $1;		else			$$ = mkn(Oseq, $1, $2);	}	; dfield	: ids ':' Lcyclic type ';'	{		for(d := $1; d != nil; d = d.next)			d.cyc = byte 1;		$$ = fielddecl(Dfield, typeids($1, $4));	}	| ids ':' type ';'	{		$$ = fielddecl(Dfield, typeids($1, $3));	}	; pdecl	: Lpick '{' pfields '}'	{		$$ = $3;	}	; pfields	: pfbody dfields	{		$1.right.right = $2;		$$ = $1;	}	| pfbody error	{		$$ = nil;	}	| error	{		$$ = nil;	}	; pfbody	: ptags Llabs	{		$$ = mkn(Opickdecl, nil, mkn(Oseq, fielddecl(Dtag, $1), nil));		typeids($1, mktype($1.src.start, $1.src.stop, Tadtpick, nil, nil));	}	| pfbody dfields ptags Llabs	{		$1.right.right = $2;		$$ = mkn(Opickdecl, $1, mkn(Oseq, fielddecl(Dtag, $3), nil));		typeids($3, mktype($3.src.start, $3.src.stop, Tadtpick, nil, nil));	}	| pfbody error ptags Llabs	{		$$ = mkn(Opickdecl, nil, mkn(Oseq, fielddecl(Dtag, $3), nil));		typeids($3, mktype($3.src.start, $3.src.stop, Tadtpick, nil, nil));	}	; ptags	: rptags	{		$$ = revids($1);	}	; rptags	: Lid	{		$$ = mkids($<tok.src>1, $1, nil, nil);	}	| rptags Lor Lid	{		$$ = mkids($<tok.src>3, $3, nil, $1);	}	; ids	: rids	{		$$ = revids($1);	}	; rids	: Lid	{		$$ = mkids($<tok.src>1, $1, nil, nil);	}	| rids ',' Lid	{		$$ = mkids($<tok.src>3, $3, nil, $1);	}	; fixtype	: Lfix '(' exp ',' exp ')'	{		$$ = mktype($1.start, $6.stop, Tfix, nil, nil);		$$.val = mkbin(Oseq, $3, $5);	}	|	Lfix '(' exp ')'	{		$$ = mktype($1.start, $4.stop, Tfix, nil, nil);		$$.val = $3;	}	; types	: type	{		$$ = addtype($1, nil);	}	|	Lcyclic type	{		$$ = addtype($2, nil);		$2.flags |= CYCLIC;	}	| types ',' type	{		$$ = addtype($3, $1);	}	| types ',' Lcyclic type	{		$$ = addtype($4, $1);		$4.flags |= CYCLIC;	}	; type	: Ltid	{		$$ = mkidtype($<tok.src>1, $1);	}	| iditype	{		$$ = $1;	}	| dotiditype	{		$$ = $1;	}	| type Lmdot Lid	{		$$ = mkarrowtype($1.src.start, $<tok.src>3.stop, $1, $3);	}

Lines 1–500 of 1970.