factor/basis/compiler/cfg/templates/templates.factor

89 lines
2.7 KiB
Factor
Raw Normal View History

2008-09-10 23:11:03 -04:00
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: assocs accessors sequences kernel fry namespaces
2008-10-07 21:00:38 -04:00
quotations combinators classes.algebra compiler.cfg.instructions
compiler.cfg.registers compiler.cfg.stacks ;
2008-09-10 23:11:03 -04:00
IN: compiler.cfg.templates
2008-09-17 01:46:38 -04:00
TUPLE: template input output scratch clobber gc ;
2008-09-10 23:11:03 -04:00
: phantom&spec ( phantom specs -- phantom' specs' )
>r stack>> r>
[ length f pad-left ] keep
[ <reversed> ] bi@ ; inline
: phantom&spec-agree? ( phantom spec quot -- ? )
>r phantom&spec r> 2all? ; inline
: live-vregs ( -- seq )
[ stack>> [ >vreg ] map sift ] each-phantom append ;
: clobbered ( template -- seq )
2008-09-17 01:46:38 -04:00
[ output>> ] [ clobber>> ] bi append ;
2008-09-10 23:11:03 -04:00
: clobbered? ( value name -- ? )
\ clobbered get member? [
>vreg \ live-vregs get member?
] [ drop f ] if ;
: lazy-load ( specs -- seq )
[ length phantom-datastack get phantom-input ] keep
2008-10-07 17:13:29 -04:00
[
2dup second clobbered?
[ first (eager-load) ] [ first (lazy-load) ] if
] 2map ;
2008-09-10 23:11:03 -04:00
: load-inputs ( template -- assoc )
[
live-vregs \ live-vregs set
dup clobbered \ clobbered set
2008-09-17 01:46:38 -04:00
input>> [ values ] [ lazy-load ] bi zip
2008-09-10 23:11:03 -04:00
] with-scope ;
: alloc-scratch ( template -- assoc )
2008-09-17 01:46:38 -04:00
scratch>> [ swap alloc-vreg ] assoc-map ;
2008-09-10 23:11:03 -04:00
2008-09-17 01:46:38 -04:00
: do-template-inputs ( template -- defs uses )
2008-09-10 23:11:03 -04:00
#! Load input values into registers and allocates scratch
#! registers.
2008-09-17 01:46:38 -04:00
[ alloc-scratch ] [ load-inputs ] bi ;
2008-09-10 23:11:03 -04:00
2008-09-17 01:46:38 -04:00
: do-template-outputs ( template defs uses -- )
[ output>> ] 2dip assoc-union '[ _ at ] map
2008-09-10 23:11:03 -04:00
phantom-datastack get phantom-append ;
: apply-template ( pair quot -- vregs )
[
2008-09-17 19:52:11 -04:00
first2
dup gc>> [ t fresh-object ] when
dup do-template-inputs
2008-09-17 01:46:38 -04:00
[ do-template-outputs ] 2keep
2008-09-10 23:11:03 -04:00
] dip call ; inline
: value-matches? ( value spec -- ? )
#! If the spec is a quotation and the value is a literal
#! fixnum, see if the quotation yields true when applied
#! to the fixnum. Otherwise, the values don't match. If the
#! spec is not a quotation, its a reg-class, in which case
#! the value is always good.
2008-09-17 19:52:11 -04:00
{
{ [ dup small-slot eq? ] [ drop dup constant? [ value>> small-slot? ] [ drop f ] if ] }
{ [ dup small-tagged eq? ] [ drop dup constant? [ value>> small-tagged? ] [ drop f ] if ] }
[ 2drop t ]
} cond ;
2008-09-10 23:11:03 -04:00
: class-matches? ( actual expected -- ? )
dup [ class<= ] [ 2drop t ] if ;
2008-09-10 23:11:03 -04:00
: spec-matches? ( value spec -- ? )
2dup first value-matches?
2008-09-17 01:46:38 -04:00
>r >r value-class 2 r> ?nth class-matches? r> and ;
2008-09-10 23:11:03 -04:00
: template-matches? ( template -- ? )
2008-09-17 01:46:38 -04:00
input>> phantom-datastack get swap
2008-09-10 23:11:03 -04:00
[ spec-matches? ] phantom&spec-agree? ;
: find-template ( templates -- pair/f )
#! Pair has shape { quot assoc }
[ second template-matches? ] find nip ;