Better handling of wrappers in locals
[factor/jcg.git] / basis / locals / rewrite / sugar / sugar.factor
blob6e7e156ced4c99c45c03adf3a6a850e90e51444d
1 ! Copyright (C) 2007, 2008 Slava Pestov, Eduardo Cavazos.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs classes classes.tuple fry
4 generalizations hashtables kernel locals locals.backend
5 locals.errors locals.types make quotations sequences vectors
6 words ;
7 IN: locals.rewrite.sugar
9 ! Step 1: rewrite [| [let [let* [wlet into :> forms, turn
10 ! literals with locals in them into code which constructs
11 ! the literal after pushing locals on the stack
13 GENERIC: rewrite-sugar* ( obj -- )
15 : (rewrite-sugar) ( form -- form' )
16     [ rewrite-sugar* ] [ ] make ;
18 GENERIC: quotation-rewrite ( form -- form' )
20 M: callable quotation-rewrite [ [ rewrite-sugar* ] each ] [ ] make ;
22 : var-defs ( vars -- defs ) <reversed> [ <def> ] [ ] map-as ;
24 M: lambda quotation-rewrite
25     [ body>> ] [ vars>> var-defs ] bi
26     prepend quotation-rewrite ;
28 M: callable rewrite-sugar* quotation-rewrite , ;
30 M: lambda rewrite-sugar* quotation-rewrite , ;
32 GENERIC: rewrite-literal? ( obj -- ? )
34 M: special rewrite-literal? drop t ;
36 M: array rewrite-literal? [ rewrite-literal? ] contains? ;
38 M: quotation rewrite-literal? [ rewrite-literal? ] contains? ;
40 M: wrapper rewrite-literal? wrapped>> rewrite-literal? ;
42 M: hashtable rewrite-literal? drop t ;
44 M: vector rewrite-literal? drop t ;
46 M: tuple rewrite-literal? drop t ;
48 M: object rewrite-literal? drop f ;
50 GENERIC: rewrite-element ( obj -- )
52 : rewrite-elements ( seq -- )
53     [ rewrite-element ] each ;
55 : rewrite-sequence ( seq -- )
56     [ rewrite-elements ] [ length ] [ 0 head ] tri '[ _ _ nsequence ] % ;
58 M: array rewrite-element
59     dup rewrite-literal? [ rewrite-sequence ] [ , ] if ;
61 M: vector rewrite-element rewrite-sequence ;
63 M: hashtable rewrite-element >alist rewrite-sequence \ >hashtable , ;
65 M: tuple rewrite-element
66     [ tuple-slots rewrite-elements ] [ class ] bi '[ _ boa ] % ;
68 M: quotation rewrite-element rewrite-sugar* ;
70 M: lambda rewrite-element rewrite-sugar* ;
72 M: binding-form rewrite-element binding-form-in-literal-error ;
74 M: local rewrite-element , ;
76 M: local-reader rewrite-element , ;
78 M: local-writer rewrite-element
79     local-writer-in-literal-error ;
81 M: local-word rewrite-element
82     local-word-in-literal-error ;
84 M: word rewrite-element literalize , ;
86 M: wrapper rewrite-element
87     dup rewrite-literal? [ wrapped>> rewrite-element \ literalize , ] [ , ] if ;
89 M: object rewrite-element , ;
91 M: array rewrite-sugar* rewrite-element ;
93 M: vector rewrite-sugar* rewrite-element ;
95 M: tuple rewrite-sugar* rewrite-element ;
97 M: def rewrite-sugar* , ;
99 M: hashtable rewrite-sugar* rewrite-element ;
101 M: wrapper rewrite-sugar*
102     dup rewrite-literal? [ wrapped>> rewrite-element ] [ , ] if ;
104 M: word rewrite-sugar*
105     dup { load-locals get-local drop-locals } memq?
106     [ >r/r>-in-lambda-error ] [ call-next-method ] if ;
108 M: object rewrite-sugar* , ;
110 : let-rewrite ( body bindings -- )
111     [ quotation-rewrite % <def> , ] assoc-each
112     quotation-rewrite % ;
114 M: let rewrite-sugar*
115     [ body>> ] [ bindings>> ] bi let-rewrite ;
117 M: let* rewrite-sugar*
118     [ body>> ] [ bindings>> ] bi let-rewrite ;
120 M: wlet rewrite-sugar*
121     [ body>> ] [ bindings>> ] bi
122     [ '[ _ ] ] assoc-map
123     let-rewrite ;