! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors combinators kernel locals locals.types math
-prettyprint.backend prettyprint.custom prettyprint.sections
-sequences words ;
+USING: accessors kernel locals locals.types prettyprint.backend
+prettyprint.custom prettyprint.sections sequences words ;
IN: locals.prettyprint
: pprint-var ( var -- )
M: let pprint* \ [let pprint-let ;
M: def pprint*
- dup locals>> [ word? ] all? [
- <block \ :> pprint-word locals>> {
- [ length 1 > [ "(" text ] when ]
- [ [ pprint-var ] each ]
- [ length 1 > [ ")" text ] when ]
- } cleave block>
- ] [ pprint-tuple ] if ;
+ dup local>> word?
+ [ <block \ :> pprint-word local>> pprint-var block> ]
+ [ pprint-tuple ] if ;
+
+M: multi-def pprint*
+ dup locals>> [ word? ] all?
+ [ <block \ :> pprint-word "(" text locals>> [ pprint-var ] each ")" text block> ]
+ [ pprint-tuple ] if ;
HELP: parse-def
{ $values
{ "name/paren" string }
- { "def" def }
+ { "def" "a " { $link def } " or a " { $link multi-def } }
}
{ $description "Parses the lexical variable bindings following a " { $link POSTPONE: :> } " token." } ;
"Words for parsing local words."
$nl
"Words for parsing variable assignments:"
-{ $subsections parse-def }
+{ $subsections parse-def parse-multi-def parse-single-def }
"Parsers for word and method definitions:"
{ $subsections (::) (M::) } ;
{ "um" t } [
[
"um" parse-def
- locals>> first name>>
+ local>> name>>
qualified-vocabs last words>> keys "um" swap member?
] with-compilation-unit
] unit-test
nip values [ name>> ] map
] unit-test
-! parse-single-def
-{
- { "tok1" }
-} [
- [
- { "tok1" } <lexer> [ scan-token parse-def ] with-lexer
- ] with-compilation-unit
- locals>> [ name>> ] map
-] unit-test
-
! parse-multi-def
{
{ "tok1" "tok2" }
+ { "tok1" "tok2" }
} [
[
- { "( tok1 tok2 )" } <lexer> [ scan-token parse-def ] with-lexer
+ { "tok1 tok2 )" } <lexer> [ parse-multi-def ] with-lexer
] with-compilation-unit
- locals>> [ name>> ] map
+ [ locals>> [ name>> ] map ] [ keys ] bi*
] unit-test
<<
(parse-lambda) <lambda>
?rewrite-closures ;
+: parse-multi-def ( -- multi-def assoc )
+ ")" parse-tokens make-locals [ <multi-def> ] dip ;
+
+: parse-single-def ( name -- def assoc )
+ [ make-local <def> ] H{ } make ;
+
: update-locals ( assoc -- )
qualified-vocabs last words>> swap assoc-union! drop ;
: parse-def ( name/paren -- def )
- dup "(" = [ drop ")" parse-tokens ] [ 1array ] if
- make-locals [ <def> ] [ update-locals ] bi* ;
+ dup "(" = [ drop parse-multi-def ] [ parse-single-def ] if update-locals ;
M: lambda-parser parse-quotation
H{ } clone (parse-lambda) ;
: defs-vars ( form -- vars ) { } [ defs-vars* ] reduce members ;
-M: def defs-vars* locals>> [ unquote suffix ] each ;
+M: def defs-vars* local>> unquote suffix ;
+
+M: multi-def defs-vars* locals>> [ unquote suffix ] each ;
M: quotation defs-vars* [ defs-vars* ] each ;
! onto the body
dup free-vars [ <quote> ] map
[ % ]
- [ [ <def> prefix ] unless-empty (rewrite-closures) point-free , ]
+ [ var-defs prepend (rewrite-closures) point-free , ]
[ length \ curry <repetition> % ]
tri ;
read-local-quot [ set-local-value ] append ;
M: def localize
+ local>>
+ [ prefix ]
+ [ local-reader? [ 1array load-local ] [ load-local ] ? ]
+ bi ;
+
+M: multi-def localize
locals>> <reversed>
[ prepend ]
[ [ [ local-reader? ] dip '[ [ 1array ] _ [ndip] ] [ [ ] ] if ] map-index concat ]
- [ length dup 1 > [ [ load-locals ] curry ] [ drop [ load-local ] ] if ]
- tri append ;
+ [ length [ load-locals ] curry ] tri append ;
M: object localize 1quotation ;
M: callable quotation-rewrite [ [ rewrite-sugar* ] each ] [ ] make ;
+: var-defs ( vars -- defs )
+ dup length 1 > [
+ <multi-def> 1quotation
+ ] [
+ <reversed> [ <def> ] [ ] map-as
+ ] if ;
+
M: lambda quotation-rewrite
- [ body>> ] [ vars>> [ <def> prefix ] unless-empty ] bi quotation-rewrite ;
+ [ body>> ] [ vars>> var-defs ] bi prepend quotation-rewrite ;
M: callable rewrite-sugar* quotation-rewrite , ;
M: def rewrite-sugar* , ;
+M: multi-def rewrite-sugar* , ;
+
M: hashtable rewrite-sugar* rewrite-element ;
M: wrapper rewrite-sugar*
: unquote ( quote -- local ) dup quote? [ local>> ] when ; inline
-TUPLE: def locals ;
+TUPLE: def local ;
C: <def> def
+TUPLE: multi-def locals ;
+
+C: <multi-def> multi-def
+
PREDICATE: local < word "local?" word-prop ;
: <local> ( name -- word )
! Create a local variable identifier
- f <word>
+ <uninterned-word>
dup t "local?" set-word-prop ;
M: local literalize ;
PREDICATE: local-reader < word "local-reader?" word-prop ;
: <local-reader> ( name -- word )
- f <word>
+ <uninterned-word>
dup t "local-reader?" set-word-prop ;
M: local-reader literalize ;
PREDICATE: local-writer < word "local-writer?" word-prop ;
: <local-writer> ( reader -- word )
- dup name>> "!" append f <word> {
+ dup name>> "!" append <uninterned-word> {
[ nip t "local-writer?" set-word-prop ]
[ swap "local-reader" set-word-prop ]
[ "local-writer" set-word-prop ]