implemented until and do..until loop
This commit is contained in:
		@ -61,23 +61,30 @@ extend Apex
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
 | 
						## INSTANTIATION & INITIALIZATION
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) __trailer_size
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method(#class) basicNew
 | 
						method(#class) basicNew
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							| perr |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<primitive: #_basic_new>
 | 
							<primitive: #_basic_new>
 | 
				
			||||||
		self primitiveFailed.
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						##	perr := thisProcess primError.
 | 
				
			||||||
 | 
						##	if (perr == xxxx) { self cannotInstantiate }
 | 
				
			||||||
 | 
						##	else { self primitiveFailed }.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	method(#class) basicNew: size
 | 
						method(#class) basicNew: size
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							| perr |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<primitive: #_basic_new>
 | 
							<primitive: #_basic_new>
 | 
				
			||||||
		self primitiveFailed.
 | 
							self primitiveFailed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						##	perr := thisProcess primError.
 | 
				
			||||||
 | 
						##	if (perr == xxxx) { self cannotInstantiate }
 | 
				
			||||||
 | 
						##	else { self primitiveFailed }.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) ngcNew
 | 
						method(#class) ngcNew
 | 
				
			||||||
@ -183,39 +190,10 @@ extend Apex
 | 
				
			|||||||
		else { self primitiveFailed }
 | 
							else { self primitiveFailed }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	(*
 | 
					 | 
				
			||||||
	method(#class) basicAt: index
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		| perr |
 | 
					 | 
				
			||||||
		<primitive: #_basic_at>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		perr := thisProcess primError.
 | 
					 | 
				
			||||||
		if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) }
 | 
					 | 
				
			||||||
		elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: }
 | 
					 | 
				
			||||||
		else { self primitiveFailed }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#dual) basicAt: index put: anObject
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		| perr |
 | 
					 | 
				
			||||||
		<primitive: #_basic_at_put>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		perr := thisProcess primError.
 | 
					 | 
				
			||||||
		if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) }
 | 
					 | 
				
			||||||
		elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: }
 | 
					 | 
				
			||||||
		else { self primitiveFailed }
 | 
					 | 
				
			||||||
	}*)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	(* ------------------------------------------------------------------
 | 
						(* ------------------------------------------------------------------
 | 
				
			||||||
	 * HASHING
 | 
						 * HASHING
 | 
				
			||||||
	 * ------------------------------------------------------------------ *)
 | 
						 * ------------------------------------------------------------------ *)
 | 
				
			||||||
	method hash
 | 
						method(#dual) hash
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_hash>
 | 
					 | 
				
			||||||
		self subclassResponsibility: #hash
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method(#class) hash
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_hash>
 | 
							<primitive: #_hash>
 | 
				
			||||||
		self subclassResponsibility: #hash
 | 
							self subclassResponsibility: #hash
 | 
				
			||||||
@ -225,7 +203,7 @@ extend Apex
 | 
				
			|||||||
	 * IDENTITY TEST
 | 
						 * IDENTITY TEST
 | 
				
			||||||
	 * ------------------------------------------------------------------ *)
 | 
						 * ------------------------------------------------------------------ *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method == anObject
 | 
						method(#dual) == anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		(* check if the receiver is identical to anObject.
 | 
							(* check if the receiver is identical to anObject.
 | 
				
			||||||
		 * this doesn't compare the contents *)
 | 
							 * this doesn't compare the contents *)
 | 
				
			||||||
@ -233,21 +211,7 @@ extend Apex
 | 
				
			|||||||
		self primitiveFailed.
 | 
							self primitiveFailed.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method ~~ anObject
 | 
						method(#dual) ~~ anObject
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_not_identical>
 | 
					 | 
				
			||||||
		^(self == anObject) not.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) == anObject
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		(* check if the receiver is identical to anObject.
 | 
					 | 
				
			||||||
		 * this doesn't compare the contents *)
 | 
					 | 
				
			||||||
		<primitive: #_identical>
 | 
					 | 
				
			||||||
		self primitiveFailed.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) ~~ anObject
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_not_identical>
 | 
							<primitive: #_not_identical>
 | 
				
			||||||
		^(self == anObject) not.
 | 
							^(self == anObject) not.
 | 
				
			||||||
@ -256,76 +220,42 @@ extend Apex
 | 
				
			|||||||
	(* ------------------------------------------------------------------
 | 
						(* ------------------------------------------------------------------
 | 
				
			||||||
	 * EQUALITY TEST
 | 
						 * EQUALITY TEST
 | 
				
			||||||
	 * ------------------------------------------------------------------ *)
 | 
						 * ------------------------------------------------------------------ *)
 | 
				
			||||||
	method = anObject
 | 
						method(#dual) = anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_equal>
 | 
							<primitive: #_equal>
 | 
				
			||||||
		self subclassResponsibility: #=
 | 
							self subclassResponsibility: #=
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	method ~= anObject
 | 
						method(#dual) ~= anObject
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_not_equal>
 | 
							<primitive: #_not_equal>
 | 
				
			||||||
		^(self = anObject) not.
 | 
							^(self = anObject) not.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) = anObject
 | 
					
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_equal>
 | 
					 | 
				
			||||||
		self subclassResponsibility: #=
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method(#class) ~= anObject
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_not_equal>
 | 
					 | 
				
			||||||
		^(self = anObject) not.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	(* ------------------------------------------------------------------
 | 
						(* ------------------------------------------------------------------
 | 
				
			||||||
	 * COMMON QUERIES
 | 
						 * COMMON QUERIES
 | 
				
			||||||
	 * ------------------------------------------------------------------ *)
 | 
						 * ------------------------------------------------------------------ *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method isNil
 | 
						method(#dual) isNil
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		"^self == nil."
 | 
							"^self == nil."
 | 
				
			||||||
		^false
 | 
							^false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method notNil
 | 
						method(#dual) notNil
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		"^(self == nil) not"
 | 
							"^(self == nil) not"
 | 
				
			||||||
		"^self ~= nil."
 | 
							"^self ~= nil."
 | 
				
			||||||
		^true.
 | 
							^true.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) isNil
 | 
						method(#dual) isError
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		"^self == nil."
 | 
					 | 
				
			||||||
		^false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) notNil
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		"^(self == nil) not"
 | 
					 | 
				
			||||||
		"^self ~= nil."
 | 
					 | 
				
			||||||
		^true.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method isError
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		^false
 | 
							^false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) isError
 | 
						method(#dual) notError
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method notError
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) notError
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		^true
 | 
							^true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -371,13 +301,7 @@ extend Apex
 | 
				
			|||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) respondsTo: selector
 | 
						method(#dual) respondsTo: selector
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_responds_to>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method respondsTo: selector
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_responds_to>
 | 
							<primitive: #_responds_to>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
@ -386,61 +310,32 @@ extend Apex
 | 
				
			|||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
	## -------------------------------------------------------
 | 
						## -------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class,#variadic) perform(selector)
 | 
						method(#dual,#variadic) perform(selector)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_perform>
 | 
							<primitive: #_perform>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#variadic) perform(selector)
 | 
						method(#dual) perform: selector
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_perform>
 | 
							<primitive: #_perform>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	method(#class) perform: selector
 | 
					
 | 
				
			||||||
	{
 | 
						method(#dual) perform: selector with: arg1
 | 
				
			||||||
		<primitive: #_perform>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method perform: selector
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_perform>
 | 
							<primitive: #_perform>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) perform: selector with: arg1
 | 
						method(#dual) perform: selector with: arg1 with: arg2
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_perform>
 | 
							<primitive: #_perform>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method perform: selector with: arg1
 | 
						method(#dual) perform: selector with: arg1 with: arg2 with: arg3
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_perform>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) perform: selector with: arg1 with: arg2
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_perform>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method perform: selector with: arg1 with: arg2
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_perform>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method(#class) perform: selector with: arg1 with: arg2 with: arg3
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		<primitive: #_perform>
 | 
					 | 
				
			||||||
		self primitiveFailed
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method perform: selector with: arg1 with: arg2 with: arg3
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		<primitive: #_perform>
 | 
							<primitive: #_perform>
 | 
				
			||||||
		self primitiveFailed
 | 
							self primitiveFailed
 | 
				
			||||||
@ -458,57 +353,12 @@ extend Apex
 | 
				
			|||||||
	(* ------------------------------------------------------------------
 | 
						(* ------------------------------------------------------------------
 | 
				
			||||||
	 * COMMON ERROR/EXCEPTION HANDLERS
 | 
						 * COMMON ERROR/EXCEPTION HANDLERS
 | 
				
			||||||
	 * ------------------------------------------------------------------ *)
 | 
						 * ------------------------------------------------------------------ *)
 | 
				
			||||||
	method primitiveFailed
 | 
						method(#dual) error: msgText
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class primitiveFailed.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method cannotInstantiate
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class cannotInstantiate
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method doesNotUnderstand: messageSymbol
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class doesNotUnderstand: messageSymbol
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method index: index outOfRange: ubound
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class index: index outOfRange: ubound.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method subclassResponsibility: method_name
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class subclassResponsibility: method_name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method notImplemented: method_name
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class notImplemented: method_name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	method messageProhibited: method_name
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class messageProhibited: method_name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method cannotExceptionizeError
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		^self class cannotExceptionizeError
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	method(#class) error: msgText
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		(* TODO: implement this
 | 
							(* TODO: implement this
 | 
				
			||||||
		  Error signal: msgText. *)
 | 
							  Error signal: msgText. *)
 | 
				
			||||||
		msgText dump.
 | 
							msgText dump.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	method error: aString
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		self class error: aString.
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Object(Apex)
 | 
					class Object(Apex)
 | 
				
			||||||
 | 
				
			|||||||
@ -33,39 +33,51 @@ class Exception(Apex)
 | 
				
			|||||||
		^(self class name) & ' - ' & self.messageText.
 | 
							^(self class name) & ' - ' & self.messageText.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						(* TODO: remove this....
 | 
				
			||||||
	method __signal 
 | 
						method __signal 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		self.signalContext := thisContext.
 | 
							self.signalContext := thisContext.
 | 
				
			||||||
		((thisContext sender) findExceptionContext) handleException: self.
 | 
							((thisContext sender) findExceptionContext) handleException: self.
 | 
				
			||||||
	}
 | 
						}*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method signal
 | 
						method signal
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		| exctx exblk retval actpos |
 | 
							| exctx exblk retval actpos ctx |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.signalContext := thisContext.
 | 
							self.signalContext := thisContext.
 | 
				
			||||||
		exctx := (thisContext sender) findExceptionContext.
 | 
							exctx := (thisContext sender) findExceptionContext.
 | 
				
			||||||
		[exctx notNil] whileTrue: [
 | 
							
 | 
				
			||||||
 | 
							##[exctx notNil] whileTrue: [
 | 
				
			||||||
 | 
							while (exctx notNil)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			exblk := exctx findExceptionHandlerFor: (self class).
 | 
								exblk := exctx findExceptionHandlerFor: (self class).
 | 
				
			||||||
			(exblk notNil and: 
 | 
								if (exblk notNil and: 
 | 
				
			||||||
			 [actpos := exctx basicSize - 1. exctx basicAt: actpos]) ifTrue: [
 | 
								    [actpos := exctx basicSize - 1. exctx basicAt: actpos])
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
				self.handlerContext := exctx.
 | 
									self.handlerContext := exctx.
 | 
				
			||||||
				exctx basicAt: actpos put: false.
 | 
									exctx basicAt: actpos put: false.
 | 
				
			||||||
				[ retval := exblk value: self ] ensure: [ 
 | 
									[ retval := exblk value: self ] ensure: [ exctx basicAt: actpos put: true ].
 | 
				
			||||||
					exctx basicAt: actpos put: true 
 | 
					 | 
				
			||||||
				].
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				thisContext unwindTo: (exctx sender) return: nil.
 | 
									thisContext unwindTo: (exctx sender) return: nil.
 | 
				
			||||||
				Processor return: retval to: (exctx sender).
 | 
									Processor return: retval to: (exctx sender).
 | 
				
			||||||
			].
 | 
								}.
 | 
				
			||||||
			exctx := (exctx sender) findExceptionContext.
 | 
								exctx := (exctx sender) findExceptionContext.
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		## -----------------------------------------------------------------
 | 
							## -----------------------------------------------------------------
 | 
				
			||||||
		## FATAL ERROR - no exception handler.
 | 
							## FATAL ERROR - no exception handler.
 | 
				
			||||||
		## -----------------------------------------------------------------
 | 
							## -----------------------------------------------------------------
 | 
				
			||||||
		##thisContext unwindTo: nil return: nil.
 | 
							##thisContext unwindTo: nil return: nil.
 | 
				
			||||||
		##thisContext unwindTo: (Processor activeProcess initialContext) return: nil.
 | 
							##thisContext unwindTo: (Processor activeProcess initialContext) return: nil.
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					## TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE...
 | 
				
			||||||
 | 
					ctx := thisContext.
 | 
				
			||||||
 | 
					while (ctx notNil)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ctx class == MethodContext) { (ctx method owner name & '>>' & ctx method name) dump }.
 | 
				
			||||||
 | 
						## TODO: include blockcontext???
 | 
				
			||||||
 | 
						ctx := ctx sender.
 | 
				
			||||||
 | 
					}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		thisContext unwindTo: (thisProcess initialContext) return: nil.
 | 
							thisContext unwindTo: (thisProcess initialContext) return: nil.
 | 
				
			||||||
		('### EXCEPTION NOT HANDLED #### ' & self class name & ' - ' & self messageText) dump.
 | 
							('### EXCEPTION NOT HANDLED #### ' & self class name & ' - ' & self messageText) dump.
 | 
				
			||||||
		## TODO: debug the current process???? "
 | 
							## TODO: debug the current process???? "
 | 
				
			||||||
@ -88,31 +100,31 @@ class Exception(Apex)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	method return: value
 | 
						method return: value
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		(self.handlerContext notNil) ifTrue: [
 | 
							if (self.handlerContext notNil) { Processor return: value to: self.handlerContext }
 | 
				
			||||||
			Processor return: value to: self.handlerContext.
 | 
					 | 
				
			||||||
		].
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method retry
 | 
						method retry
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
## TODO: verify if return:to: causes unnecessary stack growth.
 | 
					## TODO: verify if return:to: causes unnecessary stack growth.
 | 
				
			||||||
		(self.handlerContext notNil)  ifTrue: [
 | 
							if (self.handlerContext notNil) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			self.handlerContext pc: 0.
 | 
								self.handlerContext pc: 0.
 | 
				
			||||||
			Processor return: self to: self.handlerContext.
 | 
								Processor return: self to: self.handlerContext.
 | 
				
			||||||
		].
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method resume: value
 | 
						method resume: value
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
## TODO: verify if return:to: causes unnecessary stack growth.
 | 
					## TODO: verify if return:to: causes unnecessary stack growth.
 | 
				
			||||||
## is this correct???
 | 
					## is this correct???
 | 
				
			||||||
		(self.signalContext notNil and: [self.handlerContext notNil]) ifTrue: [
 | 
							| ctx |
 | 
				
			||||||
			| ctx |
 | 
							if (self.signalContext notNil and: [self.handlerContext notNil])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			ctx := self.signalContext sender.
 | 
								ctx := self.signalContext sender.
 | 
				
			||||||
			self.signalContext := nil.
 | 
								self.signalContext := nil.
 | 
				
			||||||
			self.handlerContext := nil.
 | 
								self.handlerContext := nil.
 | 
				
			||||||
			Processor return: value to: ctx.
 | 
								Processor return: value to: ctx.
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method resume
 | 
						method resume
 | 
				
			||||||
@ -143,10 +155,11 @@ extend Context
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		| ctx |
 | 
							| ctx |
 | 
				
			||||||
		ctx := self.
 | 
							ctx := self.
 | 
				
			||||||
		[ ctx notNil ] whileTrue: [
 | 
							while (ctx notNil)
 | 
				
			||||||
			(ctx isExceptionContext) ifTrue: [^ctx].
 | 
							{
 | 
				
			||||||
 | 
								if (ctx isExceptionContext) { ^ctx }.
 | 
				
			||||||
			ctx := ctx sender.
 | 
								ctx := ctx sender.
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
		^nil
 | 
							^nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -157,26 +170,29 @@ extend Context
 | 
				
			|||||||
		## private: called by VM upon unwinding
 | 
							## private: called by VM upon unwinding
 | 
				
			||||||
		## -------------------------------------------------------------------
 | 
							## -------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		| ctx stop |
 | 
							| ctx stop eb pending_pos |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx := self.
 | 
							ctx := self.
 | 
				
			||||||
		stop := false.
 | 
							stop := false.
 | 
				
			||||||
		[stop] whileFalse: [
 | 
							until (stop)
 | 
				
			||||||
			| eb |
 | 
							{
 | 
				
			||||||
			eb := ctx ensureBlock.
 | 
								eb := ctx ensureBlock.
 | 
				
			||||||
			(eb notNil) ifTrue: [
 | 
								if (eb notNil)
 | 
				
			||||||
				| donepos |
 | 
								{
 | 
				
			||||||
				donepos := ctx basicSize - 1.
 | 
									(* position of the temporary variable in the ensureBlock that indicates
 | 
				
			||||||
				(ctx basicAt: donepos) ifFalse: [
 | 
									 * if the block has been evaluated *)
 | 
				
			||||||
					ctx basicAt: donepos put: true.
 | 
									pending_pos := ctx basicSize - 1. 
 | 
				
			||||||
 | 
									if (ctx basicAt: pending_pos)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										ctx basicAt: pending_pos put: false.
 | 
				
			||||||
					eb value.
 | 
										eb value.
 | 
				
			||||||
				].
 | 
									}
 | 
				
			||||||
			].
 | 
								}.
 | 
				
			||||||
			stop := (ctx == context).
 | 
								stop := (ctx == context).
 | 
				
			||||||
			ctx := ctx sender.
 | 
								ctx := ctx sender.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			## stop ifFalse: [ stop := ctx isNil ].
 | 
								## stop ifFalse: [ stop := ctx isNil ].
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		^retval
 | 
							^retval
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -207,9 +223,7 @@ extend MethodContext
 | 
				
			|||||||
		 * instance variables of the method context. As MethodContex has
 | 
							 * instance variables of the method context. As MethodContex has
 | 
				
			||||||
		 * 8 instance variables, the ensure block must be at the 9th position
 | 
							 * 8 instance variables, the ensure block must be at the 9th position
 | 
				
			||||||
		 * which translates to index 8 *)
 | 
							 * which translates to index 8 *)
 | 
				
			||||||
 | 
							^if (self.method preambleCode == 13) { self basicAt: 8 } else { nil }
 | 
				
			||||||
		(self.method preambleCode == 13) ifFalse: [^nil].
 | 
					 | 
				
			||||||
		^self basicAt: 8.
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -226,9 +240,10 @@ extend MethodContext
 | 
				
			|||||||
## TODO: change 8 to a constant when moo is enhanced to support constant definition
 | 
					## TODO: change 8 to a constant when moo is enhanced to support constant definition
 | 
				
			||||||
##       or calcuate the minimum size using the class information.
 | 
					##       or calcuate the minimum size using the class information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		(self isExceptionContext) ifTrue: [
 | 
							| size exc |
 | 
				
			||||||
			| size exc |
 | 
							
 | 
				
			||||||
 | 
							if (self isExceptionContext) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			(* NOTE: the following loop scans all parameters to the on:do: method.
 | 
								(* NOTE: the following loop scans all parameters to the on:do: method.
 | 
				
			||||||
			 *       if the on:do: method contains local temporary variables,
 | 
								 *       if the on:do: method contains local temporary variables,
 | 
				
			||||||
			 *       those must be skipped from scanning. *)
 | 
								 *       those must be skipped from scanning. *)
 | 
				
			||||||
@ -236,9 +251,9 @@ extend MethodContext
 | 
				
			|||||||
			size := self basicSize.
 | 
								size := self basicSize.
 | 
				
			||||||
			8 priorTo: size by: 2 do: [ :i | 
 | 
								8 priorTo: size by: 2 do: [ :i | 
 | 
				
			||||||
				exc := self basicAt: i.
 | 
									exc := self basicAt: i.
 | 
				
			||||||
				((exception_class == exc) or: [exception_class inheritsFrom: exc]) ifTrue: [^self basicAt: (i + 1)].
 | 
									if ((exception_class == exc) or: [exception_class inheritsFrom: exc]) { ^self basicAt: (i + 1) }.
 | 
				
			||||||
			]
 | 
								]
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
		^nil.
 | 
							^nil.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -261,12 +276,13 @@ extend MethodContext
 | 
				
			|||||||
		actpos := (self basicSize) - 1. 
 | 
							actpos := (self basicSize) - 1. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		excblk := self findExceptionHandlerFor: (exception class).
 | 
							excblk := self findExceptionHandlerFor: (exception class).
 | 
				
			||||||
		(excblk isNil or: [(self basicAt: actpos) not]) ifTrue: [ 
 | 
							if (excblk isNil or: [(self basicAt: actpos) not])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			## self is an exception context but doesn't have a matching
 | 
								## self is an exception context but doesn't have a matching
 | 
				
			||||||
			## exception handler or the exception context is already
 | 
								## exception handler or the exception context is already
 | 
				
			||||||
			## in the middle of evaluation. 
 | 
								## in the middle of evaluation. 
 | 
				
			||||||
			^(self.sender findExceptionContext) handleException: exception.
 | 
								^(self.sender findExceptionContext) handleException: exception.
 | 
				
			||||||
		].
 | 
							}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		exception handlerContext: self.
 | 
							exception handlerContext: self.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -324,27 +340,24 @@ thisContext isExceptionContext dump.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	method ensure: aBlock
 | 
						method ensure: aBlock
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		| retval done |
 | 
							| retval pending |
 | 
				
			||||||
		<ensure>
 | 
							<ensure>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		done := false.
 | 
							pending := true.
 | 
				
			||||||
		retval := self value. 
 | 
							retval := self value. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		## the temporary variable 'done' may get changed
 | 
							(* the temporary variable 'pending' may get changed
 | 
				
			||||||
		## during evaluation for exception handling. 
 | 
							 * during evaluation for exception handling. 
 | 
				
			||||||
		done ifFalse: [
 | 
							 * it gets chagned in Context>>unwindTo:return: *)
 | 
				
			||||||
			done := true.
 | 
							if (pending) { pending := false. aBlock value }.
 | 
				
			||||||
			aBlock value.
 | 
					 | 
				
			||||||
		].
 | 
					 | 
				
			||||||
		^retval
 | 
							^retval
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method ifCurtailed: aBlock
 | 
						method ifCurtailed: aBlock
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		| v ok |
 | 
							| v pending |
 | 
				
			||||||
 | 
							pending := true.
 | 
				
			||||||
		ok := false.
 | 
							[ v := self value. pending := false. ] ensure: [ if (pending) { aBlock value } ].
 | 
				
			||||||
		[ v := self value. ok := true. ] ensure: [ ok ifFalse: [aBlock value] ].
 | 
					 | 
				
			||||||
		^v.
 | 
							^v.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -389,55 +402,50 @@ class ProhibitedMessageException(Exception)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extend Apex
 | 
					extend Apex
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	method(#class) primitiveFailed
 | 
						method(#dual) primitiveFailed
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		## TODO: implement this
 | 
					 | 
				
			||||||
## experimental backtrace...
 | 
					 | 
				
			||||||
| ctx |
 | 
					 | 
				
			||||||
ctx := thisContext.
 | 
					 | 
				
			||||||
[ctx notNil] whileTrue: [
 | 
					 | 
				
			||||||
	(ctx class == MethodContext) 
 | 
					 | 
				
			||||||
		ifTrue: [ (ctx method owner name & '>>' & ctx method name) dump ].
 | 
					 | 
				
			||||||
	## TODO: include blockcontext???
 | 
					 | 
				
			||||||
	ctx := ctx sender.
 | 
					 | 
				
			||||||
].
 | 
					 | 
				
			||||||
'------ END OF BACKTRACE -----------' dump.
 | 
					 | 
				
			||||||
		PrimitiveFailureException signal: 'PRIMITIVE FAILED'.
 | 
							PrimitiveFailureException signal: 'PRIMITIVE FAILED'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) cannotInstantiate
 | 
						method(#dual) cannotInstantiate
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
## TOOD: accept a class
 | 
							## TODO: use displayString or something like that instead of name....
 | 
				
			||||||
		InstantiationFailureException signal: 'Cannot instantiate'.
 | 
							InstantiationFailureException signal: 'Cannot instantiate ' & (self name).
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) doesNotUnderstand: message_name
 | 
						method(#dual) doesNotUnderstand: message_name
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		## TODO: implement this properly
 | 
							## TODO: implement this properly
 | 
				
			||||||
		NoSuchMessageException signal: (message_name & ' not understood by ' & (self name)).
 | 
							| class_name |
 | 
				
			||||||
 | 
							class_name := if (self class == Class) { self name } else { self class name }.
 | 
				
			||||||
 | 
							NoSuchMessageException signal: (message_name & ' not understood by ' & class_name).
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) index: index outOfRange: ubound
 | 
						method(#dual) index: index outOfRange: ubound
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		IndexOutOfRangeException signal: 'Out of range'.
 | 
							IndexOutOfRangeException signal: 'Out of range'.
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) subclassResponsibility: method_name
 | 
						method(#dual) subclassResponsibility: method_name
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SubclassResponsibilityException signal: ('Subclass must implement ' & method_name).
 | 
							SubclassResponsibilityException signal: ('Subclass must implement ' & method_name).
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) notImplemented: method_name
 | 
						method(#dual) notImplemented: method_name
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		NotImplementedException signal: (method_name & ' not implemented by ' & (self name)).
 | 
							| class_name |
 | 
				
			||||||
 | 
							class_name := if (self class == Class) { self name } else { self class name }.
 | 
				
			||||||
 | 
							NotImplementedException signal: (method_name & ' not implemented by ' & class_name).
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	method(#class) messageProhibited: method_name
 | 
						method(#dual) messageProhibited: method_name
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ProhibitedMessageException signal: (method_name & ' not allowed for ' & (self name)).
 | 
							| class_name |
 | 
				
			||||||
 | 
							class_name := if (self class == Class) { self name } else { self class name }.
 | 
				
			||||||
 | 
							ProhibitedMessageException signal: (method_name & ' not allowed for ' & class_name).
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method(#class) cannotExceptionizeError
 | 
						method(#dual) cannotExceptionizeError
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
## todo: accept the object
 | 
					## todo: accept the object
 | 
				
			||||||
		ErrorExceptionizationFailureException signal: 'Cannot exceptionize an error'
 | 
							ErrorExceptionizationFailureException signal: 'Cannot exceptionize an error'
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,16 @@ class(#pointer) Process(Object)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	var initial_context, current_context, state, sp, prev, next, sem, perr.
 | 
						var initial_context, current_context, state, sp, prev, next, sem, perr.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method new
 | 
						method(#class) basicNew
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		"instantiation is not allowed"
 | 
							(* instantiation is not allowed. a process is strictly a VM managed object *)
 | 
				
			||||||
		^nil. "TODO: raise an exception or return an error"
 | 
							self cannotInstantiate
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						method(#class) basicNew: size 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							(* instantiation is not allowed. a process is strictly a VM managed object *)
 | 
				
			||||||
 | 
							self cannotInstantiate
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	method prev { ^self.prev }
 | 
						method prev { ^self.prev }
 | 
				
			||||||
 | 
				
			|||||||
@ -120,6 +120,7 @@ static struct voca_t
 | 
				
			|||||||
	{ 11, { 't','h','i','s','C','o','n','t','e','x','t'                   } },
 | 
						{ 11, { 't','h','i','s','C','o','n','t','e','x','t'                   } },
 | 
				
			||||||
	{ 11, { 't','h','i','s','P','r','o','c','e','s','s'                   } },
 | 
						{ 11, { 't','h','i','s','P','r','o','c','e','s','s'                   } },
 | 
				
			||||||
	{  4, { 't','r','u','e'                                               } },
 | 
						{  4, { 't','r','u','e'                                               } },
 | 
				
			||||||
 | 
						{  5, { 'u','n','t','i','l'                                           } },
 | 
				
			||||||
	{  3, { 'v','a','r'                                                   } },
 | 
						{  3, { 'v','a','r'                                                   } },
 | 
				
			||||||
	{  8, { 'v','a','r','i','a','b','l','e'                               } },
 | 
						{  8, { 'v','a','r','i','a','b','l','e'                               } },
 | 
				
			||||||
	{  9, { '#','v','a','r','i','a','d','i','c'                           } },
 | 
						{  9, { '#','v','a','r','i','a','d','i','c'                           } },
 | 
				
			||||||
@ -175,6 +176,7 @@ enum voca_id_t
 | 
				
			|||||||
	VOCA_THIS_CONTEXT,
 | 
						VOCA_THIS_CONTEXT,
 | 
				
			||||||
	VOCA_THIS_PROCESS,
 | 
						VOCA_THIS_PROCESS,
 | 
				
			||||||
	VOCA_TRUE,
 | 
						VOCA_TRUE,
 | 
				
			||||||
 | 
						VOCA_UNTIL,
 | 
				
			||||||
	VOCA_VAR,
 | 
						VOCA_VAR,
 | 
				
			||||||
	VOCA_VARIABLE,
 | 
						VOCA_VARIABLE,
 | 
				
			||||||
	VOCA_VARIADIC_S,
 | 
						VOCA_VARIADIC_S,
 | 
				
			||||||
@ -318,6 +320,7 @@ static int is_reserved_word (const moo_oocs_t* ucs)
 | 
				
			|||||||
		VOCA_ELSE,
 | 
							VOCA_ELSE,
 | 
				
			||||||
		VOCA_ELSIF,
 | 
							VOCA_ELSIF,
 | 
				
			||||||
		VOCA_WHILE,
 | 
							VOCA_WHILE,
 | 
				
			||||||
 | 
							VOCA_UNTIL,
 | 
				
			||||||
		VOCA_DO,
 | 
							VOCA_DO,
 | 
				
			||||||
		VOCA_BREAK,
 | 
							VOCA_BREAK,
 | 
				
			||||||
		VOCA_CONTINUE
 | 
							VOCA_CONTINUE
 | 
				
			||||||
@ -1126,6 +1129,10 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			SET_TOKEN_TYPE (moo, MOO_IOTOK_WHILE);
 | 
								SET_TOKEN_TYPE (moo, MOO_IOTOK_WHILE);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else if (is_token_word(moo, VOCA_UNTIL))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SET_TOKEN_TYPE (moo, MOO_IOTOK_UNTIL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else if (is_token_word(moo, VOCA_DO))
 | 
							else if (is_token_word(moo, VOCA_DO))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			SET_TOKEN_TYPE (moo, MOO_IOTOK_DO);
 | 
								SET_TOKEN_TYPE (moo, MOO_IOTOK_DO);
 | 
				
			||||||
@ -2051,7 +2058,6 @@ static int emit_single_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		case BCODE_JUMP_FORWARD_0:
 | 
							case BCODE_JUMP_FORWARD_0:
 | 
				
			||||||
		case BCODE_JUMP_BACKWARD_0:
 | 
							case BCODE_JUMP_BACKWARD_0:
 | 
				
			||||||
		case BCODE_JUMP_FORWARD_IF_FALSE_0:
 | 
					 | 
				
			||||||
		case BCODE_JUMP_BACKWARD_IF_FALSE_0:
 | 
							case BCODE_JUMP_BACKWARD_IF_FALSE_0:
 | 
				
			||||||
		case BCODE_JUMP_BACKWARD_IF_TRUE_0:
 | 
							case BCODE_JUMP_BACKWARD_IF_TRUE_0:
 | 
				
			||||||
			if (param_1 < 4)
 | 
								if (param_1 < 4)
 | 
				
			||||||
@ -2072,11 +2078,24 @@ static int emit_single_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1
 | 
				
			|||||||
				goto write_long;
 | 
									goto write_long;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case BCODE_JUMP_BACKWARD_X:
 | 
				
			||||||
 | 
							case BCODE_JUMP_BACKWARD_IF_FALSE_X:
 | 
				
			||||||
 | 
							case BCODE_JUMP_BACKWARD_IF_TRUE_X:
 | 
				
			||||||
 | 
							case BCODE_JUMP_FORWARD_X:
 | 
				
			||||||
 | 
							case BCODE_JUMP_FORWARD_IF_FALSE:
 | 
				
			||||||
 | 
							case BCODE_JUMP_FORWARD_IF_TRUE:
 | 
				
			||||||
 | 
								if (param_1 > MAX_CODE_JUMP)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									cmd = cmd + 1; /* convert to a JUMP2 instruction */
 | 
				
			||||||
 | 
									param_1 = param_1 - MAX_CODE_JUMP;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								/* fall thru */
 | 
				
			||||||
		case BCODE_JUMP2_FORWARD:
 | 
							case BCODE_JUMP2_FORWARD:
 | 
				
			||||||
		case BCODE_JUMP2_BACKWARD:
 | 
							case BCODE_JUMP2_BACKWARD:
 | 
				
			||||||
		case BCODE_JUMP2_FORWARD_IF_FALSE:
 | 
					 | 
				
			||||||
		case BCODE_JUMP2_BACKWARD_IF_FALSE:
 | 
							case BCODE_JUMP2_BACKWARD_IF_FALSE:
 | 
				
			||||||
		case BCODE_JUMP2_BACKWARD_IF_TRUE:
 | 
							case BCODE_JUMP2_BACKWARD_IF_TRUE:
 | 
				
			||||||
 | 
							case BCODE_JUMP2_FORWARD_IF_FALSE:
 | 
				
			||||||
 | 
							case BCODE_JUMP2_FORWARD_IF_TRUE:
 | 
				
			||||||
		case BCODE_PUSH_INTLIT:
 | 
							case BCODE_PUSH_INTLIT:
 | 
				
			||||||
		case BCODE_PUSH_NEGINTLIT:
 | 
							case BCODE_PUSH_NEGINTLIT:
 | 
				
			||||||
		case BCODE_PUSH_CHARLIT:
 | 
							case BCODE_PUSH_CHARLIT:
 | 
				
			||||||
@ -2237,12 +2256,11 @@ static MOO_INLINE int emit_backward_jump_instruction (moo_t* moo, int cmd, moo_o
 | 
				
			|||||||
	 * instruction, which result in 1, 2, 3 when combined with the length 1
 | 
						 * instruction, which result in 1, 2, 3 when combined with the length 1
 | 
				
			||||||
	 * of the instruction itself */
 | 
						 * of the instruction itself */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	adj = (offset < 3)? 1: (MOO_BCODE_LONG_PARAM_SIZE + 1);
 | 
						adj = (offset < 3)? 1: (MOO_BCODE_LONG_PARAM_SIZE + 1);
 | 
				
			||||||
	return emit_single_param_instruction (moo, cmd, offset + adj);
 | 
						return emit_single_param_instruction (moo, cmd, offset + adj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t jt, moo_oob_t jump2_inst, moo_ioloc_t* errloc)
 | 
					static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t jt, moo_ioloc_t* errloc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	moo_oow_t code_size;
 | 
						moo_oow_t code_size;
 | 
				
			||||||
	moo_oow_t jump_offset;
 | 
						moo_oow_t jump_offset;
 | 
				
			||||||
@ -2261,11 +2279,15 @@ static int patch_long_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_o
 | 
				
			|||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MOO_ASSERT (moo, moo->c->mth.code.ptr[jip] == BCODE_JUMP_FORWARD_X ||
 | 
				
			||||||
 | 
						                 moo->c->mth.code.ptr[jip] == BCODE_JUMP_FORWARD_IF_FALSE ||
 | 
				
			||||||
 | 
						                 moo->c->mth.code.ptr[jip] == BCODE_JUMP_FORWARD_IF_TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (code_size > MAX_CODE_JUMP)
 | 
						if (code_size > MAX_CODE_JUMP)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* switch to JUMP2 instruction to allow a bigger jump offset.
 | 
							/* switch to JUMP2 instruction to allow a bigger jump offset.
 | 
				
			||||||
		 * up to twice MAX_CODE_JUMP only */
 | 
							 * up to twice MAX_CODE_JUMP only */
 | 
				
			||||||
		moo->c->mth.code.ptr[jip] = jump2_inst;
 | 
							moo->c->mth.code.ptr[jip]++; /* switch to the JUMP2 instruction */
 | 
				
			||||||
		jump_offset = code_size - MAX_CODE_JUMP;
 | 
							jump_offset = code_size - MAX_CODE_JUMP;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
@ -2311,7 +2333,7 @@ static int update_loop_jumps (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t jt)
 | 
				
			|||||||
		for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
 | 
							for (j = 0; j < MOO_COUNTOF(pool->static_chunk.buf) && i < pool->count; j++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (chunk->buf[j] != INVALID_IP &&
 | 
								if (chunk->buf[j] != INVALID_IP &&
 | 
				
			||||||
			    patch_long_forward_jump_instruction (moo, chunk->buf[j], jt, BCODE_JUMP2_FORWARD, MOO_NULL) <= -1) return -1;
 | 
								    patch_long_forward_jump_instruction (moo, chunk->buf[j], jt, MOO_NULL) <= -1) return -1;
 | 
				
			||||||
			i++;
 | 
								i++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -2402,12 +2424,13 @@ static MOO_INLINE int inject_break_to_loop (moo_t* moo)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static MOO_INLINE int inject_continue_to_loop (moo_t* moo)
 | 
					static MOO_INLINE int inject_continue_to_loop (moo_t* moo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						/* used for a do-while loop. jump forward because the conditional 
 | 
				
			||||||
 | 
						 * is at the end of the do-while loop */
 | 
				
			||||||
	if (add_to_oow_pool (moo, &moo->c->mth.loop->continue_ip_pool, moo->c->mth.code.len) <= -1 ||
 | 
						if (add_to_oow_pool (moo, &moo->c->mth.loop->continue_ip_pool, moo->c->mth.code.len) <= -1 ||
 | 
				
			||||||
	    emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1;
 | 
						    emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
 | 
					static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	moo_oow_t last;
 | 
						moo_oow_t last;
 | 
				
			||||||
@ -2547,7 +2570,8 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (var_index >= moo->c->cls.var[var_type].initv_capa)
 | 
						if (var_index >= moo->c->cls.var[var_type].initv_capa)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		moo_oow_t newcapa, oldcapa, i;
 | 
							moo_oow_t newcapa, oldcapa;
 | 
				
			||||||
 | 
							/*moo_oow_t i;*/
 | 
				
			||||||
		moo_oop_t* tmp;
 | 
							moo_oop_t* tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		oldcapa = moo->c->cls.var[var_type].initv_capa;
 | 
							oldcapa = moo->c->cls.var[var_type].initv_capa;
 | 
				
			||||||
@ -4151,7 +4175,7 @@ static int compile_block_expression (moo_t* moo)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
 | 
						if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (patch_long_forward_jump_instruction (moo, jump_inst_pos, moo->c->mth.code.len, BCODE_JUMP2_FORWARD, &block_loc) <= -1) return -1;
 | 
						if (patch_long_forward_jump_instruction (moo, jump_inst_pos, moo->c->mth.code.len, &block_loc) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* restore the temporary count */
 | 
						/* restore the temporary count */
 | 
				
			||||||
	moo->c->mth.tmprs.len = saved_tmprs_len;
 | 
						moo->c->mth.tmprs.len = saved_tmprs_len;
 | 
				
			||||||
@ -5172,7 +5196,7 @@ static int compile_if_expression (moo_t* moo)
 | 
				
			|||||||
		precondpos = moo->c->mth.code.len;
 | 
							precondpos = moo->c->mth.code.len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (jumptonext != INVALID_IP &&
 | 
							if (jumptonext != INVALID_IP &&
 | 
				
			||||||
		    patch_long_forward_jump_instruction (moo, jumptonext, precondpos, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
 | 
							    patch_long_forward_jump_instruction (moo, jumptonext, precondpos, &brace_loc) <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (compile_conditional(moo) <= -1) goto oops;
 | 
							if (compile_conditional(moo) <= -1) goto oops;
 | 
				
			||||||
		postcondpos = moo->c->mth.code.len;
 | 
							postcondpos = moo->c->mth.code.len;
 | 
				
			||||||
@ -5197,9 +5221,9 @@ static int compile_if_expression (moo_t* moo)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			/* remember position of the jump_forward_if_false instruction to be generated */
 | 
								/* remember position of the jump_forward_if_false instruction to be generated */
 | 
				
			||||||
			jumptonext = moo->c->mth.code.len; 
 | 
								jumptonext = moo->c->mth.code.len; 
 | 
				
			||||||
			/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to 
 | 
								/* BCODE_JUMP_FORWARD_IF_FALSE is always a long jump instruction.
 | 
				
			||||||
			 * produce the long jump instruction (BCODE_JUMP_FORWARD_X) */
 | 
								 * just specify MAX_CODE_JUMP for consistency with short jump variants */
 | 
				
			||||||
			if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) goto oops;
 | 
								if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE, MAX_CODE_JUMP) <= -1) goto oops;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		GET_TOKEN (moo); /* get { */
 | 
							GET_TOKEN (moo); /* get { */
 | 
				
			||||||
@ -5210,7 +5234,7 @@ static int compile_if_expression (moo_t* moo)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if (falseblock) 
 | 
								if (falseblock) 
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				/* the conditional was false. elimiate instructions emitted
 | 
									/* the conditional was false. eliminate instructions emitted
 | 
				
			||||||
				 * for the block attached to the conditional */
 | 
									 * for the block attached to the conditional */
 | 
				
			||||||
				eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
									eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
				
			||||||
				postcondpos = precondpos;
 | 
									postcondpos = precondpos;
 | 
				
			||||||
@ -5235,7 +5259,7 @@ static int compile_if_expression (moo_t* moo)
 | 
				
			|||||||
	} while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF);
 | 
						} while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (jumptonext != INVALID_IP &&
 | 
						if (jumptonext != INVALID_IP &&
 | 
				
			||||||
	    patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
 | 
						    patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, &brace_loc) <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
 | 
						if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -5263,7 +5287,7 @@ static int compile_if_expression (moo_t* moo)
 | 
				
			|||||||
		 * call will never flood either. */
 | 
							 * call will never flood either. */
 | 
				
			||||||
		for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
 | 
							for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (patch_long_forward_jump_instruction (moo, jumptoend_chunk->buf[j], moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &if_loc) <= -1) goto oops;
 | 
								if (patch_long_forward_jump_instruction (moo, jumptoend_chunk->buf[j], moo->c->mth.code.len, &if_loc) <= -1) goto oops;
 | 
				
			||||||
			i++;
 | 
								i++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -5276,13 +5300,15 @@ oops:
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int compile_while_expression (moo_t* moo)
 | 
					static int compile_while_expression (moo_t* moo) /* or compile_until_expression */
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	moo_ioloc_t while_loc, brace_loc;
 | 
						moo_ioloc_t while_loc, brace_loc;
 | 
				
			||||||
	moo_oow_t precondpos, postcondpos, prebbpos, postbbpos;
 | 
						moo_oow_t precondpos, postcondpos, prebbpos, postbbpos;
 | 
				
			||||||
	int cond_style = 0, loop_pushed = 0;
 | 
						int cond_style = 0, loop_pushed = 0, is_until_loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_WHILE);
 | 
						MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_WHILE || TOKEN_TYPE(moo) == MOO_IOTOK_UNTIL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						is_until_loop = (TOKEN_TYPE(moo) == MOO_IOTOK_UNTIL);
 | 
				
			||||||
	while_loc = *TOKEN_LOC(moo);
 | 
						while_loc = *TOKEN_LOC(moo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GET_TOKEN (moo); /* get (, verification is done inside compile_conditional() */
 | 
						GET_TOKEN (moo); /* get (, verification is done inside compile_conditional() */
 | 
				
			||||||
@ -5290,32 +5316,32 @@ static int compile_while_expression (moo_t* moo)
 | 
				
			|||||||
	if (compile_conditional (moo) <= -1) goto oops;
 | 
						if (compile_conditional (moo) <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	postcondpos = moo->c->mth.code.len;
 | 
						postcondpos = moo->c->mth.code.len;
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
	if (precondpos + 1 == postcondpos)
 | 
						if (precondpos + 1 == postcondpos)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* simple optimization - 
 | 
							/* simple optimization - 
 | 
				
			||||||
		 *   if the conditional is known to be true, emit the absolute jump instruction.
 | 
							 *   if the conditional is known to be true, emit the absolute jump instruction.
 | 
				
			||||||
		 *   if it is known to be false, kill all generated instructions. */
 | 
							 *   if it is known to be false, kill all generated instructions. */
 | 
				
			||||||
		if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE)
 | 
							if (moo->c->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_FALSE: BCODE_PUSH_TRUE))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* the conditional is always true */
 | 
								/* the conditional is always true for while, or false for until*/
 | 
				
			||||||
			cond_style = 1;
 | 
								cond_style = 1;
 | 
				
			||||||
			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
								eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
				
			||||||
			postcondpos = precondpos;
 | 
								postcondpos = precondpos;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
 | 
							else if (moo->c->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_TRUE: BCODE_PUSH_FALSE))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* the conditional is always false */
 | 
								/* the conditional is always false for while, or false for until */
 | 
				
			||||||
			cond_style = -1;
 | 
								cond_style = -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					/* TODO: at least check for some literals for optimization. 
 | 
				
			||||||
 | 
					 *       most literal values must be evaluate to true. */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cond_style != 1)
 | 
						if (cond_style != 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to 
 | 
							/* BCODE_JUMP_FORWARD_IF_FALSE is always a long jump instruction.
 | 
				
			||||||
		 * produce the long jump instruction (BCODE_JUMP_FORWARD_X) */
 | 
							 * just specify MAX_CODE_JUMP for consistency with short jump variants */
 | 
				
			||||||
		if (emit_single_param_instruction (moo, BCODE_JUMP_FORWARD_IF_FALSE_0, MAX_CODE_JUMP) <= -1) goto oops;
 | 
							if (emit_single_param_instruction (moo, (is_until_loop? BCODE_JUMP_FORWARD_IF_TRUE: BCODE_JUMP_FORWARD_IF_FALSE), MAX_CODE_JUMP) <= -1) goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* remember information about this while loop. */
 | 
						/* remember information about this while loop. */
 | 
				
			||||||
@ -5357,7 +5383,7 @@ static int compile_while_expression (moo_t* moo)
 | 
				
			|||||||
	if (cond_style != 1)
 | 
						if (cond_style != 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* patch the jump instruction */
 | 
							/* patch the jump instruction */
 | 
				
			||||||
		if (patch_long_forward_jump_instruction (moo, postcondpos, moo->c->mth.code.len, BCODE_JUMP2_FORWARD_IF_FALSE, &brace_loc) <= -1) goto oops;
 | 
							if (patch_long_forward_jump_instruction (moo, postcondpos, moo->c->mth.code.len, &brace_loc) <= -1) goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cond_style == -1) 
 | 
						if (cond_style == -1) 
 | 
				
			||||||
@ -5388,7 +5414,7 @@ static int compile_do_while_expression (moo_t* moo)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	moo_ioloc_t do_loc;
 | 
						moo_ioloc_t do_loc;
 | 
				
			||||||
	moo_oow_t precondpos, postcondpos, prebbpos, postbbpos;
 | 
						moo_oow_t precondpos, postcondpos, prebbpos, postbbpos;
 | 
				
			||||||
	int jbinst = 0, loop_pushed = 0;
 | 
						int jbinst = 0, loop_pushed = 0, is_until_loop;
 | 
				
			||||||
	moo_loop_t* loop = MOO_NULL;
 | 
						moo_loop_t* loop = MOO_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DO);
 | 
						MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DO);
 | 
				
			||||||
@ -5405,7 +5431,9 @@ static int compile_do_while_expression (moo_t* moo)
 | 
				
			|||||||
	if (compile_braced_block(moo) <= -1) goto oops;
 | 
						if (compile_braced_block(moo) <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GET_TOKEN (moo); /* get the next token after } */
 | 
						GET_TOKEN (moo); /* get the next token after } */
 | 
				
			||||||
	if (TOKEN_TYPE(moo) != MOO_IOTOK_WHILE)
 | 
						if (TOKEN_TYPE(moo) == MOO_IOTOK_UNTIL) is_until_loop = 1;
 | 
				
			||||||
 | 
						else if (TOKEN_TYPE(moo) == MOO_IOTOK_WHILE) is_until_loop = 0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		set_syntax_error (moo, MOO_SYNERR_WHILE, TOKEN_LOC(moo), TOKEN_NAME(moo));
 | 
							set_syntax_error (moo, MOO_SYNERR_WHILE, TOKEN_LOC(moo), TOKEN_NAME(moo));
 | 
				
			||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
@ -5438,20 +5466,20 @@ static int compile_do_while_expression (moo_t* moo)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (compile_conditional (moo) <= -1) goto oops;
 | 
						if (compile_conditional (moo) <= -1) goto oops;
 | 
				
			||||||
	postcondpos = moo->c->mth.code.len;
 | 
						postcondpos = moo->c->mth.code.len;
 | 
				
			||||||
	jbinst = BCODE_JUMP_BACKWARD_IF_TRUE_0;
 | 
						jbinst = (is_until_loop? BCODE_JUMP_BACKWARD_IF_FALSE_0: BCODE_JUMP_BACKWARD_IF_TRUE_0);
 | 
				
			||||||
	if (precondpos + 1 == postcondpos)
 | 
						if (precondpos + 1 == postcondpos)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* simple optimization - 
 | 
							/* simple optimization - 
 | 
				
			||||||
		 *   if the conditional is known to be true, emit the absolute jump instruction.
 | 
							 *   if the conditional is known to be true, emit the absolute jump instruction.
 | 
				
			||||||
		 *   if it is known to be false, kill all generated instructions. */
 | 
							 *   if it is known to be false, kill all generated instructions. */
 | 
				
			||||||
		if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE)
 | 
							if (moo->c->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_FALSE: BCODE_PUSH_TRUE))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* the conditional is always true. eliminate PUSH_TRUE and emit an absolute jump */
 | 
								/* the conditional is always true. eliminate PUSH_TRUE and emit an absolute jump */
 | 
				
			||||||
			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
								eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
				
			||||||
			postcondpos = precondpos;
 | 
								postcondpos = precondpos;
 | 
				
			||||||
			jbinst = BCODE_JUMP_BACKWARD_0;
 | 
								jbinst = BCODE_JUMP_BACKWARD_0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE)
 | 
							else if (moo->c->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_TRUE: BCODE_PUSH_FALSE))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* the conditional is always false. eliminate PUSH_FALSE and don't emit jump */
 | 
								/* the conditional is always false. eliminate PUSH_FALSE and don't emit jump */
 | 
				
			||||||
			eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
								eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
 | 
				
			||||||
@ -5515,7 +5543,8 @@ static int compile_method_expression (moo_t* moo, int pop)
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		if (compile_if_expression (moo) <= -1) return -1;
 | 
							if (compile_if_expression (moo) <= -1) return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (TOKEN_TYPE(moo) == MOO_IOTOK_WHILE)
 | 
						else if (TOKEN_TYPE(moo) == MOO_IOTOK_WHILE ||
 | 
				
			||||||
 | 
						         TOKEN_TYPE(moo) == MOO_IOTOK_UNTIL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (compile_while_expression (moo) <= -1) return -1;
 | 
							if (compile_while_expression (moo) <= -1) return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -264,17 +264,6 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
 | 
				
			|||||||
				LOG_INST_1 (moo, "jump_backward %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
 | 
									LOG_INST_1 (moo, "jump_backward %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_X:
 | 
					 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
					 | 
				
			||||||
				LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_0:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_1:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_2:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_3:
 | 
					 | 
				
			||||||
				LOG_INST_1 (moo, "jump_forward_if_false %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP_BACKWARD_IF_FALSE_X:
 | 
								case BCODE_JUMP_BACKWARD_IF_FALSE_X:
 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
@ -300,6 +289,16 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
 | 
				
			|||||||
				LOG_INST_1 (moo, "jump_backward_if_true %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
 | 
									LOG_INST_1 (moo, "jump_backward_if_true %zu", (moo_oow_t)(bcode & 0x3)); /* low 2 bits */
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case BCODE_JUMP_FORWARD_IF_FALSE:
 | 
				
			||||||
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
 | 
									LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case BCODE_JUMP_FORWARD_IF_TRUE:
 | 
				
			||||||
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
 | 
									LOG_INST_1 (moo, "jump_forward_if_true %zu", b1);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP2_FORWARD:
 | 
								case BCODE_JUMP2_FORWARD:
 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
				LOG_INST_1 (moo, "jump2_forward %zu", b1);
 | 
									LOG_INST_1 (moo, "jump2_forward %zu", b1);
 | 
				
			||||||
 | 
				
			|||||||
@ -4480,22 +4480,6 @@ int moo_execute (moo_t* moo)
 | 
				
			|||||||
				moo->ip -= (bcode & 0x3); /* low 2 bits */
 | 
									moo->ip -= (bcode & 0x3); /* low 2 bits */
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_X:
 | 
					 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
					 | 
				
			||||||
				LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
 | 
					 | 
				
			||||||
				if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += b1;
 | 
					 | 
				
			||||||
				MOO_STACK_POP (moo);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_0:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_1:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_2:
 | 
					 | 
				
			||||||
			case BCODE_JUMP_FORWARD_IF_FALSE_3:
 | 
					 | 
				
			||||||
				LOG_INST_1 (moo, "jump_forward_if_false %zu", (moo_oow_t)(bcode & 0x3));
 | 
					 | 
				
			||||||
				if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += (bcode & 0x3); /* low 2 bits */
 | 
					 | 
				
			||||||
				MOO_STACK_POP (moo);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case BCODE_JUMP_BACKWARD_IF_FALSE_X:
 | 
								case BCODE_JUMP_BACKWARD_IF_FALSE_X:
 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
				LOG_INST_1 (moo, "jump_backward_if_false %zu", b1);
 | 
									LOG_INST_1 (moo, "jump_backward_if_false %zu", b1);
 | 
				
			||||||
@ -4530,6 +4514,21 @@ int moo_execute (moo_t* moo)
 | 
				
			|||||||
				MOO_STACK_POP (moo);
 | 
									MOO_STACK_POP (moo);
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case BCODE_JUMP_FORWARD_IF_FALSE:
 | 
				
			||||||
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
 | 
									LOG_INST_1 (moo, "jump_forward_if_false %zu", b1);
 | 
				
			||||||
 | 
									if (MOO_STACK_GETTOP(moo) == moo->_false) moo->ip += b1;
 | 
				
			||||||
 | 
									MOO_STACK_POP (moo);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case BCODE_JUMP_FORWARD_IF_TRUE:
 | 
				
			||||||
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
 | 
									LOG_INST_1 (moo, "jump_forward_if_true %zu", b1);
 | 
				
			||||||
 | 
									/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip += b1;*/
 | 
				
			||||||
 | 
									if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip += b1;
 | 
				
			||||||
 | 
									MOO_STACK_POP (moo);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP2_FORWARD:
 | 
								case BCODE_JUMP2_FORWARD:
 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
				LOG_INST_1 (moo, "jump2_forward %zu", b1);
 | 
									LOG_INST_1 (moo, "jump2_forward %zu", b1);
 | 
				
			||||||
@ -4549,6 +4548,14 @@ int moo_execute (moo_t* moo)
 | 
				
			|||||||
				MOO_STACK_POP (moo);
 | 
									MOO_STACK_POP (moo);
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case BCODE_JUMP2_FORWARD_IF_TRUE:
 | 
				
			||||||
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
 | 
									LOG_INST_1 (moo, "jump2_forward_if_true %zu", b1);
 | 
				
			||||||
 | 
									/*if (MOO_STACK_GETTOP(moo) == moo->_true) moo->ip += MAX_CODE_JUMP + b1;*/
 | 
				
			||||||
 | 
									if (MOO_STACK_GETTOP(moo) != moo->_false) moo->ip += MAX_CODE_JUMP + b1;
 | 
				
			||||||
 | 
									MOO_STACK_POP (moo);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case BCODE_JUMP2_BACKWARD_IF_FALSE:
 | 
								case BCODE_JUMP2_BACKWARD_IF_FALSE:
 | 
				
			||||||
				FETCH_PARAM_CODE_TO (moo, b1);
 | 
									FETCH_PARAM_CODE_TO (moo, b1);
 | 
				
			||||||
				LOG_INST_1 (moo, "jump2_backward_if_false %zu", b1);
 | 
									LOG_INST_1 (moo, "jump2_backward_if_false %zu", b1);
 | 
				
			||||||
 | 
				
			|||||||
@ -334,6 +334,7 @@ struct moo_iotok_t
 | 
				
			|||||||
		MOO_IOTOK_ELSIF,
 | 
							MOO_IOTOK_ELSIF,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		MOO_IOTOK_WHILE,
 | 
							MOO_IOTOK_WHILE,
 | 
				
			||||||
 | 
							MOO_IOTOK_UNTIL,
 | 
				
			||||||
		MOO_IOTOK_DO,
 | 
							MOO_IOTOK_DO,
 | 
				
			||||||
		MOO_IOTOK_BREAK,
 | 
							MOO_IOTOK_BREAK,
 | 
				
			||||||
		MOO_IOTOK_CONTINUE
 | 
							MOO_IOTOK_CONTINUE
 | 
				
			||||||
@ -637,10 +638,17 @@ SHORT INSTRUCTION CODE                                        LONG INSTRUCTION C
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
68-71    0100 01XX JUMP_FORWARD                               196  1100 0100 XXXXXXXX JUMP_FORWARD_X
 | 
					68-71    0100 01XX JUMP_FORWARD                               196  1100 0100 XXXXXXXX JUMP_FORWARD_X
 | 
				
			||||||
 | 
					                                                              197  1000 0101 XXXXXXXX JUMP2_FORWARD
 | 
				
			||||||
72-75    0100 10XX JUMP_BACKWARD                              200  1100 1000 XXXXXXXX JUMP_BACKWARD_X
 | 
					72-75    0100 10XX JUMP_BACKWARD                              200  1100 1000 XXXXXXXX JUMP_BACKWARD_X
 | 
				
			||||||
 | 
					                                                              201  1101 1001 XXXXXXXX JUMP2_BACKWARD
 | 
				
			||||||
76-79    0100 11XX JUMP_BACKWARD_IF_FALSE                     204  1100 1100 XXXXXXXX JUMP_BACKWARD_IF_FALSE_X
 | 
					76-79    0100 11XX JUMP_BACKWARD_IF_FALSE                     204  1100 1100 XXXXXXXX JUMP_BACKWARD_IF_FALSE_X
 | 
				
			||||||
80-83    0101 00XX JUMP_FORWARD_IF_FALSE                      208  1101 0000 XXXXXXXX JUMP_FORWARD_IF_FALSE_X
 | 
					                                                              205  1101 1101 XXXXXXXX JUMP2_BACKWARD_IF_FALSE
 | 
				
			||||||
84-87    0101 01XX JUMP_FORWARD_IF_TRUE                       212  1101 0100 XXXXXXXX JUMP_FORWARD_IF_TRUE_X
 | 
					80-83    0101 00XX JUMP_BACKWARD_IF_TRUE                      208  1101 0000 XXXXXXXX JUMP_BACKWARD_IF_TRUE_X
 | 
				
			||||||
 | 
					                                                              209  1101 0001 XXXXXXXX JUMP2_FORWARD_IF_TRUE
 | 
				
			||||||
 | 
					84-87    0101 01XX UNUSED                                     212  1101 0100 XXXXXXXX JUMP_FORWARD_IF_FALSE
 | 
				
			||||||
 | 
					                                                              213  1101 0101 XXXXXXXX JUMP2_FORWARD_IF_FALSE
 | 
				
			||||||
 | 
					                                                              214  1101 0110 XXXXXXXX JUMP_FORWARD_IF_TRUE
 | 
				
			||||||
 | 
					                                                              215  1101 0111 XXXXXXXX JUMP2_FORWARD_IF_TRUE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                                                        vv
 | 
					                                                                        vv
 | 
				
			||||||
88-91    0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR             216  1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X        (bit 3 on, bit 2 off)
 | 
					88-91    0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR             216  1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X        (bit 3 on, bit 2 off)
 | 
				
			||||||
@ -761,25 +769,22 @@ enum moo_bcode_t
 | 
				
			|||||||
	BCODE_JUMP_FORWARD_2           = 0x46, /* 70 */
 | 
						BCODE_JUMP_FORWARD_2           = 0x46, /* 70 */
 | 
				
			||||||
	BCODE_JUMP_FORWARD_3           = 0x47, /* 71 */
 | 
						BCODE_JUMP_FORWARD_3           = 0x47, /* 71 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_0          = 0x48,
 | 
						BCODE_JUMP_BACKWARD_0          = 0x48, /* 72 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_1          = 0x49,
 | 
						BCODE_JUMP_BACKWARD_1          = 0x49, /* 73 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_2          = 0x4A,
 | 
						BCODE_JUMP_BACKWARD_2          = 0x4A, /* 74 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_3          = 0x4B,
 | 
						BCODE_JUMP_BACKWARD_3          = 0x4B, /* 75 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_JUMP_FORWARD_IF_FALSE_0  = 0x4C, /* 76 */
 | 
						BCODE_JUMP_BACKWARD_IF_FALSE_0 = 0x4C, /* 76 */
 | 
				
			||||||
	BCODE_JUMP_FORWARD_IF_FALSE_1  = 0x4D, /* 77 */
 | 
						BCODE_JUMP_BACKWARD_IF_FALSE_1 = 0x4D, /* 77 */
 | 
				
			||||||
	BCODE_JUMP_FORWARD_IF_FALSE_2  = 0x4E, /* 78 */
 | 
						BCODE_JUMP_BACKWARD_IF_FALSE_2 = 0x4E, /* 78 */
 | 
				
			||||||
	BCODE_JUMP_FORWARD_IF_FALSE_3  = 0x4F, /* 79 */
 | 
						BCODE_JUMP_BACKWARD_IF_FALSE_3 = 0x4F, /* 79 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_FALSE_0 = 0x50, /* 80 */
 | 
						BCODE_JUMP_BACKWARD_IF_TRUE_0  = 0x50, /* 80 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_FALSE_1 = 0x51, /* 81 */
 | 
						BCODE_JUMP_BACKWARD_IF_TRUE_1  = 0x51, /* 81 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_FALSE_2 = 0x52, /* 82 */
 | 
						BCODE_JUMP_BACKWARD_IF_TRUE_2  = 0x52, /* 82 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_FALSE_3 = 0x53, /* 83 */
 | 
						BCODE_JUMP_BACKWARD_IF_TRUE_3  = 0x53, /* 83 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_TRUE_0  = 0x54, /* 84 */
 | 
						/* UNUSED  0x54 - 0x57 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_TRUE_1  = 0x55, /* 85 */
 | 
					 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_TRUE_2  = 0x56, /* 86 */
 | 
					 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_TRUE_3  = 0x57, /* 87 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_STORE_INTO_CTXTEMPVAR_0  = 0x58, /* 88 */
 | 
						BCODE_STORE_INTO_CTXTEMPVAR_0  = 0x58, /* 88 */
 | 
				
			||||||
	BCODE_STORE_INTO_CTXTEMPVAR_1  = 0x59, /* 89 */
 | 
						BCODE_STORE_INTO_CTXTEMPVAR_1  = 0x59, /* 89 */
 | 
				
			||||||
@ -859,12 +864,15 @@ enum moo_bcode_t
 | 
				
			|||||||
	BCODE_JUMP_BACKWARD_X          = 0xC8, /* 200 ## */
 | 
						BCODE_JUMP_BACKWARD_X          = 0xC8, /* 200 ## */
 | 
				
			||||||
	BCODE_JUMP2_BACKWARD           = 0xC9, /* 201 */
 | 
						BCODE_JUMP2_BACKWARD           = 0xC9, /* 201 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_JUMP_FORWARD_IF_FALSE_X  = 0xCC, /* 204 ## */
 | 
						BCODE_JUMP_BACKWARD_IF_FALSE_X = 0xCC, /* 204 ## */
 | 
				
			||||||
	BCODE_JUMP2_FORWARD_IF_FALSE   = 0xCD, /* 205 */
 | 
						BCODE_JUMP2_BACKWARD_IF_FALSE  = 0xCD, /* 205 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_FALSE_X = 0xD0, /* 208 ## */
 | 
						BCODE_JUMP_BACKWARD_IF_TRUE_X  = 0xD0, /* 208 ## */
 | 
				
			||||||
	BCODE_JUMP2_BACKWARD_IF_FALSE  = 0xD1, /* 209 */
 | 
						BCODE_JUMP2_BACKWARD_IF_TRUE   = 0xD1, /* 209 */
 | 
				
			||||||
	BCODE_JUMP_BACKWARD_IF_TRUE_X  = 0xD4, /* 212 ## */
 | 
					
 | 
				
			||||||
	BCODE_JUMP2_BACKWARD_IF_TRUE   = 0xD5, /* 213 */
 | 
						BCODE_JUMP_FORWARD_IF_FALSE    = 0xD4, /* 212 ## */
 | 
				
			||||||
 | 
						BCODE_JUMP2_FORWARD_IF_FALSE   = 0xD5, /* 213 */
 | 
				
			||||||
 | 
						BCODE_JUMP_FORWARD_IF_TRUE     = 0xD6, /* 214 ## */
 | 
				
			||||||
 | 
						BCODE_JUMP2_FORWARD_IF_TRUE    = 0xD7, /* 215 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BCODE_STORE_INTO_CTXTEMPVAR_X  = 0xD8, /* 216 ## */
 | 
						BCODE_STORE_INTO_CTXTEMPVAR_X  = 0xD8, /* 216 ## */
 | 
				
			||||||
	BCODE_POP_INTO_CTXTEMPVAR_X    = 0xDC, /* 220 ## */
 | 
						BCODE_POP_INTO_CTXTEMPVAR_X    = 0xDC, /* 220 ## */
 | 
				
			||||||
@ -888,7 +896,7 @@ enum moo_bcode_t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	BCODE_MAKE_ARRAY                 = 0xF5, /* 245 */
 | 
						BCODE_MAKE_ARRAY                 = 0xF5, /* 245 */
 | 
				
			||||||
	BCODE_POP_INTO_ARRAY             = 0xF6, /* 246 */
 | 
						BCODE_POP_INTO_ARRAY             = 0xF6, /* 246 */
 | 
				
			||||||
	BCODE_DUP_STACKTOP               = 0xF7,
 | 
						BCODE_DUP_STACKTOP               = 0xF7, /* 247 */
 | 
				
			||||||
	BCODE_POP_STACKTOP               = 0xF8,
 | 
						BCODE_POP_STACKTOP               = 0xF8,
 | 
				
			||||||
	BCODE_RETURN_STACKTOP            = 0xF9, /* ^something */
 | 
						BCODE_RETURN_STACKTOP            = 0xF9, /* ^something */
 | 
				
			||||||
	BCODE_RETURN_RECEIVER            = 0xFA, /* ^self */
 | 
						BCODE_RETURN_RECEIVER            = 0xFA, /* ^self */
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user