Charles.Forsyth20060303-partialeea662d19 years agoHistory
334 lines · 8.8 KB · Objective-C
RawDownload
ESHostobj: module{	#	# extensible interface for adding host objects	#	# any implementation must obey the rules of the interpreter.	# it is an error to return bogus values, and may cause	# the interpreter to crash.	#	# get/put must return/set the value of property in o	#	# canput and hasproperty return es->true or es->false	#	# defaultval must return a primitive (non-object) value.	#	this means it can't return a String object, etc.	#	# call gets the caller's execution context in ex.	# the new this value is passed as an argument,	# but no new scopechain is allocated	# it returns a reference, which is typically just a value	#	# construct should make up a new object	#	get:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	put:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string, val: ref Ecmascript->Val);	canput:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	hasproperty:	fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	delete:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string);	defaultval:	fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, tyhint: int): ref Ecmascript->Val;	call:		fn(ex: ref Ecmascript->Exec, func, this: ref Ecmascript->Obj, args: array of ref Ecmascript->Val, eval: int): ref Ecmascript->Ref;	construct:	fn(ex: ref Ecmascript->Exec, func: ref Ecmascript->Obj, args: array of ref Ecmascript->Val): ref Ecmascript->Obj;}; ## calls to init and mkexec do the following#	math->FPcontrol(0, Math->INVAL|Math->ZDIV|Math->OVFL|Math->UNFL|Math->INEX);#Ecmascript: module{	PATH:	con "/dis/lib/ecmascript.dis"; 	#	# an execution context	#	Exec: adt	{		#		# well known glop		#		objproto:	cyclic ref Obj;		funcproto:	cyclic ref Obj;		strproto:	cyclic ref Obj;			numproto:	cyclic ref Obj;		boolproto:	cyclic ref Obj;		arrayproto:	cyclic ref Obj;		dateproto:	cyclic ref Obj;		regexpproto:	cyclic ref Obj;		errproto:		cyclic ref Obj;		evlerrproto:		cyclic ref Obj;		ranerrproto:		cyclic ref Obj;		referrproto:		cyclic ref Obj;		synerrproto:		cyclic ref Obj;		typerrproto:		cyclic ref Obj;		urierrproto:		cyclic ref Obj;		interrproto:		cyclic ref Obj;				global:		cyclic ref Obj;		this:		cyclic ref Obj;		scopechain:	cyclic list of ref Obj; 		error:		string;		errval:		cyclic ref Val; 		#		# private, keep out		#		stack:		cyclic array of ref Ref;		sp:	int;	}; 	#	# must be called at the dawn of time	# returns error string	init:	fn(): string; 	#	# initialize a new global execution context	# if go is supplied, it's the global object	# if not, one is made up automatically	#	mkexec:		fn(go: ref Obj): ref Exec; 	#	# throw a runtime error	# msg ends up in ex.error, and an	# "ecmascript runtime error" is raised	#	RUNTIME:	con "ecmascript runtime error";	runtime:	fn(ex: ref Exec, o: ref Obj, msg: string); 	# runtime errors	EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError, InternalError: ref Obj; 	#	# debug flags: array of 256 indexed by char	#	# e	print ops as they are executed	# f	abort on an internal error	# p	print parsed code	# r	abort on any runtime error	# v	print value of expression statements	#	debug: array of int; 	#	# parse and runt the source string	#	eval:	fn(ex: ref Exec, src: string): Completion; 	Re: type ref Arena; 	# the fundamental data structure	Obj: adt	{		props:		cyclic array of ref Prop;		prototype:	cyclic ref Obj;		# some builtin properties		val:		cyclic ref Val;		call:		cyclic ref Call;		construct:	cyclic ref Call;		class:		string;		host:		ESHostobj;		# method suite for host objects		re:		Re;				# compiled regexp for RegExp objects	}; 	Call: adt	{		params:		array of string;		code:		cyclic ref Code;		ex:		cyclic ref Exec;	}; 	# attributes	ReadOnly, DontEnum, DontDelete: con 1 << iota;	Prop: adt	{		attr:		int;		name:		string;		val:		cyclic ref RefVal;	}; 	# an extra level of indirection, because sometimes properties are aliased	RefVal: adt	{		val:		cyclic ref Val;	}; 	# types of js values	TUndef, TNull, TBool, TNum, TStr, TObj, TRegExp, NoHint: con iota;	Val: adt	{		ty:		int;		num:		real;		str:		string;		obj:		cyclic ref Obj;		rev:		ref REval;	}; 	# regular expression	REval: adt	{		p: string;		f: string;		i: int;	}; 	# intermediate result of expression evaluation	Ref: adt	{		isref:		int;		val:		ref Val;		base:		ref Obj;		name:		string;				# name of property within base	}; 	# completion values of statements	CNormal, CBreak, CContinue, CReturn, CThrow: con iota;	Completion: adt	{		kind:		int;		val:		ref Val;		lab:		string;	}; 	Code: adt	{		ops:		array of byte;			# all instructions		npc:		int;				# end of active portion of ops		vars:		cyclic array of ref Prop;	# variables defined in the code		ids:		array of string;		# ids used in the code		strs:		array of string;		# string literal		nums:		array of real;			# numerical literals		fexps:	cyclic array of ref Obj;	# function expressions	}; 	#	# stuff for adding host objects	#	# ecmascript is also a host object;	get:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	put:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string, val: ref Ecmascript->Val);	canput:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	hasproperty:	fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string): ref Ecmascript->Val;	delete:		fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, property: string);	defaultval:	fn(ex: ref Ecmascript->Exec, o: ref Ecmascript->Obj, tyhint: int): ref Ecmascript->Val;	call:		fn(ex: ref Ecmascript->Exec, func, this: ref Ecmascript->Obj, args: array of ref Ecmascript->Val, eval: int): ref Ecmascript->Ref;	construct:	fn(ex: ref Ecmascript->Exec, func: ref Ecmascript->Obj, args: array of ref Ecmascript->Val): ref Ecmascript->Obj; 	#	# return the named variable from the scope chain sc	#	bivar:		fn(ex: ref Exec, sc: list of ref Obj, s: string): ref Val; 	#	# return the nth argument value, or undefined if too far	#	biarg:		fn(args: array of ref Val, n: int): ref Val; 	#	# make up a new object	# most often called as mkobj(ex.objproto, "Object")	#	mkobj:		fn(proto: ref Obj, class: string): ref Obj; 	#	# object installation helpers	#	Builtin: adt	{		name:	string;		val:	string;		params:	array of string;		length:	int;	};	biinst:		fn(o: ref Obj, bi: Builtin, proto: ref Obj, h: ESHostobj): ref Obj;	biminst:	fn(o: ref Obj, bis: array of Builtin, proto: ref Obj, h: ESHostobj); 	#	# instantiate a new variable inside an object	#	varinstant:	fn(in: ref Obj, attr: int, name: string, val: ref RefVal); 	#	# various constructors	#	objval:		fn(o: ref Obj): ref Val;	strval:		fn(s: string): ref Val;	numval:		fn(r: real): ref Val;	valref:		fn(v: ref Val): ref Ref; 	#	# conversion routines defined in section 9	#	toPrimitive:	fn(ex: ref Exec, v: ref Val, ty: int): ref Val;	toBoolean:	fn(ex: ref Exec, v: ref Val): ref Val;	toNumber:	fn(ex: ref Exec, v: ref Val): real;	toInteger:	fn(ex: ref Exec, v: ref Val): real;	toInt32:	fn(ex: ref Exec, v: ref Val): int;	toUint32:	fn(ex: ref Exec, v: ref Val): big;	toUint16:	fn(ex: ref Exec, v: ref Val): int;	toString:	fn(ex: ref Exec, v: ref Val): string;	toObject:	fn(ex: ref Exec, v: ref Val): ref Obj; 	#	# simple coercion routines to force	# Boolean, String, and Number values to objects and vice versa	#	coerceToObj:	fn(ex: ref Exec, v: ref Val): ref Val;	coerceToVal:	fn(v: ref Val): ref Val; 	#	# object/value kind checkers	#	isstrobj:	fn(o: ref Obj): int;	isnumobj:	fn(o: ref Obj): int;	isboolobj:	fn(o: ref Obj): int;	isdateobj:	fn(o: ref Obj): int;	isregexpobj: fn(o: ref Obj): int;	isarray:	fn(o: ref Obj): int;	isstr:		fn(v: ref Val): int;	isnum:		fn(v: ref Val): int;	isbool:		fn(v: ref Val): int;	isobj:		fn(v: ref Val): int; 	#	# well-known ecmascript primitive values	#	undefined:	ref Val;	true:		ref Val;	false:		ref Val;	null:		ref Val; 	# regexp data structures 	refRex: type int;	# used instead of ref Rex to avoid circularity 	Set: adt {				# character class		neg: int;			# 0 or 1		ascii: array of int;		# ascii members, bit array		unicode: list of (int,int);	# non-ascii char ranges		subset: cyclic list of ref Set;	}; 	Nstate: adt{		m: int;		n: int;	}; 	Rex: adt {		# node in parse of regex, or state of fsm		kind: int;	# kind of node: char or ALT, CAT, etc		left: refRex;	# left descendant		right: refRex;	# right descendant, or next state		set: ref Set;	# character class		pno: int;		greedy: int;		ns: ref Nstate;	}; 	Arena: adt {		# free store from which nodes are allocated		rex: array of Rex;				ptr: refRex;	# next available space		start: refRex;	# root of parse, or start of fsm		pno: int;	};};