--- a/Block.st Sat Jan 25 21:55:08 2020 +0000
+++ b/Block.st Wed May 20 18:34:29 2020 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
COPYRIGHT (c) 2015 Jan Vrany
@@ -17,7 +19,7 @@
CompiledCode variableSubclass:#Block
instanceVariableNames:'home nargs sourcePos initialPC'
- classVariableNames:'InvalidNewSignal'
+ classVariableNames:''
poolDictionaries:''
category:'Kernel-Methods'
!
@@ -88,9 +90,9 @@
coll do:[:eachElement | Transcript showCR:eachElement ].
Blocks keep a reference to the context where it was declared -
- this allows blocks to access the methods arguments and/or variables.
+ this allows blocks to access the method's arguments and/or variables.
This is still true after the method has returned - since the
- block keeps this reference, the methods context will NOT die in this case.
+ block keeps this reference, the method's context will NOT die in this case.
(for experts: Smalltalk blocks are technically lambdas/closures)
A return (via ^-statement) out of a block will force a return from the
@@ -337,20 +339,6 @@
"
! !
-!Block class methodsFor:'initialization'!
-
-initialize
- "create signals raised by various errors"
-
- InvalidNewSignal isNil ifTrue:[
- InvalidNewSignal := Error newSignalMayProceed:false.
- InvalidNewSignal nameClass:self message:#invalidNewSignal.
- InvalidNewSignal notifierString:'blocks are only created by the system'.
- ]
-
- "Modified: 22.4.1996 / 16:34:20 / cg"
-! !
-
!Block class methodsFor:'instance creation'!
byteCode:bCode numArgs:numArgs numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
@@ -365,17 +353,15 @@
"create a new cheap (homeless) block.
Not for public use - this is a special hook for the compiler."
- |newBlock|
-
- newBlock := (super basicNew:(literals size))
+ ^ (self basicNew:literals size)
byteCode:bCode
numArgs:numArgs
numVars:numVars
numStack:nStack
sourcePosition:sourcePos
initialPC:initialPC
- literals:literals.
- ^ newBlock
+ literals:literals;
+ yourself.
"Modified: 24.6.1996 / 12:36:48 / stefan"
"Created: 13.4.1997 / 00:04:09 / cg"
@@ -386,13 +372,13 @@
If you really need a block (assuming, you are some compiler),
use basicNew and setup the instance carefully"
- ^ InvalidNewSignal raise.
+ ^ MethodNotAppropriateError raiseErrorString:'blocks are only created by the system'.
!
new:size
"catch creation of blocks - only the system creates blocks"
- ^ InvalidNewSignal raise.
+ ^ MethodNotAppropriateError raiseErrorString:'blocks are only created by the system'.
! !
!Block class methodsFor:'queries'!
@@ -407,6 +393,7 @@
! !
+
!Block methodsFor:'Compatibility-ANSI'!
argumentCount
@@ -532,7 +519,7 @@
"activate the receiver with one or zero arguments.
Squeak compatibility, but also present in VW Smalltalk"
- nargs >= 1 ifTrue:[^ self value:optionalFirstArg].
+ nargs > 0 ifTrue:[^ self value:optionalFirstArg].
^ self value
!
@@ -541,7 +528,7 @@
Squeak compatibility, but also present in VW Smalltalk"
nargs >= 2 ifTrue:[^ self value:optionalFirstArg value:optionalSecondArg].
- nargs = 1 ifTrue:[^ self value:optionalFirstArg].
+ nargs == 1 ifTrue:[^ self value:optionalFirstArg].
^ self value
!
@@ -555,7 +542,7 @@
].
^ self value:optionalFirstArg value:optionalSecondArg
].
- nargs = 1 ifTrue:[^ self value:optionalFirstArg].
+ nargs == 1 ifTrue:[^ self value:optionalFirstArg].
^ self value
!
@@ -570,22 +557,14 @@
|numArgs|
numArgs := handlerBlock isBlock ifTrue:[handlerBlock argumentCount] ifFalse:[0].
- numArgs == 1 ifTrue:[
+ numArgs <= 1 ifTrue:[
^ self on:Error do:handlerBlock
].
^ self
on:Error
do:[:ex |
- |errString errReceiver|
-
- numArgs == 0 ifTrue:[
- ex return:handlerBlock value
- ] ifFalse:[
- errString := ex description.
- errReceiver := ex suspendedContext receiver.
- ex return:(handlerBlock value:errString value:errReceiver)
- ].
+ ex return:(handlerBlock value:ex description value:ex suspendedContext receiver)
]
"
@@ -608,6 +587,8 @@
a := 0.
[ 123 / a ] ifError:[self halt]
"
+
+ "Modified: / 18-03-2017 / 18:19:20 / stefan"
!
timeToRun
@@ -712,7 +693,45 @@
"Created: / 28-08-2010 / 14:41:15 / cg"
! !
-
+!Block methodsFor:'Javascript support'!
+
+_at:index
+ "this is a synthetic selector, generated by the compiler,
+ if a construct of the form expr[idx] is parsed.
+ I.e.
+ foo[n]
+ generates
+ foo _at: n
+ "
+
+ ^ self value:index
+
+ "
+ |double|
+
+ double := [:n | n*2].
+ double[10]
+ "
+!
+
+_at:index1 at:index2
+ "this is a synthetic selector, generated by the compiler,
+ if a construct of the form expr[idx] is parsed.
+ I.e.
+ foo[n][m]
+ generates
+ foo _at:n at:m
+ "
+ ^ self value:index1 value:index2
+
+ "
+ |doubleDiv|
+
+ doubleDiv := [:n :d | n*2/d].
+ doubleDiv[10][3].
+ doubleDiv[10 . 3].
+ "
+! !
!Block methodsFor:'accessing'!
@@ -747,9 +766,11 @@
<resource: #obsolete>
+ self obsoleteMethodWarning:'use #homeMethod'.
^ self homeMethod
- "Modified: 19.6.1997 / 16:15:24 / cg"
+ "Modified: / 19-06-1997 / 16:15:24 / cg"
+ "Modified: / 23-06-2017 / 10:47:00 / stefan"
!
methodHome
@@ -763,11 +784,11 @@
!
numArgs
+ <resource: #obsolete> "/ but left in for a while, for performance and Squeak compatibility
+
"return the number of arguments I expect for evaluation.
Please use argumentCount for ANSI compatibility"
-"/ <resource: #obsolete>
-
^ nargs
! !
@@ -780,10 +801,34 @@
!Block methodsFor:'conversion'!
+asBlock
+ ^ self
+
+ "Created: / 17-05-2019 / 15:09:21 / Claus Gittinger"
+!
+
+asIterator
+ "return myself as an iterator.
+ that is a collection which uses the receiver block to
+ generate the elements."
+
+ ^ Iterator on:self.
+
+ "
+ |coll|
+
+ coll := [:action | 1 to:20 do:action] asIterator.
+ coll do:[:each | Transcript showCR:each].
+ "
+
+ "Created: / 09-02-2019 / 15:31:10 / Claus Gittinger"
+!
+
asVarArgBlock
"convert myself into a varArg block;
this one has 1 formal argument, which gets the list
- of actual arguments when evaluated."
+ of actual arguments when evaluated
+ (similar to rest arg in scheme)."
nargs ~~ 1 ifTrue:[
self error:'vararg blocks must take exactly 1 argument - the arg list'.
@@ -805,8 +850,8 @@
b value:'arg1' value:'arg2' value:'arg3' value:'arg4'
"
- "Created: 23.1.1997 / 13:35:28 / cg"
- "Modified: 23.1.1997 / 13:35:48 / cg"
+ "Created: / 23-01-1997 / 13:35:28 / cg"
+ "Modified (comment): / 28-06-2019 / 12:37:23 / Claus Gittinger"
!
beCurryingBlock
@@ -858,6 +903,14 @@
"Created: 23.1.1997 / 13:35:28 / cg"
"Modified: 23.1.1997 / 13:35:48 / cg"
+!
+
+literalArrayEncoding
+ "I have none"
+
+ ^ nil
+
+ "Created: / 11-02-2019 / 16:50:58 / sr"
! !
!Block methodsFor:'copying'!
@@ -881,11 +934,12 @@
!Block methodsFor:'debugging'!
benchmark:anInfoString
- "evaluate myseld and show the timing info on Transcript"
+ "evaluate myself and show the timing info on Transcript"
|startTime endTime startCycles endCycles overhead overheadCycles
micros millis cycles|
+ "/warmup before executing self
startTime := OperatingSystem getMicrosecondTime.
startCycles := OperatingSystem getCPUCycleCount.
[123] value.
@@ -893,7 +947,7 @@
endTime := OperatingSystem getMicrosecondTime.
overhead := endTime - startTime.
"/ just in case, the OS does not support cpu cycles
- overheadCycles := endCycles - startCycles.
+ startCycles notNil ifTrue:[ overheadCycles := endCycles - startCycles ].
startTime := OperatingSystem getMicrosecondTime.
startCycles := OperatingSystem getCPUCycleCount.
@@ -902,13 +956,16 @@
endTime := OperatingSystem getMicrosecondTime.
micros := (endTime - startTime - overhead) max:0.
+ "/ just in case, the OS does not support cpu cycles
+ startCycles notNil ifTrue:[
cycles := (endCycles - startCycles - overheadCycles) max:0.
+ ].
Transcript show:anInfoString.
micros < 1000 ifTrue:[
"/ too stupid: many fonts do not have a mu,
"/ so I output it as us here.
- Transcript show:micros; show:' s'.
+ Transcript show:micros; show:' µs'.
] ifFalse:[
micros < 100000 ifTrue:[
millis := (micros / 1000.0) asFixedPointRoundedToScale:2.
@@ -918,7 +975,7 @@
Transcript show:(TimeDuration milliseconds:millis).
].
].
- cycles ~~ 0 ifTrue:[
+ cycles notNil ifTrue:[
Transcript show:' ('; show:cycles; show:' cycles)'.
].
Transcript cr.
@@ -936,6 +993,8 @@
[10 factorial] benchmark:'11 factorial:'
[100 factorial] benchmark:'100 factorial:'
"
+
+ "Modified (comment): / 23-02-2017 / 21:06:29 / mawalch"
! !
!Block methodsFor:'error handling'!
@@ -1532,17 +1591,16 @@
i.e. change the priority for the execution of the receiver.
Bad name: should be called evaluateWithPriority: or similar"
- |oldPrio retVal activeProcess|
+ |oldPrio activeProcess|
activeProcess := Processor activeProcess.
oldPrio := Processor activePriority.
- [
+ ^ [
activeProcess priority:priority.
- retVal := self value.
+ self value.
] ensure:[
activeProcess priority:oldPrio
].
- ^ retVal
"
[
@@ -1552,7 +1610,8 @@
] valueAt:3
"
- "Created: / 29.7.1998 / 19:19:48 / cg"
+ "Created: / 29-07-1998 / 19:19:48 / cg"
+ "Modified: / 23-06-2017 / 11:13:30 / stefan"
!
valueWithArguments:argArrayIn
@@ -1940,13 +1999,191 @@
"
! !
+!Block methodsFor:'evaluation with timeout'!
+
+valueWithConfirmedTimeout:secondsOrTimeDuration confirmWith:confirmationBlock
+ "evaluate the receiver.
+ If not finished after secondsOrTimeDuration, call the confirmationBlock.
+ If it returns true, another time-interval is setup and we continue waiting.
+ If it returns a number (seconds) or a timeDuration, this time-interval is setup and we continue waiting.
+ If it returns false, nil is returned immediately.
+
+ The receiver's code must be prepared
+ for premature returning (by adding ensure blocks, as required)"
+
+ |ok retVal interrupter|
+
+ ok := false.
+ interrupter := [ ok ifFalse:[ TimeoutError raiseRequest ] ].
+ [
+ Processor addTimedBlock:interrupter after:secondsOrTimeDuration.
+
+ TimeoutError handle:[:ex |
+ |answer nextWaitTime|
+
+ answer := confirmationBlock valueWithOptionalArgument:ex.
+ answer == false ifTrue:[
+ ^ nil
+ ].
+ answer == true ifTrue:[
+ nextWaitTime := secondsOrTimeDuration
+ ] ifFalse:[
+ nextWaitTime := answer asTimeDuration
+ ].
+ "/ proceed, setting up another timeout
+ Processor addTimedBlock:interrupter after:nextWaitTime.
+ ex proceed
+ ] do:[
+ retVal := self value.
+ ok := true.
+ ].
+ ] ensure:[
+ Processor removeTimedBlock:interrupter.
+ ].
+ ^ retVal
+
+ "
+ [
+ 1 to:10 do:[:i |
+ Transcript showCR:i.
+ 1 seconds wait.
+ ].
+ 'finished'
+ ] valueWithConfirmedTimeout:(3 seconds) confirmWith:[
+ (Dialog confirm:'continue?')
+ ].
+ "
+
+ "
+ [
+ 1 to:10 do:[:i |
+ Transcript showCR:i.
+ 1 seconds wait.
+ ].
+ 'finished'
+ ] valueWithConfirmedTimeout:(3 seconds) confirmWith:[
+ (Dialog confirm:'wait another 5 seconds?') ifTrue:[
+ 5
+ ] ifFalse:[
+ false
+ ].
+ ].
+ "
+
+ "Created: / 26-06-2019 / 11:46:02 / Claus Gittinger"
+!
+
+valueWithTimeout:aTimeDurationOrIntegerSeconds
+ "execute the receiver, but abort the evaluation after aTimeDuration if still running.
+ Return the receiver's value, or nil if aborted.
+
+ The receiver's code must be prepared
+ for premature returning (by adding ensure blocks, as required)"
+
+ |milliseconds|
+
+ milliseconds := aTimeDurationOrIntegerSeconds isTimeDuration
+ ifTrue:[ aTimeDurationOrIntegerSeconds asMilliseconds ]
+ ifFalse:[ (aTimeDurationOrIntegerSeconds * 1000) truncated].
+ ^ self valueWithWatchDog:[nil] afterMilliseconds:milliseconds
+
+ "
+ [
+ 1 to:15 do:[:round |
+ Transcript showCR:round.
+ Delay waitForMilliseconds:20.
+ ].
+ true
+ ] valueWithTimeout:(TimeDuration seconds:1)
+ "
+
+ "
+ [
+ 1 to:100 do:[:round |
+ Transcript showCR:round.
+ Delay waitForMilliseconds:20.
+ ].
+ true
+ ] valueWithTimeout:(TimeDuration seconds:1)
+ "
+
+ "Modified (comment): / 26-06-2019 / 11:53:25 / Claus Gittinger"
+!
+
+valueWithWatchDog:exceptionBlock afterMilliseconds:aTimeLimit
+ "a watchdog on a block's execution. If the block does not finish its
+ evaluation after aTimeLimit milliseconds, it is interrupted (aborted) and
+ exceptionBlock's value is returned.
+
+ The receiver's code must be prepared
+ for premature returning (by adding ensure blocks, as required)"
+
+ |inError|
+
+ inError := false.
+
+ ^ TimeoutNotification handle:[:ex |
+ inError ifTrue:[
+ ex proceed
+ ].
+ exceptionBlock valueWithOptionalArgument:ex.
+ ] do:[
+ NoHandlerError handle:[:ex |
+ inError := true.
+ ex reject.
+ ] do:[
+ |showStopper me done|
+
+ done := false.
+ me := Processor activeProcess.
+ showStopper := [
+ done ifFalse:[
+ me interruptWith:[
+ (done not and:[me isDebugged not]) ifTrue:[
+ TimeoutNotification raiseRequest.
+ ]
+ ]
+ ]
+ ].
+
+ [
+ |retVal|
+
+ Processor
+ addTimedBlock:showStopper
+ for:me
+ afterMilliseconds:aTimeLimit.
+
+ retVal := self value.
+ done := true.
+ retVal
+ ] ensure:[
+ Processor removeTimedBlock:showStopper
+ ].
+ ]
+ ].
+
+ "
+ [
+ Delay waitForSeconds:5.
+ true
+ ] valueWithWatchDog:[false] afterMilliseconds:2000
+ "
+
+ "Modified: / 21-05-2010 / 12:19:57 / sr"
+ "Modified: / 19-03-2017 / 18:13:07 / cg"
+ "Modified: / 31-01-2018 / 08:34:51 / stefan"
+ "Modified: / 23-05-2018 / 12:47:00 / Maren"
+ "Modified (comment): / 26-06-2019 / 11:53:29 / Claus Gittinger"
+! !
+
!Block methodsFor:'exception handling'!
on:aSignalOrSignalSetOrException do:exceptionBlock
"added for ANSI compatibility; evaluate the receiver,
handling aSignalOrSignalSetOrException.
If the signal is raised during evaluation,
- the 2nd argument, exceptionBlock is evaluated (and its value returned"
+ the 2nd argument, exceptionBlock is evaluated (and its value returned)"
<context: #return>
<exception: #handle>
@@ -1972,7 +2209,8 @@
] on:Error do:[:ex| 2 ]
"
- "Modified: / 26.7.1999 / 15:30:48 / stefan"
+ "Modified: / 26-07-1999 / 15:30:48 / stefan"
+ "Modified (comment): / 26-06-2019 / 11:55:55 / Claus Gittinger"
!
on:aSignalOrSignalSetOrException do:exceptionBlock ensure:ensureBlock
@@ -2000,23 +2238,39 @@
e := 0.
[
1 foo
- ] on:MessageNotUnderstood
- do:[:ex | self halt]
- ensure:[ e := 1 ].
+ ] on:MessageNotUnderstood do:[:ex |
+ self halt
+ ] ensure:[
+ e := 1
+ ].
self assert:(e == 1).
"
"
+ [
+ 1 foo
+ ] on:MessageNotUnderstood do:[:ex |
+ ^ self
+ ] ensure:[
+ Transcript showCR:'ensure ensured'
+ ].
+ "
+
+ "
|e|
e := 0.
[
1 negated
- ] on:MessageNotUnderstood
- do:[:ex | self halt]
- ensure:[ e := 1 ].
+ ] on:MessageNotUnderstood do:[:ex |
+ self halt
+ ] ensure:[
+ e := 1
+ ].
self assert:(e == 1).
"
+
+ "Modified (comment): / 30-05-2018 / 21:20:14 / Claus Gittinger"
!
on:aSignalOrSignalSetOrException do:exceptionBlock ifCurtailed:curtailBlock
@@ -2076,6 +2330,20 @@
ifCurtailed:[ e := 1 ].
self assert:(e == 0).
"
+
+
+ "
+ |e|
+
+ e := 0.
+ [
+ 1 foo
+ ] on:MessageNotUnderstood do:[:ex | 2 bla]
+ ifCurtailed:[ e := 1 ].
+ self assert:(e == 0).
+ "
+
+ "Modified (comment): / 23-03-2017 / 19:10:31 / stefan"
!
on:anExceptionHandler do:exceptionBlock on:anExceptionHandler2 do:anExceptionBlock2
@@ -2117,96 +2385,6 @@
"Created: / 26.7.1999 / 11:23:45 / stefan"
"Modified: / 26.7.1999 / 11:24:06 / stefan"
-!
-
-valueWithTimeout:aTimeDurationOrIntegerSeconds
- "execute the receiver, but abort the evaluation after aTimeDuration if still running.
- Return the receiver's value, or nil if aborted."
-
- |milliseconds|
-
- milliseconds := aTimeDurationOrIntegerSeconds isTimeDuration
- ifTrue:[ aTimeDurationOrIntegerSeconds asMilliseconds ]
- ifFalse:[ (aTimeDurationOrIntegerSeconds * 1000) truncated].
- ^ self valueWithWatchDog:[^ nil] afterMilliseconds:milliseconds
-
- "
- [
- 1 to:15 do:[:round |
- Transcript showCR:round.
- Delay waitForMilliseconds:20.
- ].
- true
- ] valueWithTimeout:(TimeDuration seconds:1)
- "
-
- "
- [
- 1 to:100 do:[:round |
- Transcript showCR:round.
- Delay waitForMilliseconds:20.
- ].
- true
- ] valueWithTimeout:(TimeDuration seconds:1)
- "
-!
-
-valueWithWatchDog:exceptionBlock afterMilliseconds:aTimeLimit
- "a watchdog on a block's execution. If the block does not finish its
- evaluation after aTimeLimit milliseconds, it is interrupted (aborted) and
- exceptionBlock's value is returned. The receiver's code must be prepared
- for premature returning (by adding ensure blocks, as required)"
-
- |showStopper me retVal done inError|
-
- done := false.
- me := Processor activeProcess.
-
- showStopper :=
- [
- done ifFalse:[
- me interruptWith:[
- (Processor activeProcess state ~~ #debug) ifTrue:[
- done ifFalse:[ TimeoutNotification raiseRequest ]
- ]
- ]
- ]
- ].
-
- TimeoutNotification handle:[:ex |
- inError ifTrue:[
- ex proceed
- ].
- retVal := exceptionBlock value.
- ] do:[
- NoHandlerError handle:[:ex |
- inError := true.
- ex reject.
- ] do:[
- [
- Processor
- addTimedBlock:showStopper
- for:me
- afterMilliseconds:aTimeLimit.
-
- retVal := self value.
- done := true.
- ] ensure:[
- Processor removeTimedBlock:showStopper
- ].
- ]
- ].
- ^ retVal
-
- "
- [
- Delay waitForSeconds:5.
- true
- ] valueWithWatchDog:[false] afterMilliseconds:2000
- "
-
- "Modified: / 21-05-2010 / 12:19:57 / sr"
- "Modified: / 18-01-2011 / 19:24:13 / cg"
! !
!Block methodsFor:'exception handling private'!
@@ -2220,20 +2398,7 @@
exceptionCreator := anException creator.
exceptionHandlerInContext := aContext argAt:1.
exceptionHandlerInContext isExceptionHandler ifFalse:[
- exceptionHandlerInContext isNil ifTrue:[
- 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ] ifFalse:[
- (exceptionHandlerInContext isBehavior
- and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
- "If the exception class is still autoloaded,
- it does not accept our exception. Raising the exception would load the class"
- ^ nil
- ] ifFalse:[
- 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ]
- ].
- aContext fullPrintString errorPrintCR.
- self breakPoint:#cg.
+ GenericException printBadExceptionHandler:exceptionHandlerInContext in:aContext.
^ nil.
].
(exceptionHandlerInContext accepts:exceptionCreator) ifTrue:[
@@ -2242,20 +2407,7 @@
exceptionHandlerInContext := aContext argAt:3.
exceptionHandlerInContext isExceptionHandler ifFalse:[
- exceptionHandlerInContext isNil ifTrue:[
- 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ] ifFalse:[
- (exceptionHandlerInContext isBehavior
- and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
- "If the exception class is still autoloaded,
- it does not accept our exception. Raising the exception would load the class"
- ^ nil
- ] ifFalse:[
- 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ]
- ].
- aContext fullPrintString errorPrintCR.
- self breakPoint:#cg.
+ GenericException printBadExceptionHandler:exceptionHandlerInContext in:aContext.
^ nil.
].
(exceptionHandlerInContext accepts:exceptionCreator) ifTrue:[
@@ -2268,89 +2420,59 @@
^ aContext argAt:1.
!
-handlerForSignal:exceptionCreator context:theContext originator:originator
+handlerForSignal:exceptionCreator context:aContext originator:originator
"answer the handler block for the exceptionCreator from originator.
The handler block is retrieved from aContext.
Answer nil if the exceptionCreator is not handled."
|selector exceptionHandlerInContext|
- selector := theContext selector.
+ selector := aContext selector.
(selector == #on:do:
or:[ selector == #on:do:ensure:
or:[ selector == #on:do:ifCurtailed: ]]
) ifTrue:[
- exceptionHandlerInContext := theContext argAt:1.
+ exceptionHandlerInContext := aContext argAt:1.
exceptionHandlerInContext isExceptionHandler ifFalse:[
- exceptionHandlerInContext isNil ifTrue:[
- 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ] ifFalse:[(exceptionHandlerInContext isBehavior
- and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
- "If the exception class is still autoloaded,
- it does not accept our exception. Raising the exception would load the class"
- ^ nil
- ] ifFalse:[
- 'Block [warning]: non-ExceptionHandler in on:do:-context' errorPrintCR.
- ]].
- theContext fullPrint.
+ GenericException printBadExceptionHandler:exceptionHandlerInContext in:aContext.
^ nil.
].
(exceptionHandlerInContext == exceptionCreator
or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
selector == #on:do:ifCurtailed: ifTrue:[
- theContext unmarkForUnwind. "if there is a handler, no unwind block has to be performed"
+ aContext unmarkForUnwind. "if there is a handler, no unwind block has to be performed"
].
- ^ (theContext argAt:2) ? [nil].
+ ^ (aContext argAt:2) ? [nil].
].
^ nil
].
selector == #on:do:on:do: ifTrue:[
- exceptionHandlerInContext := theContext argAt:1.
+ exceptionHandlerInContext := aContext argAt:1.
exceptionHandlerInContext isExceptionHandler ifFalse:[
- exceptionHandlerInContext isNil ifTrue:[
- 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ] ifFalse:[(exceptionHandlerInContext isBehavior
- and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
- "If the exception class is still autoloaded,
- it does not accept our exception. Raising the exception would load the class"
- ^ nil
- ] ifFalse:[
- 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ]].
- theContext fullPrint.
+ GenericException printBadExceptionHandler:exceptionHandlerInContext in:aContext.
^ nil.
].
(exceptionHandlerInContext == exceptionCreator
or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
- ^ (theContext argAt:2) ? [nil].
+ ^ (aContext argAt:2) ? [nil].
].
- exceptionHandlerInContext := theContext argAt:3.
+ exceptionHandlerInContext := aContext argAt:3.
exceptionHandlerInContext isExceptionHandler ifFalse:[
- exceptionHandlerInContext isNil ifTrue:[
- 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ] ifFalse:[(exceptionHandlerInContext isBehavior
- and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
- "If the exception class is still autoloaded,
- it does not accept our exception. Raising the exception would load the class"
- ^ nil
- ] ifFalse:[
- 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
- ]].
- theContext fullPrint.
+ GenericException printBadExceptionHandler:exceptionHandlerInContext in:aContext.
^ nil.
].
(exceptionHandlerInContext == exceptionCreator
or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
- ^ (theContext argAt:4) ? [nil].
+ ^ (aContext argAt:4) ? [nil].
].
^ nil
].
selector == #valueWithExceptionHandler: ifTrue:[
- ^ (theContext argAt:1) handlerForSignal:exceptionCreator.
+ ^ (aContext argAt:1) handlerForSignal:exceptionCreator.
].
"/ mhmh - should not arrive here
@@ -2837,11 +2959,13 @@
sourcePos isString ifTrue:[ "/ misuses the sourcePosition slot
^ sourcePos
].
- m := self method.
+ m := self homeMethod.
m notNil ifTrue:[
^ m source
].
^ nil
+
+ "Modified: / 31-03-2017 / 17:26:52 / stefan"
!
source:aString
@@ -2887,7 +3011,10 @@
^ self value
].
+ "/ was not blocked
^ self ensure:[OperatingSystem unblockInterrupts].
+
+ "Modified (comment): / 24-07-2017 / 18:03:04 / cg"
!
valueUnpreemptively
@@ -2947,36 +3074,34 @@
passing the elements in argArray as arguments to the receiver block."
^ [self valueWithArguments:argArray] newProcess
-!
-
-promise
- "create a promise on the receiver. The promise will evaluate the
- receiver and promise to return the value with the #value message.
- The evaluation will be performed as a separate process.
- Asking the promise for its value will either block the asking process
- (if the evaluation has not yet been finished) or return the value
- immediately."
-
- ^ Promise value:self
+! !
+
+!Block methodsFor:'splitting & joining'!
+
+split: aSequenceableCollection indicesDo: aBlock
+ "let me split aSequenceableCollection and evaluate aBlock for each fragment's
+ start- and end-position"
+
+ | position |
+
+ position := 1.
+ aSequenceableCollection withIndexDo:[:element :idx |
+ (self value: element) ifTrue:[
+ aBlock value: position value: idx - 1.
+ position := idx + 1
+ ]
+ ].
+ aBlock value: position value: aSequenceableCollection size
"
- |p|
-
- p := [1000 factorial] promise.
- 'do something else ...'.
- p value
+ [ :char| char isSeparator ] split: 'aa bb cc dd'
+
+ [ :char| char isSeparator ] split: 'aa bb cc dd' do:[:fragment | Transcript showCR:fragment ]
+
+ [ :char| char isSeparator ] split: 'aa bb cc dd' indicesDo:[:start :end | Transcript show:start; show:' to '; showCR:end ]
"
-!
-
-promiseAt:prio
- "create a promise on the receiver. The promise will evaluate the
- receiver and promise to return the value with the #value message.
- The evaluation will be performed as a separate process running at prio.
- Asking the promise for its value will either block the asking process
- (if the evaluation has not yet been finished) or return the value
- immediately."
-
- ^ Promise value:self priority:prio
+
+ "Created: / 13-07-2017 / 18:32:09 / cg"
! !
!Block methodsFor:'testing'!
@@ -2987,6 +3112,14 @@
^ true
!
+isBlockWithArgumentCount:count
+ "return true, if this is a block with count args"
+
+ ^ nargs == count
+
+ "Created: / 18-03-2017 / 18:07:03 / stefan"
+!
+
isCheapBlock
^ false
!