Block.st
changeset 18959 59de21f18945
parent 18434 6d5f0280a7c7
child 18960 6e6225b7a7d9
child 18992 5df345494151
equal deleted inserted replaced
18957:e0bb91eae748 18959:59de21f18945
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1989 by Claus Gittinger
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     5 	      All Rights Reserved
     3 	      All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
   858 
   856 
   859     micros := endTime - startTime.
   857     micros := endTime - startTime.
   860 
   858 
   861     Transcript show:anInfoString.
   859     Transcript show:anInfoString.
   862     micros < 1000 ifTrue:[
   860     micros < 1000 ifTrue:[
   863 	Transcript show:micros; show:' µs'.
   861 	Transcript show:micros; show:' µs'.
   864     ] ifFalse:[
   862     ] ifFalse:[
   865 	micros < 100000 ifTrue:[
   863 	micros < 100000 ifTrue:[
   866 	    millis := (micros / 1000.0) asFixedPointRoundedToScale:2.
   864 	    millis := (micros / 1000.0) asFixedPointRoundedToScale:2.
   867 	    Transcript show:millis; show:' ms'.
   865 	    Transcript show:millis; show:' ms'.
   868 	] ifFalse:[
   866 	] ifFalse:[
  2172      ensure:[ e := 1 ].
  2170      ensure:[ e := 1 ].
  2173      self assert:(e == 1).
  2171      self assert:(e == 1).
  2174     "
  2172     "
  2175 !
  2173 !
  2176 
  2174 
       
  2175 on:aSignalOrSignalSetOrException do:exceptionBlock ifCurtailed:curtailBlock
       
  2176     "evaluate the receiver,
       
  2177      handling aSignalOrSignalSetOrException.
       
  2178      The 2nd argument, exceptionBlock is evaluated
       
  2179      if the signal is raised during evaluation.
       
  2180      The 3rd argument, curtailBlock is evaluated if the activity
       
  2181      was unwound due to an unhandled exception in the receiver block
       
  2182      (but not in the exceptionBlock)."
       
  2183 
       
  2184     <context: #return>
       
  2185     <exception: #handle>
       
  2186     <exception: #unwind>
       
  2187 
       
  2188     |v|
       
  2189 
       
  2190     v := self value.       "the real logic is in Context>>unwind and Exception>>doRaise"
       
  2191     thisContext unmarkForUnwind.
       
  2192     ^ v
       
  2193 
       
  2194     "
       
  2195      |e|
       
  2196 
       
  2197      e := 0.
       
  2198      [
       
  2199         1 foo
       
  2200      ] on:MessageNotUnderstood
       
  2201      do:[:ex | e := 1]
       
  2202      ifCurtailed:[ e := 2 ].
       
  2203      self assert:(e == 1).
       
  2204     "
       
  2205 
       
  2206     "
       
  2207      abort the debugger to perform the ifCurtailedBlock...
       
  2208      continue the debugger to go to the end   
       
  2209 
       
  2210      |e|
       
  2211 
       
  2212      e := 0.
       
  2213      [
       
  2214         #[] at:2
       
  2215      ] on:MessageNotUnderstood
       
  2216      do:[:ex | e := 1]
       
  2217      ifCurtailed:[ e := 2. e inspect ].
       
  2218      self assert:(e == 0).
       
  2219     "
       
  2220 
       
  2221     "
       
  2222      |e|
       
  2223 
       
  2224      e := 0.
       
  2225      [
       
  2226         1 negated
       
  2227      ] on:MessageNotUnderstood
       
  2228      do:[:ex | self halt]
       
  2229      ifCurtailed:[ e := 1 ].
       
  2230      self assert:(e == 0).
       
  2231     "
       
  2232 !
       
  2233 
  2177 on:anExceptionHandler do:exceptionBlock on:anExceptionHandler2 do:anExceptionBlock2
  2234 on:anExceptionHandler do:exceptionBlock on:anExceptionHandler2 do:anExceptionBlock2
  2178     "added for ANSI compatibility; evaluate the receiver,
  2235     "added for ANSI compatibility; evaluate the receiver,
  2179      handling aSignalOrSignalSetOrException.
  2236      handling aSignalOrSignalSetOrException.
  2180      The 2nd argument, exceptionBlock is evaluated
  2237      The 2nd argument, exceptionBlock is evaluated
  2181      if the signal is raised during evaluation."
  2238      if the signal is raised during evaluation."
  2357 
  2414 
  2358     "aContext selector must be #on:do: , #on:do:ensure: or #valueWithExceptionHandler:"
  2415     "aContext selector must be #on:do: , #on:do:ensure: or #valueWithExceptionHandler:"
  2359     ^ aContext argAt:1.
  2416     ^ aContext argAt:1.
  2360 !
  2417 !
  2361 
  2418 
  2362 handlerForSignal:exceptionHandler context:theContext originator:originator
  2419 handlerForSignal:exceptionCreator context:theContext originator:originator
  2363     "answer the handler block for the exceptionHandler from originator.
  2420     "answer the handler block for the exceptionCreator from originator.
  2364      The handler block is retrieved from aContext.
  2421      The handler block is retrieved from aContext.
  2365      Answer nil if the exceptionHandler is not handled."
  2422      Answer nil if the exceptionCreator is not handled."
  2366 
  2423 
  2367     |selector exceptionHandlerInContext|
  2424     |selector exceptionHandlerInContext|
  2368 
  2425 
  2369     selector := theContext selector.
  2426     selector := theContext selector.
  2370 
  2427 
  2371     (selector == #on:do:
  2428     (selector == #on:do:
  2372     or:[ selector == #on:do:ensure: ]) ifTrue:[
  2429      or:[ selector == #on:do:ensure: 
  2373 	exceptionHandlerInContext := theContext argAt:1.
  2430      or:[ selector == #on:do:ifCurtailed: ]]
  2374 	exceptionHandlerInContext isExceptionHandler ifFalse:[
  2431      ) ifTrue:[
  2375 	    exceptionHandlerInContext isNil ifTrue:[
  2432         exceptionHandlerInContext := theContext argAt:1.
  2376 		'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2433         exceptionHandlerInContext isExceptionHandler ifFalse:[
  2377 	    ] ifFalse:[(exceptionHandlerInContext isBehavior
  2434             exceptionHandlerInContext isNil ifTrue:[
  2378 			and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2435                 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2379 		"If the exception class is still autoloaded,
  2436             ] ifFalse:[(exceptionHandlerInContext isBehavior
  2380 		 it does not accept our exception. Raising the exception would load the class"
  2437                         and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2381 		^ nil
  2438                 "If the exception class is still autoloaded,
  2382 	    ] ifFalse:[
  2439                  it does not accept our exception. Raising the exception would load the class"
  2383 		'Block [warning]: non-ExceptionHandler in on:do:-context' errorPrintCR.
  2440                 ^ nil
  2384 	    ]].
  2441             ] ifFalse:[
  2385 	    theContext fullPrint.
  2442                 'Block [warning]: non-ExceptionHandler in on:do:-context' errorPrintCR.
  2386 	    ^ nil.
  2443             ]].
  2387 	].
  2444             theContext fullPrint.
  2388 	(exceptionHandlerInContext == exceptionHandler
  2445             ^ nil.
  2389 	 or:[exceptionHandlerInContext accepts:exceptionHandler]) ifTrue:[
  2446         ].
  2390 	    ^ (theContext argAt:2) ? [nil].
  2447         (exceptionHandlerInContext == exceptionCreator
  2391 	].
  2448          or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
  2392 	^ nil
  2449             selector == #on:do:ifCurtailed: ifTrue:[
       
  2450                 theContext unmarkForUnwind.     "if there is a handler, no unwind block has to be performed"
       
  2451             ].
       
  2452             ^ (theContext argAt:2) ? [nil].
       
  2453         ].
       
  2454         ^ nil
  2393     ].
  2455     ].
  2394 
  2456 
  2395     selector == #on:do:on:do: ifTrue:[
  2457     selector == #on:do:on:do: ifTrue:[
  2396 	exceptionHandlerInContext := theContext argAt:1.
  2458         exceptionHandlerInContext := theContext argAt:1.
  2397 	exceptionHandlerInContext isExceptionHandler ifFalse:[
  2459         exceptionHandlerInContext isExceptionHandler ifFalse:[
  2398 	    exceptionHandlerInContext isNil ifTrue:[
  2460             exceptionHandlerInContext isNil ifTrue:[
  2399 		'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2461                 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2400 	    ] ifFalse:[(exceptionHandlerInContext isBehavior
  2462             ] ifFalse:[(exceptionHandlerInContext isBehavior
  2401 			and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2463                         and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2402 		"If the exception class is still autoloaded,
  2464                 "If the exception class is still autoloaded,
  2403 		 it does not accept our exception. Raising the exception would load the class"
  2465                  it does not accept our exception. Raising the exception would load the class"
  2404 		^ nil
  2466                 ^ nil
  2405 	    ] ifFalse:[
  2467             ] ifFalse:[
  2406 		'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2468                 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2407 	    ]].
  2469             ]].
  2408 	    theContext fullPrint.
  2470             theContext fullPrint.
  2409 	    ^ nil.
  2471             ^ nil.
  2410 	].
  2472         ].
  2411 	(exceptionHandlerInContext == exceptionHandler
  2473         (exceptionHandlerInContext == exceptionCreator
  2412 	 or:[exceptionHandlerInContext accepts:exceptionHandler]) ifTrue:[
  2474          or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
  2413 	    ^ (theContext argAt:2) ? [nil].
  2475             ^ (theContext argAt:2) ? [nil].
  2414 	].
  2476         ].
  2415 
  2477 
  2416 	exceptionHandlerInContext := theContext argAt:3.
  2478         exceptionHandlerInContext := theContext argAt:3.
  2417 	exceptionHandlerInContext isExceptionHandler ifFalse:[
  2479         exceptionHandlerInContext isExceptionHandler ifFalse:[
  2418 	    exceptionHandlerInContext isNil ifTrue:[
  2480             exceptionHandlerInContext isNil ifTrue:[
  2419 		'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2481                 'Block [warning]: nil ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2420 	    ] ifFalse:[(exceptionHandlerInContext isBehavior
  2482             ] ifFalse:[(exceptionHandlerInContext isBehavior
  2421 			and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2483                         and:[exceptionHandlerInContext isLoaded not]) ifTrue:[
  2422 		"If the exception class is still autoloaded,
  2484                 "If the exception class is still autoloaded,
  2423 		 it does not accept our exception. Raising the exception would load the class"
  2485                  it does not accept our exception. Raising the exception would load the class"
  2424 		^ nil
  2486                 ^ nil
  2425 	    ] ifFalse:[
  2487             ] ifFalse:[
  2426 		'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2488                 'Block [warning]: non-ExceptionHandler in on:do:on:do:-context' errorPrintCR.
  2427 	    ]].
  2489             ]].
  2428 	    theContext fullPrint.
  2490             theContext fullPrint.
  2429 	    ^ nil.
  2491             ^ nil.
  2430 	].
  2492         ].
  2431 	(exceptionHandlerInContext == exceptionHandler
  2493         (exceptionHandlerInContext == exceptionCreator
  2432 	 or:[exceptionHandlerInContext accepts:exceptionHandler]) ifTrue:[
  2494          or:[exceptionHandlerInContext accepts:exceptionCreator]) ifTrue:[
  2433 	    ^ (theContext argAt:4) ? [nil].
  2495             ^ (theContext argAt:4) ? [nil].
  2434 	].
  2496         ].
  2435 	^ nil
  2497         ^ nil
  2436     ].
  2498     ].
  2437 
  2499 
  2438     selector == #valueWithExceptionHandler: ifTrue:[
  2500     selector == #valueWithExceptionHandler: ifTrue:[
  2439 	^ (theContext argAt:1) handlerForSignal:exceptionHandler.
  2501         ^ (theContext argAt:1) handlerForSignal:exceptionCreator.
  2440     ].
  2502     ].
  2441 
  2503 
  2442     "/ mhmh - should not arrive here
  2504     "/ mhmh - should not arrive here
  2443     ^ nil
  2505     ^ nil
  2444 
  2506 
  3083 
  3145 
  3084     |selector|
  3146     |selector|
  3085 
  3147 
  3086     selector := aContext selector.
  3148     selector := aContext selector.
  3087     selector == #'value:onUnwindDo:' ifTrue:[
  3149     selector == #'value:onUnwindDo:' ifTrue:[
  3088 	^ aContext argAt:2
  3150         ^ aContext argAt:2
  3089     ].
  3151     ].
  3090     selector == #'on:do:ensure:' ifTrue:[
  3152     (selector == #'on:do:ensure:'
  3091 	^ aContext argAt:3
  3153      or:[selector == #'on:do:ifCurtailed:'])ifTrue:[
       
  3154         ^ aContext argAt:3
  3092     ].
  3155     ].
  3093 
  3156 
  3094     "/ for now, only #valueNowOrOnUnwindDo:
  3157     "/ for now, only #valueNowOrOnUnwindDo:
  3095     "/          or   #valueOnUnwindDo:
  3158     "/          or   #valueOnUnwindDo:
  3096     "/          or   #ensure:
  3159     "/          or   #ensure:
  3232 ! !
  3295 ! !
  3233 
  3296 
  3234 !Block class methodsFor:'documentation'!
  3297 !Block class methodsFor:'documentation'!
  3235 
  3298 
  3236 version
  3299 version
  3237     ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.213 2015-06-05 16:08:43 stefan Exp $'
  3300     ^ '$Header$'
  3238 !
  3301 !
  3239 
  3302 
  3240 version_CVS
  3303 version_CVS
  3241     ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.213 2015-06-05 16:08:43 stefan Exp $'
  3304     ^ '$Header$'
  3242 ! !
  3305 ! !
  3243 
  3306 
  3244 
  3307 
  3245 Block initialize!
  3308 Block initialize!