$nl
"A combinator which can help with implementing methods on " { $link hashcode* } ":"
{ $subsection recursive-hashcode }
-"An oddball combinator:"
-{ $subsection with-datastack }
{ $subsection "combinators-quot" }
{ $see-also "quotations" "dataflow" } ;
{ $description "Throws a " { $link no-case } " error." }
{ $error-description "Thrown by " { $link case } " if the object at the top of the stack does not match any case, and no default case is given." } ;
-HELP: with-datastack
-{ $values { "stack" sequence } { "quot" quotation } { "newstack" sequence } }
-{ $description "Executes the quotation with the given data stack contents, and outputs the new data stack after the word returns. The input sequence is not modified. Does not affect the data stack in surrounding code, other than consuming the two inputs and pushing the output." }
-{ $examples
- { $example "USING: combinators math prettyprint ;" "{ 3 7 } [ + ] with-datastack ." "{ 10 }" }
-} ;
-
HELP: recursive-hashcode
{ $values { "n" integer } { "obj" object } { "quot" "a quotation with stack effect " { $snippet "( n obj -- code )" } } { "code" integer } }
{ $description "A combinator used to implement methods for the " { $link hashcode* } " generic word. If " { $snippet "n" } " is less than or equal to zero, outputs 0, otherwise calls the quotation." } ;
[ drop linear-case-quot ]
} cond ;
-! with-datastack
-: with-datastack ( stack quot -- newstack )
- datastack >r
- >r >array set-datastack r> call
- datastack r> swap suffix set-datastack 2nip ; inline
-
! recursive-hashcode
: recursive-hashcode ( n obj quot -- code )
pick 0 <= [ 3drop 0 ] [ rot 1- -rot call ] if ; inline
USING: help.markup help.syntax kernel kernel.private
continuations.private vectors arrays namespaces
-assocs words quotations lexer ;
+assocs words quotations lexer sequences ;
IN: continuations
ARTICLE: "errors-restartable" "Restartable errors"
"Another two words resume continuations:"
{ $subsection continue }
{ $subsection continue-with }
+"Reflecting the datastack:"
+{ $subsection with-datastack }
"Continuations serve as the building block for a number of higher-level abstractions, such as " { $link "errors" } " and " { $link "threads" } "."
{ $subsection "continuations.private" } ;
{ $values { "error" "an error" } }
{ $description "Called by the error handler to set the " { $link error } " and " { $link restarts } " global variables after an error was thrown." }
$low-level-note ;
+
+HELP: with-datastack
+{ $values { "stack" sequence } { "quot" quotation } { "newstack" sequence } }
+{ $description "Executes the quotation with the given data stack contents, and outputs the new data stack after the word returns. The input sequence is not modified. Does not affect the data stack in surrounding code, other than consuming the two inputs and pushing the output." }
+{ $examples
+ { $example "USING: combinators math prettyprint ;" "{ 3 7 } [ + ] with-datastack ." "{ 10 }" }
+} ;
[ ] [ [ return ] with-return ] unit-test
[ { } [ ] attempt-all ] [ attempt-all-error? ] must-fail-with
+
+[ { 4 } ] [ { 2 2 } [ + ] with-datastack ] unit-test
+
+\ with-datastack must-infer
: return ( -- )
return-continuation get continue ;
+: with-datastack ( stack quot -- newstack )
+ [
+ [
+ [ [ { } like set-datastack ] dip call datastack ] dip
+ continue-with
+ ] 3 (throw)
+ ] callcc1 2nip ;
+
GENERIC: compute-restarts ( error -- seq )
<PRIVATE