implemented until and do..until loop
This commit is contained in:
parent
04864659a8
commit
6fe65f66fc
@ -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>
|
<primitive: #_perform>
|
||||||
self primitiveFailed
|
self primitiveFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
method perform: selector
|
method(#dual) perform: selector with: arg1 with: arg2
|
||||||
{
|
{
|
||||||
<primitive: #_perform>
|
<primitive: #_perform>
|
||||||
self primitiveFailed
|
self primitiveFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
method(#class) perform: selector with: arg1
|
method(#dual) perform: selector with: arg1 with: arg2 with: arg3
|
||||||
{
|
|
||||||
<primitive: #_perform>
|
|
||||||
self primitiveFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
method perform: selector with: arg1
|
|
||||||
{
|
|
||||||
<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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user