Fry now throws a parse time error if it detects >r r> usage, tweak fry to better interact with locals
parent
3e29a31493
commit
420ff0a447
|
@ -19,6 +19,9 @@ HELP: '[
|
||||||
{ $description "Literal fried quotation. Expands into code which takes values from the stack and substitutes them in place of the fry specifiers " { $link _ } " and " { $link @ } "." }
|
{ $description "Literal fried quotation. Expands into code which takes values from the stack and substitutes them in place of the fry specifiers " { $link _ } " and " { $link @ } "." }
|
||||||
{ $examples "See " { $link "fry.examples" } "." } ;
|
{ $examples "See " { $link "fry.examples" } "." } ;
|
||||||
|
|
||||||
|
HELP: >r/r>-in-fry-error
|
||||||
|
{ $error-description "Thrown by " { $link POSTPONE: '[ } " if the fried quotation contains calls to " { $link >r } " or " { $link r> } ". Explicit retain stack manipulation of this form does not work with fry; use " { $link dip } " instead." } ;
|
||||||
|
|
||||||
ARTICLE: "fry.examples" "Examples of fried quotations"
|
ARTICLE: "fry.examples" "Examples of fried quotations"
|
||||||
"The easiest way to understand fried quotations is to look at some examples."
|
"The easiest way to understand fried quotations is to look at some examples."
|
||||||
$nl
|
$nl
|
||||||
|
@ -73,7 +76,10 @@ ARTICLE: "fry.philosophy" "Fried quotation philosophy"
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
ARTICLE: "fry.limitations" "Fried quotation limitations"
|
ARTICLE: "fry.limitations" "Fried quotation limitations"
|
||||||
"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead." ;
|
"As with " { $vocab-link "locals" } ", fried quotations cannot contain " { $link >r } " and " { $link r> } ". This is not a real limitation in practice, since " { $link dip } " can be used instead."
|
||||||
|
$nl
|
||||||
|
"An error thrown if a fried quotation contains calls to " { $link >r } " and " { $link r> } ":"
|
||||||
|
{ $subsection >r/r>-in-fry-error } ;
|
||||||
|
|
||||||
ARTICLE: "fry" "Fried quotations"
|
ARTICLE: "fry" "Fried quotations"
|
||||||
"The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with ``holes'' (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack."
|
"The " { $vocab-link "fry" } " vocabulary implements " { $emphasis "fried quotation" } ". Conceptually, fried quotations are quotations with ``holes'' (more formally, " { $emphasis "fry specifiers" } "), and the holes are filled in when the fried quotation is pushed on the stack."
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
IN: fry.tests
|
IN: fry.tests
|
||||||
USING: fry tools.test math prettyprint kernel io arrays
|
USING: fry tools.test math prettyprint kernel io arrays
|
||||||
sequences ;
|
sequences eval accessors ;
|
||||||
|
|
||||||
[ [ 3 + ] ] [ 3 '[ _ + ] ] unit-test
|
[ [ 3 + ] ] [ 3 '[ _ + ] ] unit-test
|
||||||
|
|
||||||
[ [ 1 3 + ] ] [ 1 3 '[ _ _ + ] ] unit-test
|
[ [ 1 3 + ] ] [ 1 3 '[ _ _ + ] ] unit-test
|
||||||
|
|
||||||
[ [ 1 + ] ] [ 1 [ + ] '[ _ @ ] ] unit-test
|
[ [ 1 [ + ] call ] ] [ 1 [ + ] '[ _ @ ] ] unit-test
|
||||||
|
|
||||||
[ [ 1 + . ] ] [ 1 [ + ] '[ _ @ . ] ] unit-test
|
[ [ 1 [ + ] call . ] ] [ 1 [ + ] '[ _ @ . ] ] unit-test
|
||||||
|
|
||||||
[ [ + - ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test
|
[ [ [ + ] [ - ] [ call ] dip call ] ] [ [ + ] [ - ] '[ @ @ ] ] unit-test
|
||||||
|
|
||||||
[ [ "a" write "b" print ] ]
|
[ [ "a" "b" [ write ] dip print ] ]
|
||||||
[ "a" "b" '[ _ write _ print ] ] unit-test
|
[ "a" "b" '[ _ write _ print ] ] unit-test
|
||||||
|
|
||||||
[ [ 1 2 + 3 4 - ] ]
|
|
||||||
[ [ + ] [ - ] '[ 1 2 @ 3 4 @ ] ] unit-test
|
|
||||||
|
|
||||||
[ 1/2 ] [
|
[ 1/2 ] [
|
||||||
1 '[ [ _ ] dip / ] 2 swap call
|
1 '[ [ _ ] dip / ] 2 swap call
|
||||||
] unit-test
|
] unit-test
|
||||||
|
@ -58,3 +55,6 @@ sequences ;
|
||||||
[ { { { 3 } } } ] [
|
[ { { { 3 } } } ] [
|
||||||
3 '[ [ [ _ 1array ] call 1array ] call 1array ] call
|
3 '[ [ [ _ 1array ] call 1array ] call 1array ] call
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[ "USING: fry kernel ; f '[ >r _ r> ]" eval ]
|
||||||
|
[ error>> >r/r>-in-fry-error? ] must-fail-with
|
||||||
|
|
|
@ -1,33 +1,37 @@
|
||||||
! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos.
|
! Copyright (C) 2008 Slava Pestov, Eduardo Cavazos.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel sequences combinators parser splitting math
|
USING: kernel sequences combinators parser splitting math
|
||||||
quotations arrays make words ;
|
quotations arrays make words locals.backend summary sets ;
|
||||||
IN: fry
|
IN: fry
|
||||||
|
|
||||||
: _ ( -- * ) "Only valid inside a fry" throw ;
|
: _ ( -- * ) "Only valid inside a fry" throw ;
|
||||||
: @ ( -- * ) "Only valid inside a fry" throw ;
|
: @ ( -- * ) "Only valid inside a fry" throw ;
|
||||||
|
|
||||||
|
ERROR: >r/r>-in-fry-error ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
DEFER: (shallow-fry)
|
: [ncurry] ( n -- quot )
|
||||||
DEFER: shallow-fry
|
{
|
||||||
|
{ 0 [ [ ] ] }
|
||||||
|
{ 1 [ [ curry ] ] }
|
||||||
|
{ 2 [ [ 2curry ] ] }
|
||||||
|
{ 3 [ [ 3curry ] ] }
|
||||||
|
[ [ curry ] <repetition> ]
|
||||||
|
} case ;
|
||||||
|
|
||||||
: ((shallow-fry)) ( accum quot adder -- result )
|
M: >r/r>-in-fry-error summary
|
||||||
>r shallow-fry r>
|
drop
|
||||||
append swap [
|
"Explicit retain stack manipulation is not permitted in fried quotations" ;
|
||||||
[ prepose ] curry append
|
|
||||||
] unless-empty ; inline
|
|
||||||
|
|
||||||
: (shallow-fry) ( accum quot -- result )
|
: check-fry ( quot -- quot )
|
||||||
[ 1quotation ] [
|
dup { >r r> load-locals get-local drop-locals } intersect
|
||||||
unclip {
|
empty? [ >r/r>-in-fry-error ] unless ;
|
||||||
{ \ _ [ [ curry ] ((shallow-fry)) ] }
|
|
||||||
{ \ @ [ [ compose ] ((shallow-fry)) ] }
|
|
||||||
[ swap >r suffix r> (shallow-fry) ]
|
|
||||||
} case
|
|
||||||
] if-empty ;
|
|
||||||
|
|
||||||
: shallow-fry ( quot -- quot' ) [ ] swap (shallow-fry) ;
|
: shallow-fry ( quot -- quot' )
|
||||||
|
check-fry
|
||||||
|
[ dup \ @ = [ drop [ _ call ] ] [ 1array ] if ] map concat
|
||||||
|
{ _ } split [ length 1- [ncurry] ] [ spread>quot ] bi prefix ;
|
||||||
|
|
||||||
PREDICATE: fry-specifier < word { _ @ } memq? ;
|
PREDICATE: fry-specifier < word { _ @ } memq? ;
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,7 @@ IN: combinators
|
||||||
|
|
||||||
! spread
|
! spread
|
||||||
: spread>quot ( seq -- quot )
|
: spread>quot ( seq -- quot )
|
||||||
[ ] [
|
[ ] [ [ dup empty? [ [ dip ] curry ] unless ] dip append ] reduce ;
|
||||||
[ dup empty? [ [ >r ] swap [ r> ] 3append ] unless ] dip
|
|
||||||
append
|
|
||||||
] reduce ;
|
|
||||||
|
|
||||||
: spread ( objs... seq -- )
|
: spread ( objs... seq -- )
|
||||||
spread>quot call ;
|
spread>quot call ;
|
||||||
|
|
Loading…
Reference in New Issue