typed: only unbox final classes. Fixes bug reported by littledan
parent
01824d41be
commit
60296be964
|
@ -1,7 +1,8 @@
|
||||||
! Copyright (C) 2009, 2010 Slava Pestov.
|
! Copyright (C) 2009, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: assocs accessors classes.algebra fry generic kernel math
|
USING: assocs accessors classes.algebra fry generic kernel math
|
||||||
namespaces sequences words sets combinators.short-circuit ;
|
namespaces sequences words sets combinators.short-circuit
|
||||||
|
classes.tuple ;
|
||||||
FROM: classes.tuple.private => tuple-layout ;
|
FROM: classes.tuple.private => tuple-layout ;
|
||||||
IN: stack-checker.dependencies
|
IN: stack-checker.dependencies
|
||||||
|
|
||||||
|
@ -122,6 +123,15 @@ TUPLE: depends-on-flushable word ;
|
||||||
M: depends-on-flushable satisfied?
|
M: depends-on-flushable satisfied?
|
||||||
word>> flushable? ;
|
word>> flushable? ;
|
||||||
|
|
||||||
|
TUPLE: depends-on-final class ;
|
||||||
|
|
||||||
|
: depends-on-final ( word -- )
|
||||||
|
[ depends-on-conditionally ]
|
||||||
|
[ \ depends-on-final add-conditional-dependency ] bi ;
|
||||||
|
|
||||||
|
M: depends-on-final satisfied?
|
||||||
|
class>> final-class? ;
|
||||||
|
|
||||||
: init-dependencies ( -- )
|
: init-dependencies ( -- )
|
||||||
H{ } clone dependencies set
|
H{ } clone dependencies set
|
||||||
H{ } clone generic-dependencies set
|
H{ } clone generic-dependencies set
|
||||||
|
|
|
@ -14,8 +14,8 @@ TYPED: fix+ ( a: fixnum b: fixnum -- c: fixnum )
|
||||||
most-positive-fixnum neg 1 - 1quotation
|
most-positive-fixnum neg 1 - 1quotation
|
||||||
[ most-positive-fixnum 1 fix+ ] unit-test
|
[ most-positive-fixnum 1 fix+ ] unit-test
|
||||||
|
|
||||||
TUPLE: tweedle-dee ;
|
TUPLE: tweedle-dee ; final
|
||||||
TUPLE: tweedle-dum ;
|
TUPLE: tweedle-dum ; final
|
||||||
|
|
||||||
TYPED: dee ( x: tweedle-dee -- y )
|
TYPED: dee ( x: tweedle-dee -- y )
|
||||||
drop \ tweedle-dee ;
|
drop \ tweedle-dee ;
|
||||||
|
@ -39,11 +39,11 @@ TYPED:: f+locals ( a: float b: float -- c: float )
|
||||||
|
|
||||||
TUPLE: unboxable
|
TUPLE: unboxable
|
||||||
{ x fixnum read-only }
|
{ x fixnum read-only }
|
||||||
{ y fixnum read-only } ;
|
{ y fixnum read-only } ; final
|
||||||
|
|
||||||
TUPLE: unboxable2
|
TUPLE: unboxable2
|
||||||
{ u unboxable read-only }
|
{ u unboxable read-only }
|
||||||
{ xy fixnum read-only } ;
|
{ xy fixnum read-only } ; final
|
||||||
|
|
||||||
TYPED: unboxy ( in: unboxable -- out: unboxable2 )
|
TYPED: unboxy ( in: unboxable -- out: unboxable2 )
|
||||||
dup [ x>> ] [ y>> ] bi - unboxable2 boa ;
|
dup [ x>> ] [ y>> ] bi - unboxable2 boa ;
|
||||||
|
@ -63,7 +63,7 @@ IN: typed.tests
|
||||||
TUPLE: unboxable
|
TUPLE: unboxable
|
||||||
{ x fixnum read-only }
|
{ x fixnum read-only }
|
||||||
{ y fixnum read-only }
|
{ y fixnum read-only }
|
||||||
{ z float read-only } ;
|
{ z float read-only } ; final
|
||||||
""" eval( -- )
|
""" eval( -- )
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -79,13 +79,15 @@ TYPED: no-inputs ( -- out: integer )
|
||||||
[ 1 ] [ no-inputs ] unit-test
|
[ 1 ] [ no-inputs ] unit-test
|
||||||
|
|
||||||
TUPLE: unboxable3
|
TUPLE: unboxable3
|
||||||
{ x read-only } ;
|
{ x read-only } ; final
|
||||||
|
|
||||||
TYPED: no-inputs-unboxable-output ( -- out: unboxable3 )
|
TYPED: no-inputs-unboxable-output ( -- out: unboxable3 )
|
||||||
T{ unboxable3 } ;
|
T{ unboxable3 } ;
|
||||||
|
|
||||||
[ T{ unboxable3 } ] [ no-inputs-unboxable-output ] unit-test
|
[ T{ unboxable3 } ] [ no-inputs-unboxable-output ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ no-inputs-unboxable-output no-inputs-unboxable-output eq? ] unit-test
|
||||||
|
|
||||||
SYMBOL: buh
|
SYMBOL: buh
|
||||||
|
|
||||||
TYPED: no-outputs ( x: integer -- )
|
TYPED: no-outputs ( x: integer -- )
|
||||||
|
@ -98,10 +100,25 @@ TYPED: no-outputs-unboxable-input ( x: unboxable3 -- )
|
||||||
|
|
||||||
[ T{ unboxable3 } ] [ T{ unboxable3 } no-outputs-unboxable-input buh get ] unit-test
|
[ T{ unboxable3 } ] [ T{ unboxable3 } no-outputs-unboxable-input buh get ] unit-test
|
||||||
|
|
||||||
! Reported by littledan
|
[ f ] [
|
||||||
TUPLE: superclass x ;
|
T{ unboxable3 } no-outputs-unboxable-input buh get
|
||||||
TUPLE: subclass < superclass y ;
|
T{ unboxable3 } no-outputs-unboxable-input buh get
|
||||||
|
eq?
|
||||||
|
] unit-test
|
||||||
|
|
||||||
TYPED: unbox-fail ( superclass: a -- ? ) subclass? ;
|
! Reported by littledan
|
||||||
|
TUPLE: superclass { x read-only } ;
|
||||||
|
TUPLE: subclass < superclass { y read-only } ; final
|
||||||
|
|
||||||
|
TYPED: unbox-fail ( a: superclass -- ? ) subclass? ;
|
||||||
|
|
||||||
[ t ] [ subclass new unbox-fail ] unit-test
|
[ t ] [ subclass new unbox-fail ] unit-test
|
||||||
|
|
||||||
|
! If a final class becomes non-final, typed words need to be recompiled
|
||||||
|
TYPED: recompile-fail ( a: subclass -- ? ) buh get eq? ;
|
||||||
|
|
||||||
|
[ f ] [ subclass new [ buh set ] [ recompile-fail ] bi ] unit-test
|
||||||
|
|
||||||
|
[ ] [ "IN: typed.tests TUPLE: subclass < superclass { y read-only } ;" eval( -- ) ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ subclass new [ buh set ] [ recompile-fail ] bi ] unit-test
|
||||||
|
|
|
@ -20,6 +20,7 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
|
||||||
{
|
{
|
||||||
[ all-slots empty? not ]
|
[ all-slots empty? not ]
|
||||||
[ immutable-tuple-class? ]
|
[ immutable-tuple-class? ]
|
||||||
|
[ final-class? ]
|
||||||
} 1&& ;
|
} 1&& ;
|
||||||
|
|
||||||
! typed inputs
|
! typed inputs
|
||||||
|
@ -30,9 +31,14 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
|
||||||
: input-mismatch-quot ( word types -- quot )
|
: input-mismatch-quot ( word types -- quot )
|
||||||
[ input-mismatch-error ] 2curry ;
|
[ input-mismatch-error ] 2curry ;
|
||||||
|
|
||||||
|
: depends-on-unboxing ( class -- )
|
||||||
|
[ dup tuple-layout depends-on-tuple-layout ]
|
||||||
|
[ depends-on-final ]
|
||||||
|
bi ;
|
||||||
|
|
||||||
: (unboxer) ( type -- quot )
|
: (unboxer) ( type -- quot )
|
||||||
dup unboxable-tuple-class? [
|
dup unboxable-tuple-class? [
|
||||||
dup dup tuple-layout depends-on-tuple-layout
|
dup depends-on-unboxing
|
||||||
all-slots [
|
all-slots [
|
||||||
[ name>> reader-word 1quotation ]
|
[ name>> reader-word 1quotation ]
|
||||||
[ class>> (unboxer) ] bi compose
|
[ class>> (unboxer) ] bi compose
|
||||||
|
@ -52,7 +58,7 @@ PREDICATE: typed-word < word "typed-word" word-prop ;
|
||||||
: (unboxed-types) ( type -- types )
|
: (unboxed-types) ( type -- types )
|
||||||
dup unboxable-tuple-class?
|
dup unboxable-tuple-class?
|
||||||
[
|
[
|
||||||
dup dup tuple-layout depends-on-tuple-layout
|
dup depends-on-unboxing
|
||||||
all-slots [ class>> (unboxed-types) ] map concat
|
all-slots [ class>> (unboxed-types) ] map concat
|
||||||
]
|
]
|
||||||
[ 1array ] if ;
|
[ 1array ] if ;
|
||||||
|
@ -81,7 +87,7 @@ DEFER: make-boxer
|
||||||
: boxer ( type -- quot )
|
: boxer ( type -- quot )
|
||||||
dup unboxable-tuple-class?
|
dup unboxable-tuple-class?
|
||||||
[
|
[
|
||||||
dup dup tuple-layout depends-on-tuple-layout
|
dup depends-on-unboxing
|
||||||
[ all-slots [ class>> ] map make-boxer ]
|
[ all-slots [ class>> ] map make-boxer ]
|
||||||
[ [ boa ] curry ]
|
[ [ boa ] curry ]
|
||||||
bi compose
|
bi compose
|
||||||
|
|
|
@ -93,6 +93,14 @@ ERROR: bad-superclass class ;
|
||||||
] [ 2drop f ] if
|
] [ 2drop f ] if
|
||||||
] [ 2drop f ] if ; inline
|
] [ 2drop f ] if ; inline
|
||||||
|
|
||||||
|
GENERIC: final-class? ( class -- ? )
|
||||||
|
|
||||||
|
M: tuple-class final-class? "final" word-prop ;
|
||||||
|
|
||||||
|
M: builtin-class final-class? tuple eq? not ;
|
||||||
|
|
||||||
|
M: class final-class? drop t ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: tuple-predicate-quot/1 ( class -- quot )
|
: tuple-predicate-quot/1 ( class -- quot )
|
||||||
|
@ -238,16 +246,8 @@ M: tuple-class update-class
|
||||||
[ [ "slots" word-prop ] dip = ]
|
[ [ "slots" word-prop ] dip = ]
|
||||||
bi-curry* bi and ;
|
bi-curry* bi and ;
|
||||||
|
|
||||||
GENERIC: valid-superclass? ( class -- ? )
|
|
||||||
|
|
||||||
M: tuple-class valid-superclass? "final" word-prop not ;
|
|
||||||
|
|
||||||
M: builtin-class valid-superclass? tuple eq? ;
|
|
||||||
|
|
||||||
M: class valid-superclass? drop f ;
|
|
||||||
|
|
||||||
: check-superclass ( superclass -- )
|
: check-superclass ( superclass -- )
|
||||||
dup valid-superclass? [ bad-superclass ] unless drop ;
|
dup final-class? [ bad-superclass ] when drop ;
|
||||||
|
|
||||||
GENERIC# (define-tuple-class) 2 ( class superclass slots -- )
|
GENERIC# (define-tuple-class) 2 ( class superclass slots -- )
|
||||||
|
|
||||||
|
@ -261,12 +261,19 @@ GENERIC# (define-tuple-class) 2 ( class superclass slots -- )
|
||||||
read-only suffix
|
read-only suffix
|
||||||
] map ;
|
] map ;
|
||||||
|
|
||||||
|
: reset-final ( class -- )
|
||||||
|
dup final-class? [
|
||||||
|
[ f "final" set-word-prop ]
|
||||||
|
[ changed-conditionally ]
|
||||||
|
bi
|
||||||
|
] [ drop ] if ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: define-tuple-class ( class superclass slots -- )
|
: define-tuple-class ( class superclass slots -- )
|
||||||
over check-superclass
|
over check-superclass
|
||||||
over prepare-slots
|
over prepare-slots
|
||||||
pick f "final" set-word-prop
|
pick reset-final
|
||||||
(define-tuple-class) ;
|
(define-tuple-class) ;
|
||||||
|
|
||||||
GENERIC: make-final ( class -- )
|
GENERIC: make-final ( class -- )
|
||||||
|
|
Loading…
Reference in New Issue