257 lines
7.6 KiB
Factor
257 lines
7.6 KiB
Factor
! Copyright (C) 2004, 2011 Slava Pestov, Daniel Ehrenberg.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: accessors alien arrays assocs classes classes.tuple.private
|
|
combinators combinators.private combinators.short-circuit effects fry
|
|
generic.single.private kernel kernel.private locals locals.backend
|
|
locals.types macros math namespaces quotations.private sequences
|
|
sequences.private stack-checker.alien stack-checker.backend
|
|
stack-checker.branches stack-checker.dependencies stack-checker.errors
|
|
stack-checker.row-polymorphism stack-checker.state
|
|
stack-checker.transforms stack-checker.values stack-checker.visitor
|
|
words ;
|
|
QUALIFIED-WITH: generic.single.private gsp
|
|
IN: stack-checker.known-words
|
|
|
|
: infer-special ( word -- )
|
|
[ current-word set ] [ "special" word-prop call( -- ) ] bi ;
|
|
|
|
: infer-shuffle ( shuffle -- )
|
|
[ in>> length consume-d ] keep ! inputs shuffle
|
|
[ drop ] [ shuffle dup copy-values dup output-d ] 2bi ! inputs outputs copies
|
|
[ nip f f ] [ swap zip ] 2bi ! in-d out-d in-r out-r mapping
|
|
#shuffle, ;
|
|
|
|
: infer-shuffle-word ( word -- )
|
|
"shuffle" word-prop infer-shuffle ;
|
|
|
|
: infer-local-reader ( word -- )
|
|
( -- value ) apply-word/effect ;
|
|
|
|
: infer-local-writer ( word -- )
|
|
( value -- ) apply-word/effect ;
|
|
|
|
: non-inline-word ( word -- )
|
|
dup add-depends-on-effect
|
|
{
|
|
{ [ dup "shuffle" word-prop ] [ infer-shuffle-word ] }
|
|
{ [ dup "special" word-prop ] [ infer-special ] }
|
|
{ [ dup "transform-quot" word-prop ] [ apply-transform ] }
|
|
{ [ dup macro? ] [ apply-macro ] }
|
|
{ [ dup local? ] [ infer-local-reader ] }
|
|
{ [ dup local-reader? ] [ infer-local-reader ] }
|
|
{ [ dup local-writer? ] [ infer-local-writer ] }
|
|
{ [ dup "no-compile" word-prop ] [ do-not-compile ] }
|
|
[ dup required-stack-effect apply-word/effect ]
|
|
} cond ;
|
|
|
|
{
|
|
{ drop ( x -- ) }
|
|
{ 2drop ( x y -- ) }
|
|
{ 3drop ( x y z -- ) }
|
|
{ 4drop ( w x y z -- ) }
|
|
{ dup ( x -- x x ) }
|
|
{ 2dup ( x y -- x y x y ) }
|
|
{ 3dup ( x y z -- x y z x y z ) }
|
|
{ 4dup ( w x y z -- w x y z w x y z ) }
|
|
{ rot ( x y z -- y z x ) }
|
|
{ -rot ( x y z -- z x y ) }
|
|
{ dupd ( x y -- x x y ) }
|
|
{ swapd ( x y z -- y x z ) }
|
|
{ nip ( x y -- y ) }
|
|
{ 2nip ( x y z -- z ) }
|
|
{ over ( x y -- x y x ) }
|
|
{ pick ( x y z -- x y z x ) }
|
|
{ swap ( x y -- y x ) }
|
|
} [ "shuffle" set-word-prop ] assoc-each
|
|
|
|
: check-declaration ( declaration -- declaration )
|
|
dup { [ array? ] [ [ classoid? ] all? ] } 1&&
|
|
[ bad-declaration-error ] unless ;
|
|
|
|
: infer-declare ( -- )
|
|
pop-literal nip check-declaration
|
|
[ length ensure-d ] keep zip
|
|
#declare, ;
|
|
|
|
\ declare [ infer-declare ] "special" set-word-prop
|
|
|
|
! Call
|
|
GENERIC: infer-call* ( value known -- )
|
|
|
|
: (infer-call) ( value -- ) dup known infer-call* ;
|
|
|
|
: infer-call ( -- ) pop-d (infer-call) ;
|
|
|
|
\ call [ infer-call ] "special" set-word-prop
|
|
|
|
\ (call) [ infer-call ] "special" set-word-prop
|
|
|
|
M: literal-tuple infer-call*
|
|
[ 1array #drop, ] [ infer-literal-quot ] bi* ;
|
|
|
|
M: curried infer-call*
|
|
swap push-d
|
|
[ uncurry ] infer-quot-here
|
|
[ quot>> known pop-d [ set-known ] keep ]
|
|
[ obj>> known pop-d [ set-known ] keep ] bi
|
|
push-d (infer-call) ;
|
|
|
|
M: composed infer-call*
|
|
swap push-d
|
|
[ uncompose ] infer-quot-here
|
|
[ quot2>> known pop-d [ set-known ] keep ]
|
|
[ quot1>> known pop-d [ set-known ] keep ] bi
|
|
push-d push-d
|
|
1 infer->r infer-call
|
|
terminated? get [ 1 infer-r> infer-call ] unless ;
|
|
|
|
M: declared-effect infer-call*
|
|
[ [ known>> infer-call* ] keep ] with-effect-here check-declared-effect ;
|
|
|
|
M: input-parameter infer-call* \ call unknown-macro-input ;
|
|
|
|
M: object infer-call* \ call bad-macro-input ;
|
|
|
|
:: infer-ndip ( word n -- )
|
|
literals get [
|
|
word def>> infer-quot-here
|
|
] [
|
|
pop n [ infer->r infer-quot-here ] [ infer-r> ] bi
|
|
] if-empty ;
|
|
|
|
: infer-dip ( -- ) \ dip 1 infer-ndip ;
|
|
|
|
\ dip [ infer-dip ] "special" set-word-prop
|
|
|
|
: infer-2dip ( -- ) \ 2dip 2 infer-ndip ;
|
|
|
|
\ 2dip [ infer-2dip ] "special" set-word-prop
|
|
|
|
: infer-3dip ( -- ) \ 3dip 3 infer-ndip ;
|
|
|
|
\ 3dip [ infer-3dip ] "special" set-word-prop
|
|
|
|
:: infer-builder ( quot word -- )
|
|
2 consume-d dup first2 quot call make-known
|
|
[ push-d ] [ 1array ] bi word #call, ; inline
|
|
|
|
: infer-curry ( -- ) [ <curried> ] \ curry infer-builder ;
|
|
|
|
\ curry [ infer-curry ] "special" set-word-prop
|
|
|
|
: infer-compose ( -- ) [ <composed> ] \ compose infer-builder ;
|
|
|
|
\ compose [ infer-compose ] "special" set-word-prop
|
|
|
|
: infer-execute ( -- )
|
|
pop-literal nip
|
|
dup word? [
|
|
apply-object
|
|
] [
|
|
\ execute time-bomb
|
|
] if ;
|
|
|
|
\ execute [ infer-execute ] "special" set-word-prop
|
|
|
|
\ (execute) [ infer-execute ] "special" set-word-prop
|
|
|
|
: infer-<tuple-boa> ( -- )
|
|
\ <tuple-boa>
|
|
peek-d literal value>> second 1 + "obj" <array> { tuple } <effect>
|
|
apply-word/effect ;
|
|
|
|
\ <tuple-boa> [ infer-<tuple-boa> ] "special" set-word-prop
|
|
|
|
: infer-effect-unsafe ( word -- )
|
|
pop-literal nip
|
|
add-effect-input
|
|
apply-word/effect ;
|
|
|
|
: infer-execute-effect-unsafe ( -- )
|
|
\ (execute) infer-effect-unsafe ;
|
|
|
|
\ execute-effect-unsafe [ infer-execute-effect-unsafe ] "special" set-word-prop
|
|
|
|
: infer-call-effect-unsafe ( -- )
|
|
\ call infer-effect-unsafe ;
|
|
|
|
\ call-effect-unsafe [ infer-call-effect-unsafe ] "special" set-word-prop
|
|
|
|
: infer-load-locals ( -- )
|
|
pop-literal nip
|
|
consume-d dup copy-values dup output-r
|
|
[ [ f f ] dip ] [ swap zip ] 2bi #shuffle, ;
|
|
|
|
\ load-locals [ infer-load-locals ] "special" set-word-prop
|
|
|
|
: infer-load-local ( -- )
|
|
1 infer->r ;
|
|
|
|
\ load-local [ infer-load-local ] "special" set-word-prop
|
|
|
|
:: infer-get-local ( -- )
|
|
pop-literal nip 1 swap - :> n
|
|
n consume-r :> in-r
|
|
in-r first copy-value 1array :> out-d
|
|
in-r copy-values :> out-r
|
|
|
|
out-d output-d
|
|
out-r output-r
|
|
f out-d in-r out-r
|
|
out-r in-r zip out-d first in-r first 2array suffix
|
|
#shuffle, ;
|
|
|
|
\ get-local [ infer-get-local ] "special" set-word-prop
|
|
|
|
: infer-drop-locals ( -- )
|
|
f f pop-literal nip consume-r f f #shuffle, ;
|
|
|
|
\ drop-locals [ infer-drop-locals ] "special" set-word-prop
|
|
|
|
: infer-call-effect ( word -- )
|
|
1 ensure-d first literal value>>
|
|
add-effect-input add-effect-input
|
|
apply-word/effect ;
|
|
|
|
{ call-effect execute-effect } [
|
|
dup t "no-compile" set-word-prop
|
|
dup '[ _ infer-call-effect ] "special" set-word-prop
|
|
] each
|
|
|
|
\ if [ infer-if ] "special" set-word-prop
|
|
\ dispatch [ infer-dispatch ] "special" set-word-prop
|
|
|
|
\ alien-invoke [ infer-alien-invoke ] "special" set-word-prop
|
|
\ alien-indirect [ infer-alien-indirect ] "special" set-word-prop
|
|
\ alien-assembly [ infer-alien-assembly ] "special" set-word-prop
|
|
\ alien-callback [ infer-alien-callback ] "special" set-word-prop
|
|
|
|
{
|
|
c-to-factor
|
|
do-primitive
|
|
mega-cache-lookup
|
|
mega-cache-miss
|
|
inline-cache-miss
|
|
inline-cache-miss-tail
|
|
lazy-jit-compile
|
|
set-callstack
|
|
set-datastack
|
|
set-retainstack
|
|
unwind-native-frames
|
|
} [ dup '[ _ do-not-compile ] "special" set-word-prop ] each
|
|
|
|
{
|
|
declare call (call) dip 2dip 3dip curry compose
|
|
execute (execute) call-effect-unsafe execute-effect-unsafe
|
|
if dispatch <tuple-boa> do-primitive
|
|
load-local load-locals get-local drop-locals
|
|
alien-invoke alien-indirect alien-callback alien-assembly
|
|
} [ t "no-compile" set-word-prop ] each
|
|
|
|
! Exceptions to the above
|
|
\ curry f "no-compile" set-word-prop
|
|
\ compose f "no-compile" set-word-prop
|
|
|
|
! More words not to compile
|
|
\ clear t "no-compile" set-word-prop
|