factor/basis/stack-checker/backend/backend.factor

155 lines
4.0 KiB
Factor
Raw Normal View History

! Copyright (C) 2004, 2009 Slava Pestov.
2008-07-20 05:24:37 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: fry arrays generic io io.streams.string kernel math
2008-12-08 15:58:00 -05:00
namespaces parser sequences strings vectors words quotations
effects classes continuations assocs combinators
compiler.errors accessors math.order definitions sets
generic.standard.engines.tuple hints macros stack-checker.state
2008-12-08 15:58:00 -05:00
stack-checker.visitor stack-checker.errors stack-checker.values
stack-checker.recursive-state ;
2008-07-20 05:24:37 -04:00
IN: stack-checker.backend
2008-12-04 07:02:49 -05:00
: push-d ( obj -- ) meta-d push ;
2008-07-20 05:24:37 -04:00
: pop-d ( -- obj )
2008-12-04 07:02:49 -05:00
meta-d [
2008-09-06 20:13:59 -04:00
<value> dup 1array #introduce, d-in inc
] [ pop ] if-empty ;
2008-07-20 05:24:37 -04:00
: peek-d ( -- obj ) pop-d dup push-d ;
2008-11-11 20:51:26 -05:00
: make-values ( n -- values )
[ <value> ] replicate ;
2008-07-20 05:24:37 -04:00
2008-11-11 20:51:26 -05:00
: ensure-d ( n -- values )
2008-12-04 07:02:49 -05:00
meta-d 2dup length > [
2008-11-11 20:51:26 -05:00
2dup
[ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
2008-12-04 07:02:49 -05:00
[ length d-in +@ ] [ #introduce, ] [ meta-d push-all ] tri
meta-d push-all
2008-11-11 20:51:26 -05:00
] when swap tail* ;
2008-07-20 05:24:37 -04:00
2008-11-11 20:51:26 -05:00
: shorten-by ( n seq -- )
[ length swap - ] keep shorten ; inline
2008-07-20 05:24:37 -04:00
2008-11-11 20:51:26 -05:00
: consume-d ( n -- seq )
2008-12-04 07:02:49 -05:00
[ ensure-d ] [ meta-d shorten-by ] bi ;
2008-11-11 20:51:26 -05:00
2008-12-04 07:02:49 -05:00
: output-d ( values -- ) meta-d push-all ;
2008-07-20 05:24:37 -04:00
: produce-d ( n -- values )
2008-12-04 07:02:49 -05:00
make-values dup meta-d push-all ;
2008-07-20 05:24:37 -04:00
2008-12-04 07:02:49 -05:00
: push-r ( obj -- ) meta-r push ;
2008-07-20 05:24:37 -04:00
2008-12-04 07:02:49 -05:00
: pop-r ( -- obj )
meta-r dup empty?
[ too-many-r> ] [ pop ] if ;
2008-07-20 05:24:37 -04:00
2008-11-11 20:51:26 -05:00
: consume-r ( n -- seq )
2008-12-04 07:02:49 -05:00
meta-r 2dup length >
[ too-many-r> ] when
2008-11-11 20:51:26 -05:00
[ swap tail* ] [ shorten-by ] 2bi ;
2008-07-20 05:24:37 -04:00
2008-12-04 07:02:49 -05:00
: output-r ( seq -- ) meta-r push-all ;
: push-literal ( obj -- )
literals get push ;
2008-07-20 05:24:37 -04:00
: pop-literal ( -- rstate obj )
2008-12-04 07:02:49 -05:00
literals get [
pop-d
[ 1array #drop, ]
[ literal [ recursion>> ] [ value>> ] bi ] bi
] [ pop recursive-state get swap ] if-empty ;
2008-07-20 05:24:37 -04:00
2008-12-04 07:02:49 -05:00
: literals-available? ( n -- literals ? )
literals get 2dup length <=
[ [ swap tail* ] [ shorten-by ] 2bi t ] [ 2drop f f ] if ;
2008-07-20 05:24:37 -04:00
2008-12-04 07:02:49 -05:00
GENERIC: apply-object ( obj -- )
2008-07-20 05:24:37 -04:00
M: wrapper apply-object
wrapped>>
2008-08-30 03:31:27 -04:00
[ dup word? [ called-dependency depends-on ] [ drop ] if ]
2008-07-20 05:24:37 -04:00
[ push-literal ]
bi ;
M: object apply-object push-literal ;
: terminate ( -- )
2008-12-04 07:02:49 -05:00
terminated? on meta-d clone meta-r clone #terminate, ;
: check->r ( -- )
meta-r empty? [ too-many->r ] unless ;
2008-07-20 05:24:37 -04:00
2008-11-03 04:06:11 -05:00
: infer-quot-here ( quot -- )
meta-r [
V{ } clone \ meta-r set
[ apply-object terminated? get not ] all?
[ commit-literals check->r ] [ literals get delete-all ] if
] dip \ meta-r set ;
2008-11-03 04:06:11 -05:00
2008-07-20 05:24:37 -04:00
: infer-quot ( quot rstate -- )
recursive-state get [
recursive-state set
2008-11-03 04:06:11 -05:00
infer-quot-here
2008-07-20 05:24:37 -04:00
] dip recursive-state set ;
: time-bomb ( error -- )
2008-11-03 04:06:11 -05:00
'[ _ throw ] infer-quot-here ;
2008-07-20 05:24:37 -04:00
: bad-call ( -- )
"call must be given a callable" time-bomb ;
: infer-literal-quot ( literal -- )
dup recursive-quotation? [
value>> recursive-quotation-error
2008-07-20 05:24:37 -04:00
] [
dup value>> callable? [
[ value>> ]
[ [ recursion>> ] keep add-local-quotation ]
2008-07-20 05:24:37 -04:00
bi infer-quot
] [
drop bad-call
] if
] if ;
: infer->r ( n -- )
consume-d dup copy-values [ nip output-r ] [ #>r, ] 2bi ;
2008-07-20 05:24:37 -04:00
: infer-r> ( n -- )
consume-r dup copy-values [ nip output-d ] [ #r>, ] 2bi ;
: consume/produce ( effect quot: ( inputs outputs -- ) -- )
'[ [ in>> length consume-d ] [ out>> length produce-d ] bi @ ]
[ terminated?>> [ terminate ] when ]
bi ; inline
2008-07-20 05:24:37 -04:00
: apply-word/effect ( word effect -- )
swap '[ _ #call, ] consume/produce ;
2008-07-20 05:24:37 -04:00
: end-infer ( -- )
2008-12-04 07:02:49 -05:00
meta-d clone #return, ;
2008-07-20 05:24:37 -04:00
: required-stack-effect ( word -- effect )
dup stack-effect [ ] [ missing-effect ] ?if ;
2008-07-20 05:24:37 -04:00
: infer-word ( word -- )
{
{ [ dup macro? ] [ do-not-compile ] }
{ [ dup "no-compile" word-prop ] [ do-not-compile ] }
[ dup required-stack-effect apply-word/effect ]
} cond ;
2008-07-20 05:24:37 -04:00
: with-infer ( quot -- effect visitor )
[
init-inference
init-known-values
stack-visitor off
call
end-infer
current-effect
stack-visitor get
] with-scope ; inline