! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors kernel locals locals.types prettyprint.backend
-prettyprint.custom prettyprint.sections sequences words ;
+USING: accessors combinators kernel locals locals.types math
+prettyprint.backend prettyprint.custom prettyprint.sections
+sequences words ;
IN: locals.prettyprint
: pprint-var ( var -- )
M: let pprint* \ [let pprint-let ;
M: def pprint*
- 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 ;
+ dup locals>> [ word? ] all? [
+ <block \ :> pprint-word locals>> {
+ [ length 1 > [ "(" text ] when ]
+ [ [ pprint-var ] each ]
+ [ length 1 > [ ")" text ] when ]
+ } cleave block>
+ ] [ pprint-tuple ] if ;
HELP: parse-def
{ $values
{ "name/paren" string }
- { "def" "a " { $link def } " or a " { $link multi-def } }
+ { "def" 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 parse-multi-def parse-single-def }
+{ $subsections parse-def }
"Parsers for word and method definitions:"
{ $subsections (::) (M::) } ;
{ "um" t } [
[
"um" parse-def
- local>> name>>
+ locals>> first 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> [ parse-multi-def ] with-lexer
+ { "( tok1 tok2 )" } <lexer> [ scan-token parse-def ] with-lexer
] with-compilation-unit
- [ locals>> [ name>> ] map ] [ keys ] bi*
+ locals>> [ name>> ] map
] 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-multi-def ] [ parse-single-def ] if update-locals ;
+ dup "(" = [ drop ")" parse-tokens ] [ 1array ] if
+ make-locals [ <def> ] [ update-locals ] bi* ;
M: lambda-parser parse-quotation
H{ } clone (parse-lambda) ;
: defs-vars ( form -- vars ) { } [ defs-vars* ] reduce members ;
-M: def defs-vars* local>> unquote suffix ;
-
-M: multi-def defs-vars* locals>> [ unquote suffix ] each ;
+M: def defs-vars* locals>> [ unquote suffix ] each ;
M: quotation defs-vars* [ defs-vars* ] each ;
! onto the body
dup free-vars [ <quote> ] map
[ % ]
- [ var-defs prepend (rewrite-closures) point-free , ]
+ [ [ <def> prefix ] unless-empty (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 [ load-locals ] curry ] tri append ;
+ [ length dup 1 > [ [ load-locals ] curry ] [ drop [ load-local ] ] if ]
+ 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>> var-defs ] bi prepend quotation-rewrite ;
+ [ body>> ] [ vars>> [ <def> prefix ] unless-empty ] bi 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 local ;
+TUPLE: def locals ;
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
- <uninterned-word>
+ f <word>
dup t "local?" set-word-prop ;
M: local literalize ;
PREDICATE: local-reader < word "local-reader?" word-prop ;
: <local-reader> ( name -- word )
- <uninterned-word>
+ f <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 <uninterned-word> {
+ dup name>> "!" append f <word> {
[ nip t "local-writer?" set-word-prop ]
[ swap "local-reader" set-word-prop ]
[ "local-writer" set-word-prop ]