:> now works
parent
db92c90569
commit
6286f96379
|
@ -24,8 +24,17 @@ ERROR: local-word-in-literal-error ;
|
||||||
M: local-word-in-literal-error summary
|
M: local-word-in-literal-error summary
|
||||||
drop "Local words not permitted inside literals" ;
|
drop "Local words not permitted inside literals" ;
|
||||||
|
|
||||||
|
ERROR: :>-outside-lambda-error ;
|
||||||
|
|
||||||
|
M: :>-outside-lambda-error summary
|
||||||
|
drop ":> cannot be used outside of lambda expressions" ;
|
||||||
|
|
||||||
ERROR: bad-lambda-rewrite output ;
|
ERROR: bad-lambda-rewrite output ;
|
||||||
|
|
||||||
M: bad-lambda-rewrite summary
|
M: bad-lambda-rewrite summary
|
||||||
drop "You have found a bug in locals. Please report." ;
|
drop "You have found a bug in locals. Please report." ;
|
||||||
|
|
||||||
|
ERROR: bad-local args obj ;
|
||||||
|
|
||||||
|
M: bad-local summary
|
||||||
|
drop "You have bound a bug in locals. Please report." ;
|
||||||
|
|
|
@ -63,6 +63,33 @@ HELP: [wlet
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
HELP: :>
|
||||||
|
{ $syntax ":> binding" }
|
||||||
|
{ $description "Introduces a new binding, lexically scoped to the enclosing quotation or definition." }
|
||||||
|
{ $notes
|
||||||
|
"Lambda and let forms are really just syntax sugar for " { $link POSTPONE: :> } "."
|
||||||
|
$nl
|
||||||
|
"Lambdas desugar as follows:"
|
||||||
|
{ $code
|
||||||
|
"[| a b | a b + b / ]"
|
||||||
|
"[ :> b :> a a b + b / ]"
|
||||||
|
}
|
||||||
|
"Let forms desugar as follows:"
|
||||||
|
{ $code
|
||||||
|
"[|let | x [ 10 random ] | { x x } ]"
|
||||||
|
"10 random :> x { x x }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ $examples
|
||||||
|
{ $code
|
||||||
|
"USING: locals math kernel ;"
|
||||||
|
"IN: scratchpad"
|
||||||
|
":: quadratic ( a b c -- x y )"
|
||||||
|
" b sq 4 a c * * - sqrt :> disc"
|
||||||
|
" b neg disc [ + ] [ - ] 2bi [ 2 a * / ] bi@ ;"
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
HELP: ::
|
HELP: ::
|
||||||
{ $syntax ":: word ( bindings... -- outputs... ) body... ;" }
|
{ $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." }
|
{ $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." }
|
||||||
|
@ -209,6 +236,8 @@ $nl
|
||||||
{ $subsection POSTPONE: [wlet }
|
{ $subsection POSTPONE: [wlet }
|
||||||
"Lambda abstractions:"
|
"Lambda abstractions:"
|
||||||
{ $subsection POSTPONE: [| }
|
{ $subsection POSTPONE: [| }
|
||||||
|
"Lightweight binding form:"
|
||||||
|
{ $subsection POSTPONE: :> }
|
||||||
"Additional topics:"
|
"Additional topics:"
|
||||||
{ $subsection "locals-literals" }
|
{ $subsection "locals-literals" }
|
||||||
{ $subsection "locals-mutable" }
|
{ $subsection "locals-mutable" }
|
||||||
|
|
|
@ -441,6 +441,16 @@ M:: integer lambda-method-forget-test ( a -- b ) ;
|
||||||
|
|
||||||
[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval ] must-fail
|
[ "USE: locals [| | [wlet | a [ 0 ] | { a } ] ]" eval ] must-fail
|
||||||
|
|
||||||
|
[ "USE: locals [| | { :> a } ]" eval ] must-fail
|
||||||
|
|
||||||
|
[ "USE: locals 3 :> a" eval ] must-fail
|
||||||
|
|
||||||
|
[ 3 ] [ 3 [| | :> a a ] call ] unit-test
|
||||||
|
|
||||||
|
[ 3 ] [ 3 [| | :> a! a ] call ] unit-test
|
||||||
|
|
||||||
|
[ 3 ] [ 2 [| | :> a! a 1+ a! a ] call ] unit-test
|
||||||
|
|
||||||
:: wlet-&&-test ( a -- ? )
|
:: wlet-&&-test ( a -- ? )
|
||||||
[wlet | is-integer? [ a integer? ]
|
[wlet | is-integer? [ a integer? ]
|
||||||
is-even? [ a even? ]
|
is-even? [ a even? ]
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
|
! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: lexer locals.parser locals.types macros memoize parser
|
USING: lexer macros memoize parser sequences vocabs
|
||||||
sequences vocabs vocabs.loader words kernel ;
|
vocabs.loader words kernel namespaces locals.parser locals.types
|
||||||
|
locals.errors ;
|
||||||
IN: locals
|
IN: locals
|
||||||
|
|
||||||
: :> scan <local> <def> parsed ; parsing
|
: :>
|
||||||
|
scan locals get [ :>-outside-lambda-error ] unless*
|
||||||
|
[ make-local ] bind <def> parsed ; parsing
|
||||||
|
|
||||||
: [| parse-lambda parsed-lambda ; parsing
|
: [| parse-lambda parsed-lambda ; parsing
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ IN: locals.parser
|
||||||
[ <local-word> [ dup name>> set ] [ ] [ ] tri ] dip
|
[ <local-word> [ dup name>> set ] [ ] [ ] tri ] dip
|
||||||
"local-word-def" set-word-prop ;
|
"local-word-def" set-word-prop ;
|
||||||
|
|
||||||
|
SYMBOL: locals
|
||||||
|
|
||||||
: push-locals ( assoc -- )
|
: push-locals ( assoc -- )
|
||||||
use get push ;
|
use get push ;
|
||||||
|
|
||||||
|
@ -29,11 +31,16 @@ IN: locals.parser
|
||||||
SYMBOL: in-lambda?
|
SYMBOL: in-lambda?
|
||||||
|
|
||||||
: (parse-lambda) ( assoc end -- quot )
|
: (parse-lambda) ( assoc end -- quot )
|
||||||
t in-lambda? [ parse-until ] with-variable
|
[
|
||||||
>quotation swap pop-locals ;
|
in-lambda? on
|
||||||
|
over locals set
|
||||||
|
over push-locals
|
||||||
|
parse-until >quotation
|
||||||
|
swap pop-locals
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
: parse-lambda ( -- lambda )
|
: parse-lambda ( -- lambda )
|
||||||
"|" parse-tokens make-locals dup push-locals
|
"|" parse-tokens make-locals
|
||||||
\ ] (parse-lambda) <lambda> ;
|
\ ] (parse-lambda) <lambda> ;
|
||||||
|
|
||||||
: parse-binding ( end -- pair/f )
|
: parse-binding ( end -- pair/f )
|
||||||
|
@ -52,15 +59,14 @@ SYMBOL: in-lambda?
|
||||||
: parse-bindings ( end -- bindings vars )
|
: parse-bindings ( end -- bindings vars )
|
||||||
[
|
[
|
||||||
[ (parse-bindings) ] H{ } make-assoc
|
[ (parse-bindings) ] H{ } make-assoc
|
||||||
dup push-locals
|
|
||||||
] { } make swap ;
|
] { } make swap ;
|
||||||
|
|
||||||
: parse-bindings* ( end -- words assoc )
|
: parse-bindings* ( end -- words assoc )
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
namespace push-locals
|
namespace push-locals
|
||||||
|
|
||||||
(parse-bindings)
|
(parse-bindings)
|
||||||
|
namespace pop-locals
|
||||||
] { } make-assoc
|
] { } make-assoc
|
||||||
] { } make swap ;
|
] { } make swap ;
|
||||||
|
|
||||||
|
@ -73,13 +79,12 @@ SYMBOL: in-lambda?
|
||||||
: parse-wbindings ( end -- bindings vars )
|
: parse-wbindings ( end -- bindings vars )
|
||||||
[
|
[
|
||||||
[ (parse-wbindings) ] H{ } make-assoc
|
[ (parse-wbindings) ] H{ } make-assoc
|
||||||
dup push-locals
|
|
||||||
] { } make swap ;
|
] { } make swap ;
|
||||||
|
|
||||||
: parse-locals ( -- vars assoc )
|
: parse-locals ( -- vars assoc )
|
||||||
"(" expect ")" parse-effect
|
"(" expect ")" parse-effect
|
||||||
word [ over "declared-effect" set-word-prop ] when*
|
word [ over "declared-effect" set-word-prop ] when*
|
||||||
in>> [ dup pair? [ first ] when ] map make-locals dup push-locals ;
|
in>> [ dup pair? [ first ] when ] map make-locals ;
|
||||||
|
|
||||||
: parse-locals-definition ( word -- word quot )
|
: parse-locals-definition ( word -- word quot )
|
||||||
parse-locals \ ; (parse-lambda) <lambda>
|
parse-locals \ ; (parse-lambda) <lambda>
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
|
! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays fry kernel locals.backend locals.types
|
USING: accessors arrays fry kernel math quotations sequences
|
||||||
math quotations sequences words combinators make ;
|
words combinators make locals.backend locals.types
|
||||||
|
locals.errors ;
|
||||||
IN: locals.rewrite.point-free
|
IN: locals.rewrite.point-free
|
||||||
|
|
||||||
! Step 3: rewrite locals usage within a single quotation into
|
! Step 3: rewrite locals usage within a single quotation into
|
||||||
! retain stack manipulation
|
! retain stack manipulation
|
||||||
|
|
||||||
ERROR: bad-local args obj ;
|
|
||||||
|
|
||||||
: local-index ( args obj -- n )
|
: local-index ( args obj -- n )
|
||||||
2dup '[ unquote _ eq? ] find drop
|
2dup '[ unquote _ eq? ] find drop
|
||||||
dup [ 2nip ] [ drop bad-local ] if ;
|
dup [ 2nip ] [ drop bad-local ] if ;
|
||||||
|
|
Loading…
Reference in New Issue