2009-03-30 06:31:50 -04:00
|
|
|
! Copyright (C) 2009 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors arrays assocs combinators.short-circuit
|
|
|
|
continuations fry kernel namespaces quotations sequences sets
|
2009-04-01 03:06:57 -04:00
|
|
|
generalizations slots locals.types splitting math
|
|
|
|
locals.rewrite.closures generic words combinators locals smalltalk.ast
|
|
|
|
smalltalk.compiler.lexenv smalltalk.compiler.assignment
|
|
|
|
smalltalk.compiler.return smalltalk.selectors smalltalk.classes ;
|
2009-03-30 06:31:50 -04:00
|
|
|
IN: smalltalk.compiler
|
|
|
|
|
|
|
|
GENERIC: compile-ast ( lexenv ast -- quot )
|
|
|
|
|
|
|
|
M: object compile-ast nip 1quotation ;
|
|
|
|
|
2009-03-31 02:24:38 -04:00
|
|
|
M: self compile-ast drop self>> 1quotation ;
|
|
|
|
|
2009-03-30 06:31:50 -04:00
|
|
|
ERROR: unbound-local name ;
|
|
|
|
|
2009-03-31 02:24:38 -04:00
|
|
|
M: ast-name compile-ast name>> swap lookup-reader ;
|
2009-03-30 06:31:50 -04:00
|
|
|
|
2009-03-31 22:23:09 -04:00
|
|
|
: compile-arguments ( lexenv ast -- quot )
|
|
|
|
arguments>> [ compile-ast ] with map [ ] join ;
|
|
|
|
|
2009-04-01 03:53:30 -04:00
|
|
|
: compile-new ( lexenv ast -- quot )
|
|
|
|
[ receiver>> compile-ast ]
|
|
|
|
[ compile-arguments ] 2bi
|
|
|
|
[ new ] 3append ;
|
|
|
|
|
2009-04-01 03:47:51 -04:00
|
|
|
: compile-ifTrue:ifFalse: ( lexenv ast -- quot )
|
2009-03-30 06:31:50 -04:00
|
|
|
[ receiver>> compile-ast ]
|
2009-04-01 03:47:51 -04:00
|
|
|
[ compile-arguments ] 2bi
|
|
|
|
[ if ] 3append ;
|
|
|
|
|
|
|
|
M: ast-message-send compile-ast
|
|
|
|
dup selector>> {
|
|
|
|
{ "ifTrue:ifFalse:" [ compile-ifTrue:ifFalse: ] }
|
2009-04-01 03:53:30 -04:00
|
|
|
{ "new" [ compile-new ] }
|
2009-04-01 03:47:51 -04:00
|
|
|
[
|
|
|
|
drop
|
|
|
|
[ compile-arguments ]
|
|
|
|
[ receiver>> compile-ast ]
|
|
|
|
[ nip selector>> selector>generic ]
|
|
|
|
2tri [ append ] dip suffix
|
|
|
|
]
|
|
|
|
} case ;
|
2009-03-30 06:31:50 -04:00
|
|
|
|
2009-03-31 22:23:09 -04:00
|
|
|
M: ast-cascade compile-ast
|
|
|
|
[ receiver>> compile-ast ]
|
|
|
|
[
|
|
|
|
messages>> [
|
|
|
|
[ compile-arguments \ dip ]
|
|
|
|
[ selector>> selector>generic ] bi
|
|
|
|
[ ] 3sequence
|
|
|
|
] with map
|
|
|
|
unclip-last [ [ [ drop ] append ] map ] dip suffix
|
|
|
|
cleave>quot
|
|
|
|
] 2bi append ;
|
|
|
|
|
2009-03-30 06:31:50 -04:00
|
|
|
M: ast-return compile-ast
|
2009-04-01 03:47:51 -04:00
|
|
|
[ value>> compile-ast ] [ drop return>> 1quotation ] 2bi
|
|
|
|
[ continue-with ] 3append ;
|
2009-03-30 06:31:50 -04:00
|
|
|
|
2009-04-01 03:06:57 -04:00
|
|
|
: (compile-sequence) ( lexenv asts -- quot )
|
|
|
|
[ drop [ nil ] ] [
|
|
|
|
[ compile-ast ] with map [ drop ] join
|
|
|
|
] if-empty ;
|
|
|
|
|
|
|
|
: block-lexenv ( block -- lexenv )
|
|
|
|
[ [ arguments>> ] [ temporaries>> ] bi append ]
|
|
|
|
[ body>> [ assigned-locals ] map concat unique ] bi
|
|
|
|
'[
|
|
|
|
dup dup _ key?
|
|
|
|
[ <local-reader> ]
|
|
|
|
[ <local> ]
|
|
|
|
if
|
|
|
|
] H{ } map>assoc
|
|
|
|
dup
|
|
|
|
[ nip local-reader? ] assoc-filter
|
|
|
|
[ <local-writer> ] assoc-map
|
|
|
|
<lexenv> swap >>local-writers swap >>local-readers ;
|
|
|
|
|
|
|
|
: lookup-block-vars ( vars lexenv -- seq )
|
|
|
|
local-readers>> '[ _ at ] map ;
|
|
|
|
|
|
|
|
: make-temporaries ( block lexenv -- quot )
|
|
|
|
[ temporaries>> ] dip lookup-block-vars
|
|
|
|
[ <def> [ f ] swap suffix ] map [ ] join ;
|
|
|
|
|
|
|
|
:: compile-sequence ( lexenv block -- vars quot )
|
|
|
|
lexenv block block-lexenv lexenv-union :> lexenv
|
|
|
|
block arguments>> lexenv lookup-block-vars
|
|
|
|
lexenv block body>> (compile-sequence) block lexenv make-temporaries prepend ;
|
2009-03-31 22:23:09 -04:00
|
|
|
|
|
|
|
M: ast-sequence compile-ast
|
2009-04-01 03:06:57 -04:00
|
|
|
compile-sequence nip ;
|
2009-03-31 22:23:09 -04:00
|
|
|
|
2009-03-30 21:45:01 -04:00
|
|
|
GENERIC: contains-blocks? ( obj -- ? )
|
|
|
|
|
|
|
|
M: ast-block contains-blocks? drop t ;
|
|
|
|
|
|
|
|
M: object contains-blocks? drop f ;
|
|
|
|
|
|
|
|
M: array contains-blocks? [ contains-blocks? ] any? ;
|
|
|
|
|
|
|
|
M: array compile-ast
|
|
|
|
dup contains-blocks? [
|
|
|
|
[ [ compile-ast ] with map [ ] join ] [ length ] bi
|
|
|
|
'[ @ _ narray ]
|
2009-03-31 02:24:38 -04:00
|
|
|
] [ call-next-method ] if ;
|
2009-03-30 21:45:01 -04:00
|
|
|
|
2009-03-30 06:31:50 -04:00
|
|
|
GENERIC: compile-assignment ( lexenv name -- quot )
|
|
|
|
|
2009-03-31 02:24:38 -04:00
|
|
|
M: ast-name compile-assignment name>> swap lookup-writer ;
|
2009-03-30 06:31:50 -04:00
|
|
|
|
|
|
|
M: ast-assignment compile-ast
|
|
|
|
[ value>> compile-ast [ dup ] ] [ name>> compile-assignment ] 2bi 3append ;
|
|
|
|
|
2009-03-31 02:24:38 -04:00
|
|
|
M: ast-block compile-ast
|
2009-04-01 03:06:57 -04:00
|
|
|
compile-sequence <lambda> '[ _ ] ;
|
2009-03-31 02:24:38 -04:00
|
|
|
|
2009-04-01 03:06:57 -04:00
|
|
|
:: (compile-method-body) ( lexenv block -- lambda )
|
|
|
|
lexenv block compile-sequence
|
|
|
|
[ lexenv self>> suffix ] dip <lambda> ;
|
2009-03-31 02:24:38 -04:00
|
|
|
|
|
|
|
: compile-method-body ( lexenv block -- quot )
|
2009-08-13 20:21:44 -04:00
|
|
|
[ [ (compile-method-body) ] [ arguments>> length 1 + ] bi ] 2keep
|
2009-03-31 02:24:38 -04:00
|
|
|
make-return ;
|
|
|
|
|
|
|
|
: compile-method ( lexenv ast-method -- )
|
|
|
|
[ [ class>> ] [ name>> selector>generic ] bi* create-method ]
|
|
|
|
[ body>> compile-method-body ]
|
|
|
|
2bi define ;
|
|
|
|
|
|
|
|
: <class-lexenv> ( class -- lexenv )
|
2009-04-01 03:47:51 -04:00
|
|
|
<lexenv> swap >>class "self" <local> >>self "^" <local> >>return ;
|
2009-03-31 02:24:38 -04:00
|
|
|
|
2009-04-01 03:06:57 -04:00
|
|
|
M: ast-class compile-ast
|
|
|
|
nip
|
2009-03-31 02:24:38 -04:00
|
|
|
[
|
|
|
|
[ name>> ] [ superclass>> ] [ ivars>> ] tri
|
|
|
|
define-class <class-lexenv>
|
|
|
|
]
|
|
|
|
[ methods>> ] bi
|
|
|
|
[ compile-method ] with each
|
|
|
|
[ nil ] ;
|
|
|
|
|
|
|
|
ERROR: no-word name ;
|
|
|
|
|
2009-04-01 03:06:57 -04:00
|
|
|
M: ast-foreign compile-ast
|
|
|
|
nip
|
2009-03-31 02:24:38 -04:00
|
|
|
[ class>> dup ":" split1 lookup [ ] [ no-word ] ?if ]
|
|
|
|
[ name>> ] bi define-foreign
|
2009-04-01 03:06:57 -04:00
|
|
|
[ nil ] ;
|
|
|
|
|
|
|
|
: compile-smalltalk ( statement -- quot )
|
2009-04-01 03:47:51 -04:00
|
|
|
[ empty-lexenv ] dip [ compile-sequence nip 0 ]
|
2009-08-13 20:21:44 -04:00
|
|
|
2keep make-return ;
|