]> gitweb.factorcode.org Git - factor.git/blob - extra/smalltalk/compiler/compiler.factor
First checkin of extra/smalltalk
[factor.git] / extra / smalltalk / compiler / compiler.factor
1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators.short-circuit
4 continuations fry kernel namespaces quotations sequences sets
5 slots locals.types generalizations smalltalk.ast
6 smalltalk.compiler.lexenv smalltalk.selectors ;
7 IN: smalltalk.compiler
8
9 SYMBOL: return-continuation
10
11 GENERIC: need-return-continuation? ( ast -- ? )
12
13 M: ast-return need-return-continuation? drop t ;
14
15 M: ast-block need-return-continuation? body>> [ need-return-continuation? ] any? ;
16
17 M: ast-message-send need-return-continuation?
18     {
19         [ receiver>> need-return-continuation? ]
20         [ arguments>> [ need-return-continuation? ] any? ]
21     } 1&& ;
22
23 M: ast-assignment need-return-continuation?
24     value>> need-return-continuation? ;
25
26 M: object need-return-continuation? drop f ;
27
28 GENERIC: assigned-locals ( ast -- seq )
29
30 M: ast-return assigned-locals value>> assigned-locals ;
31
32 M: ast-block assigned-locals
33     [ body>> [ assigned-locals ] map concat ] [ arguments>> ] bi diff ;
34
35 M: ast-message-send assigned-locals
36     [ receiver>> assigned-locals ]
37     [ arguments>> [ assigned-locals ] map ] bi append ;
38
39 M: ast-assignment assigned-locals
40     [ name>> dup ast-name? [ name>> 1array ] [ drop { } ] if ]
41     [ value>> assigned-locals ] bi append ;
42
43 M: object assigned-locals drop f ;
44
45 GENERIC: compile-ast ( lexenv ast -- quot )
46
47 M: object compile-ast nip 1quotation ;
48
49 ERROR: unbound-local name ;
50
51 M: ast-name compile-ast
52     name>> swap local-readers>> at 1quotation ;
53
54 M: ast-message-send compile-ast
55     [ receiver>> compile-ast ]
56     [ arguments>> [ compile-ast ] with map concat ]
57     [ nip selector>> selector>generic ]
58     2tri [ append ] dip suffix ;
59
60 M: ast-return compile-ast
61     value>> compile-ast
62     [ return-continuation get continue-with ] append ;
63
64 GENERIC: compile-assignment ( lexenv name -- quot )
65
66 M: ast-name compile-assignment
67     name>> swap local-writers>> at 1quotation ;
68
69 M: ast-assignment compile-ast
70     [ value>> compile-ast [ dup ] ] [ name>> compile-assignment ] 2bi 3append ;
71
72 : block-lexenv ( block -- lexenv )
73     [ arguments>> ] [ body>> [ assigned-locals ] map concat unique ] bi
74     '[
75         dup dup _ key?
76         [ <local-reader> ]
77         [ <local> ]
78         if
79     ] { } map>assoc
80     dup
81     [ nip local-reader? ] assoc-filter
82     [ <local-writer> ] assoc-map
83     <lexenv> ;
84
85 M: ast-block compile-ast
86     [
87         block-lexenv
88         [ nip local-readers>> values ]
89         [ lexenv-union ] 2bi
90     ] [ body>> ] bi
91     [ drop [ nil ] ] [
92         unclip-last
93         [ [ compile-ast [ drop ] append ] with map [ ] join ]
94         [ compile-ast ]
95         bi-curry* bi
96         append
97     ] if-empty
98     <lambda> '[ @ ] ;
99
100 : compile-method ( block -- quot )
101     [ [ empty-lexenv ] dip compile-ast ] [ arguments>> length ] [ need-return-continuation? ] tri
102     [ '[ [ _ _ ncurry [ return-continuation set ] prepose callcc1 ] with-scope ] ] [ drop ] if ;