#include 'Apex.st'. #include 'Object.st'. #include 'UndefinedObject.st'. #include 'Class.st'. #include 'Boolean.st'. #class Error(Object) { #method(#class) signal: aString { "accept an arbitary object instead of a string. the object can be sent displayString for string conversion" } } #class Magnitude(Object) { } #class Association(Magnitude) { #dcl key value. } #class Character(Magnitude) { } #class Number(Magnitude) { #method add: aNumber { } #method + aNumber { } #method - aNumber { } #method * aNumber { } #method = aNumber { } #method < aNumber { } #method > aNumber { } #method to: end by: step do: aBlock { | i | i := self. (step > 0) ifTrue: [ [ i <= end ] whileTrue: [ aBlock value: i. i := i + step. ] ] ifFalse: [ [ i >= end ] whileTrue: [ aBlock value: i. i := i - step. ] ]. } #method to: end do: aBlock { ^self to: end by: 1 do: aBlock. } } #class SmallInteger(Number) { } #include 'Collection.st'. #include 'Collection-ByteArray.st'. #include 'Collection-Array.st'. #include 'Collection-Set.st'. #class(#pointer) Context(Apex) { } #class(#pointer) MethodContext(Context) { #dcl sender ip sp ntmprs method receiver home origin. #method pc { ^ip } #method pc: anInteger { ip := anInteger. "sp := sp - 1." "whould this always work??? " } #method sp { ^sp. } #method sp: anInteger { sp := anInteger. } #method pc: aPC sp: aSP { ip := aPC. sp := aSP. ##sp := sp - 1. } } #class(#pointer) BlockContext(Context) { #dcl caller ip sp ntmprs nargs source home origin. #method value { } #method value: a { } #method value: a value: b { } #method value: a value: b value: c { } #method whileTrue: aBlock { ## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without ## ---------------------------------------------------------------------------- ## ^(self value) ifTrue: [aBlock value. self whileTrue: aBlock]. ## ---------------------------------------------------------------------------- ## less block context before whileTrue: is recursively sent. ## whileTrue: is sent in a method context. ## (self value) ifFalse: [^nil]. ## aBlock value. ## self whileTrue: aBlock. ## ---------------------------------------------------------------------------- ## ---------------------------------------------------------------------------- | pc sp xsp | sp := thisContext sp. sp := sp - 1. "decrement sp by 1 becuase thisContext pushed above affects the sp method" pc := thisContext pc. self value ifFalse: [ ^nil "^self" ]. aBlock value. ##thisContext pc: pc - 3 sp: sp. ##thisContext pc: pc + 2 sp: sp. thisContext pc: pc + 1 sp: sp. ## this +2 or - 3 above is dependent on the byte code instruction size used for 'store' ## +2 to skip STORE_INTO_TEMP(pc) and POP_STACKTOP. ## TODO: make it independent of the byte code size ## ---------------------------------------------------------------------------- ## #