interval
literal
literal?
-length
slots ;
CONSTANT: null-info T{ value-info f null empty-interval }
] unless
] unless ;
+: length-slots ( length class -- slots )
+ "slots" word-prop length 1 - f <array>
+ swap prefix ;
+
: init-literal-info ( info -- info )
empty-interval >>interval
dup literal>> literal-class >>class
dup literal>> {
{ [ dup real? ] [ [a,a] >>interval ] }
{ [ dup tuple? ] [ tuple-slot-infos >>slots ] }
- { [ dup fixed-length? ] [ length <literal-info> >>length ] }
+ { [ dup fixed-length? ] [
+ [ length <literal-info> ] [ class ] bi
+ length-slots >>slots
+ ] }
[ drop ]
} cond ; inline
t >>literal?
init-value-info ; foldable
-: <sequence-info> ( value -- info )
+: <sequence-info'> ( length class -- info )
<value-info>
- object >>class
- swap value-info >>length
- init-value-info ; foldable
+ over >>class
+ [ length-slots ] dip swap >>slots
+ init-value-info ;
: <tuple-info> ( slots class -- info )
<value-info>
DEFER: (value-info-intersect)
-: intersect-lengths ( info1 info2 -- length )
- [ length>> ] bi@ {
- { [ dup not ] [ drop ] }
- { [ over not ] [ nip ] }
- [ value-info-intersect ]
- } cond ;
-
: intersect-slot ( info1 info2 -- info )
{
{ [ dup not ] [ nip ] }
[ [ class>> ] bi@ class-and >>class ]
[ [ interval>> ] bi@ interval-intersect >>interval ]
[ intersect-literals [ >>literal ] [ >>literal? ] bi* ]
- [ intersect-lengths >>length ]
[ intersect-slots >>slots ]
} 2cleave
init-value-info ;
DEFER: (value-info-union)
-: union-lengths ( info1 info2 -- length )
- [ length>> ] bi@ {
- { [ dup not ] [ nip ] }
- { [ over not ] [ drop ] }
- [ value-info-union ]
- } cond ;
-
: union-slot ( info1 info2 -- info )
{
{ [ dup not ] [ nip ] }
[ [ class>> ] bi@ class-or >>class ]
[ [ interval>> ] bi@ interval-union >>interval ]
[ union-literals [ >>literal ] [ >>literal? ] bi* ]
- [ union-lengths >>length ]
[ union-slots >>slots ]
} 2cleave
init-value-info ;
{ [ 2dup [ class>> ] bi@ class<= not ] [ f ] }
{ [ 2dup [ interval>> ] bi@ interval-subset? not ] [ f ] }
{ [ 2dup literals<= not ] [ f ] }
- { [ 2dup [ length>> ] bi@ value-info<= not ] [ f ] }
{ [ 2dup [ slots>> ] bi@ [ value-info<= ] 2all? not ] [ f ] }
[ t ]
} cond 2nip
! Propagation of immutable slots and array lengths
-UNION: fixed-length-sequence array byte-array string ;
-
: sequence-constructor? ( word -- ? )
{ <array> <byte-array> (byte-array) <string> } member-eq? ;
} at ;
: propagate-sequence-constructor ( #call word -- infos )
- [ in-d>> first <sequence-info> ]
- [ constructor-output-class <class-info> ]
- bi* value-info-intersect 1array ;
+ [ in-d>> first value-info ]
+ [ constructor-output-class ] bi*
+ <sequence-info'> 1array ;
: fold-<tuple-boa> ( values class -- info )
[ [ literal>> ] map ] dip prefix >tuple
: value-info-slot ( slot info -- info' )
{
{ [ over 0 = ] [ 2drop fixnum <class-info> ] }
- { [ 2dup length-accessor? ] [ nip length>> ] }
{ [ dup literal?>> ] [ literal>> literal-info-slot ] }
[ [ 1 - ] [ slots>> ] bi* ?nth ]
} cond [ object-info ] unless* ;