write-description
[let | k! [ 0 ] alu [ ] |
[| len | k len alu make-repeat-fasta k! ] split-lines
- ] with-locals ; inline
+ ] ; inline
: fasta ( n out -- )
homo-sapiens make-cumulative
drop
] with-file-writer
- ] with-locals ;
+ ] ;
: run-fasta 2500000 reverse-complement-in fasta ;
memoize ;
IN: locals
-<PRIVATE
-
-: $with-locals-note
- drop {
- "This form must appear either in a word defined by " { $link POSTPONE: :: } " or " { $link POSTPONE: MACRO:: } ", or alternatively, " { $link with-locals } " must be called on the top-level form of the word to perform closure conversion."
- } $notes ;
-
-PRIVATE>
-
HELP: [|
{ $syntax "[| bindings... | body... ]" }
{ $description "A lambda abstraction. When called, reads stack values into the bindings from left to right; the body may then refer to these bindings." }
"3 5 adder call ."
"8"
}
-}
-$with-locals-note ;
+} ;
HELP: [let
{ $syntax "[let | binding1 [ value1... ]\n binding2 [ value2... ]\n ... |\n body... ]" }
"6 { 36 14 } frobnicate ."
"{ 36 2 }"
}
-}
-$with-locals-note ;
+} ;
HELP: [let*
{ $syntax "[let* | binding1 [ value1... ]\n binding2 [ value2... ]\n ... |\n body... ]" }
"1 { 32 48 } frobnicate ."
"{ 2 3 }"
}
-}
-$with-locals-note ;
+} ;
{ POSTPONE: [let POSTPONE: [let* } related-words
}
} ;
-HELP: with-locals
-{ $values { "form" "a quotation, lambda, let or wlet form" } { "quot" "a quotation" } }
-{ $description "Performs closure conversion of a lexically-scoped form. All nested sub-forms are converted. This word must be applied to a " { $link POSTPONE: [| } ", " { $link POSTPONE: [let } " or " { $link POSTPONE: [wlet } " used in an ordinary definition, however forms in " { $link POSTPONE: :: } " and " { $link POSTPONE: MACRO:: } " definitions are automatically closure-converted and there is no need to use this word." } ;
-
HELP: ::
{ $syntax ":: word ( bindings... -- outputs... ) body... ;" }
{ $description "Defines a word with named inputs; it reads stack values into bindings from left to right, then executes the body with those bindings in lexical scope. Any " { $link POSTPONE: [| } ", " { $link POSTPONE: [let } " or " { $link POSTPONE: [wlet } " forms used in the body of the word definition are automatically closure-converted." }
{ $subsection POSTPONE: :: }
{ $subsection POSTPONE: MEMO:: }
{ $subsection POSTPONE: MACRO:: }
-"Explicit closure conversion outside of applicative word definitions:"
-{ $subsection with-locals }
"Lexical binding forms:"
{ $subsection POSTPONE: [let }
{ $subsection POSTPONE: [let* }
USING: locals math sequences tools.test hashtables words kernel
namespaces arrays strings prettyprint io.streams.string parser
-;
+accessors ;
IN: locals.tests
:: foo ( a b -- a a ) a a ;
[ 5 ] [
[let | a [ 3 ] | [wlet | func [ a + ] | 2 func ] ]
- with-locals
] unit-test
:: wlet-test-2 ( a b -- seq )
[ 10 20 ]
[
- 20 10 [| a! | [| b! | a b ] ] with-locals call call
+ 20 10 [| a! | [| b! | a b ] ] call call
] unit-test
:: write-test-3 ( a! -- q ) [| b | b a! ] ;
[ ] [ \ lambda-generic see ] unit-test
+:: unparse-test-1 ( a -- ) [let | a! [ ] | ] ;
+
[ "[let | a! [ ] | ]" ] [
- [let | a! [ ] | ] unparse
+ \ unparse-test-1 "lambda" word-prop body>> first unparse
] unit-test
+:: unparse-test-2 ( -- ) [wlet | a! [ ] | ] ;
+
[ "[wlet | a! [ ] | ]" ] [
- [wlet | a! [ ] | ] unparse
+ \ unparse-test-2 "lambda" word-prop body>> first unparse
] unit-test
+:: unparse-test-3 ( -- b ) [| a! | ] ;
+
[ "[| a! | ]" ] [
- [| a! | ] unparse
+ \ unparse-test-3 "lambda" word-prop body>> first unparse
] unit-test
DEFER: xyzzy
M:: fixnum next-method-test ( a -- b ) a call-next-method 1 + ;
[ 5 ] [ 1 next-method-test ] unit-test
+
+: no-with-locals-test { 1 2 3 } [| x | x 3 + ] map ;
+
+[ { 4 5 6 } ] [ no-with-locals-test ] unit-test
: pop-locals ( assoc -- )
use get delete ;
+SYMBOL: in-lambda?
+
: (parse-lambda) ( assoc end -- quot )
- parse-until >quotation swap pop-locals ;
+ t in-lambda? [ parse-until ] with-variable
+ >quotation swap pop-locals ;
: parse-lambda ( -- lambda )
"|" parse-tokens make-locals dup push-locals
CREATE-METHOD
[ parse-locals-definition ] with-method-definition ;
+: parsed-lambda ( form -- )
+ in-lambda? get [ parsed ] [ lambda-rewrite over push-all ] if ;
+
PRIVATE>
-: [| parse-lambda parsed ; parsing
+: [| parse-lambda parsed-lambda ; parsing
: [let
scan "|" assert= parse-bindings
-\ ] (parse-lambda) <let> parsed ; parsing
+ \ ] (parse-lambda) <let> parsed-lambda ; parsing
: [let*
scan "|" assert= parse-bindings*
- >r \ ] parse-until >quotation <let*> parsed r> pop-locals ;
- parsing
+ \ ] (parse-lambda) <let*> parsed-lambda ; parsing
: [wlet
scan "|" assert= parse-wbindings
- \ ] (parse-lambda) <wlet> parsed ; parsing
-
-MACRO: with-locals ( form -- quot ) lambda-rewrite ;
+ \ ] (parse-lambda) <wlet> parsed-lambda ; parsing
: :: (::) define ; parsing
] 2each\r
" | " %\r
% \r
- " ] with-locals" % \r
+ " ]" % \r
] "" make \r
] if ;\r
\r
name>> % " [ dup ] " %\r
" | " %\r
% \r
- " ] with-locals" % \r
+ " ]" % \r
] "" make ;\r
\r
M: object build-locals ( code ast -- )\r