BOA constructors now check types

db4
Slava Pestov 2008-06-30 01:44:58 -05:00
parent a91d51dc1c
commit f7b7001f39
21 changed files with 229 additions and 184 deletions

View File

@ -217,42 +217,42 @@ bi
"bignum" "math" create ">bignum" "math" create 1quotation "coercer" set-word-prop "bignum" "math" create ">bignum" "math" create 1quotation "coercer" set-word-prop
"ratio" "math" create { "ratio" "math" create {
{ "numerator" { "integer" "math" } read-only: t } { "numerator" { "integer" "math" } read-only }
{ "denominator" { "integer" "math" } read-only: t } { "denominator" { "integer" "math" } read-only }
} define-builtin } define-builtin
"float" "math" create { } define-builtin "float" "math" create { } define-builtin
"float" "math" create ">float" "math" create 1quotation "coercer" set-word-prop "float" "math" create ">float" "math" create 1quotation "coercer" set-word-prop
"complex" "math" create { "complex" "math" create {
{ "real" { "real" "math" } read-only: t } { "real" { "real" "math" } read-only }
{ "imaginary" { "real" "math" } read-only: t } { "imaginary" { "real" "math" } read-only }
} define-builtin } define-builtin
"array" "arrays" create { } define-builtin "array" "arrays" create { } define-builtin
"wrapper" "kernel" create { "wrapper" "kernel" create {
{ "wrapped" read-only: t } { "wrapped" read-only }
} define-builtin } define-builtin
"string" "strings" create { "string" "strings" create {
{ "length" { "array-capacity" "sequences.private" } read-only: t } { "length" { "array-capacity" "sequences.private" } read-only }
"aux" "aux"
} define-builtin } define-builtin
"quotation" "quotations" create { "quotation" "quotations" create {
{ "array" { "array" "arrays" } read-only: t } { "array" { "array" "arrays" } read-only }
{ "compiled" read-only: t } { "compiled" read-only }
} define-builtin } define-builtin
"dll" "alien" create { "dll" "alien" create {
{ "path" { "byte-array" "byte-arrays" } read-only: t } { "path" { "byte-array" "byte-arrays" } read-only }
} }
define-builtin define-builtin
"alien" "alien" create { "alien" "alien" create {
{ "underlying" { "c-ptr" "alien" } read-only: t } { "underlying" { "c-ptr" "alien" } read-only }
{ "expired?" read-only: t } { "expired?" read-only }
} }
define-builtin define-builtin
@ -262,7 +262,7 @@ define-builtin
"vocabulary" "vocabulary"
{ "def" { "quotation" "quotations" } initial: [ ] } { "def" { "quotation" "quotations" } initial: [ ] }
"props" "props"
{ "compiled" read-only: t } { "compiled" read-only }
{ "counter" { "fixnum" "math" } } { "counter" { "fixnum" "math" } }
} define-builtin } define-builtin
@ -275,11 +275,11 @@ define-builtin
"callstack" "kernel" create { } define-builtin "callstack" "kernel" create { } define-builtin
"tuple-layout" "classes.tuple.private" create { "tuple-layout" "classes.tuple.private" create {
{ "hashcode" { "fixnum" "math" } read-only: t } { "hashcode" { "fixnum" "math" } read-only }
{ "class" { "word" "words" } initial: t read-only: t } { "class" { "word" "words" } initial: t read-only }
{ "size" { "fixnum" "math" } read-only: t } { "size" { "fixnum" "math" } read-only }
{ "superclasses" { "array" "arrays" } initial: { } read-only: t } { "superclasses" { "array" "arrays" } initial: { } read-only }
{ "echelon" { "fixnum" "math" } read-only: t } { "echelon" { "fixnum" "math" } read-only }
} define-builtin } define-builtin
"tuple" "kernel" create { "tuple" "kernel" create {
@ -312,8 +312,8 @@ tuple
"curry" "kernel" create "curry" "kernel" create
tuple tuple
{ {
{ "obj" read-only: t } { "obj" read-only }
{ "quot" read-only: t } { "quot" read-only }
} prepare-slots define-tuple-class } prepare-slots define-tuple-class
"curry" "kernel" lookup "curry" "kernel" lookup
@ -325,8 +325,8 @@ tuple
"compose" "kernel" create "compose" "kernel" create
tuple tuple
{ {
{ "first" read-only: t } { "first" read-only }
{ "second" read-only: t } { "second" read-only }
} prepare-slots define-tuple-class } prepare-slots define-tuple-class
"compose" "kernel" lookup "compose" "kernel" lookup

View File

@ -70,7 +70,7 @@ IN: bootstrap.syntax
">>" ">>"
"call-next-method" "call-next-method"
"initial:" "initial:"
"read-only:" "read-only"
} [ "syntax" create drop ] each } [ "syntax" create drop ] each
"t" "syntax" lookup define-symbol "t" "syntax" lookup define-symbol

View File

@ -1,7 +1,7 @@
! Copyright (C) 2004, 2008 Slava Pestov. ! Copyright (C) 2004, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: classes words kernel kernel.private namespaces USING: classes words kernel kernel.private namespaces
sequences math ; sequences math math.private ;
IN: classes.builtin IN: classes.builtin
SYMBOL: builtins SYMBOL: builtins
@ -24,7 +24,7 @@ M: builtin-class rank-class drop 0 ;
: builtin-instance? ( object n -- ? ) : builtin-instance? ( object n -- ? )
#! 7 == tag-mask get #! 7 == tag-mask get
#! 3 == hi-tag tag-number #! 3 == hi-tag tag-number
dup 7 <= [ swap tag eq? ] [ dup 7 fixnum<= [ swap tag eq? ] [
swap dup tag 3 eq? swap dup tag 3 eq?
[ hi-tag eq? ] [ 2drop f ] if [ hi-tag eq? ] [ 2drop f ] if
] if ; inline ] if ; inline

View File

@ -35,7 +35,7 @@ TUPLE: test-7 { b integer initial: 3 } ;
[ 3 ] [ "b" test-7 "slots" word-prop slot-named initial>> ] unit-test [ 3 ] [ "b" test-7 "slots" word-prop slot-named initial>> ] unit-test
TUPLE: test-8 { b integer read-only: t } ; TUPLE: test-8 { b integer read-only } ;
[ t ] [ "b" test-8 "slots" word-prop slot-named read-only>> ] unit-test [ t ] [ "b" test-8 "slots" word-prop slot-named read-only>> ] unit-test

View File

@ -4,7 +4,7 @@ namespaces quotations sequences.private classes continuations
generic.standard effects classes.tuple classes.tuple.private generic.standard effects classes.tuple classes.tuple.private
arrays vectors strings compiler.units accessors classes.algebra arrays vectors strings compiler.units accessors classes.algebra
calendar prettyprint io.streams.string splitting inspector calendar prettyprint io.streams.string splitting inspector
columns math.order classes.private slots.private ; columns math.order classes.private slots slots.private ;
IN: classes.tuple.tests IN: classes.tuple.tests
TUPLE: rect x y w h ; TUPLE: rect x y w h ;
@ -190,15 +190,6 @@ M: vector silly "z" ;
! Typo ! Typo
SYMBOL: not-a-tuple-class SYMBOL: not-a-tuple-class
[
"IN: classes.tuple.tests C: <not-a-tuple-class> not-a-tuple-class"
eval
] must-fail
[ t ] [
"not-a-tuple-class" "classes.tuple.tests" lookup symbol?
] unit-test
! Missing check ! Missing check
[ not-a-tuple-class boa ] must-fail [ not-a-tuple-class boa ] must-fail
[ not-a-tuple-class new ] must-fail [ not-a-tuple-class new ] must-fail
@ -218,10 +209,6 @@ C: <erg's-reshape-problem> erg's-reshape-problem
[ t ] [ cons-test-1 tuple-size "a" get tuple-size = ] unit-test [ t ] [ cons-test-1 tuple-size "a" get tuple-size = ] unit-test
[
"IN: classes.tuple.tests SYMBOL: not-a-class C: <not-a-class> not-a-class" eval
] [ error>> not-a-tuple-class? ] must-fail-with
! Inheritance ! Inheritance
TUPLE: computer cpu ram ; TUPLE: computer cpu ram ;
C: <computer> computer C: <computer> computer
@ -490,7 +477,7 @@ USE: vocabs
] with-compilation-unit ] with-compilation-unit
] unit-test ] unit-test
[ "USE: words T{ word }" eval ] [ error>> not-a-tuple-class? ] must-fail-with [ "USE: words T{ word }" eval ] [ error>> T{ no-method f word new } = ] must-fail-with
! Accessors not being forgotten... ! Accessors not being forgotten...
[ [ ] ] [ [ [ ] ] [
@ -598,3 +585,39 @@ GENERIC: break-me ( obj -- )
! Insufficient type checking ! Insufficient type checking
[ \ vocab tuple>array drop ] must-fail [ \ vocab tuple>array drop ] must-fail
! Check type declarations
TUPLE: declared-types { n fixnum } { m string } ;
[ T{ declared-types f 0 "hi" } ]
[ { declared-types f 0 "hi" } >tuple ]
unit-test
[ { declared-types f "hi" 0 } >tuple ]
[ T{ bad-slot-value f "hi" fixnum } = ]
must-fail-with
[ T{ declared-types f 0 "hi" } ]
[ 0.0 "hi" declared-types boa ] unit-test
: foo ( a b -- c ) declared-types boa ;
\ foo must-infer
[ T{ declared-types f 0 "hi" } ] [ 0.0 "hi" foo ] unit-test
[ "hi" 0.0 declared-types boa ]
[ T{ no-method f "hi" >fixnum } = ]
must-fail-with
[ 0 { } declared-types boa ]
[ T{ bad-slot-value f { } string } = ]
must-fail-with
[ "hi" 0.0 foo ]
[ T{ no-method f "hi" >fixnum } = ]
must-fail-with
[ 0 { } foo ]
[ T{ bad-slot-value f { } string } = ]
must-fail-with

View File

@ -14,15 +14,10 @@ ERROR: not-a-tuple object ;
: check-tuple ( object -- tuple ) : check-tuple ( object -- tuple )
dup tuple? [ not-a-tuple ] unless ; inline dup tuple? [ not-a-tuple ] unless ; inline
ERROR: not-a-tuple-class class ;
: check-tuple-class ( class -- class )
dup tuple-class? [ not-a-tuple-class ] unless ; inline
<PRIVATE <PRIVATE
: tuple-layout ( class -- layout ) : tuple-layout ( class -- layout )
check-tuple-class "layout" word-prop ; "layout" word-prop ;
: layout-of ( tuple -- layout ) : layout-of ( tuple -- layout )
1 slot { tuple-layout } declare ; inline 1 slot { tuple-layout } declare ; inline
@ -46,12 +41,26 @@ PRIVATE>
: tuple-slots ( tuple -- seq ) : tuple-slots ( tuple -- seq )
prepare-tuple>array drop copy-tuple-slots ; prepare-tuple>array drop copy-tuple-slots ;
: slots>tuple ( tuple class -- array ) : all-slots ( class -- slots )
tuple-layout <tuple> [ superclasses [ "slots" word-prop ] map concat ;
[ tuple-size ] [ [ set-array-nth ] curry ] bi 2each
: check-slots ( seq class -- seq class )
[ ] [
2dup all-slots [
class>> 2dup instance?
[ 2drop ] [ bad-slot-value ] if
] 2each
] if-bootstrapping ; inline
: slots>tuple ( seq class -- tuple )
check-slots
new [
[ tuple-size ]
[ [ set-array-nth ] curry ]
bi 2each
] keep ; ] keep ;
: >tuple ( tuple -- seq ) : >tuple ( seq -- tuple )
unclip slots>tuple ; unclip slots>tuple ;
: slot-names ( class -- seq ) : slot-names ( class -- seq )
@ -73,22 +82,43 @@ ERROR: bad-superclass class ;
2drop f 2drop f
] if ; inline ] if ; inline
: tuple-instance? ( object class -- ? ) : tuple-instance? ( object class echelon -- ? )
over tuple? [ #! 4 slot == superclasses>>
[ rot dup tuple? [
[ layout-of superclasses>> ] layout-of 4 slot
[ tuple-layout echelon>> ] bi* 2dup array-capacity fixnum<
swap ?nth [ array-nth eq? ] [ 3drop f ] if
] keep eq? ] [ 3drop f ] if ; inline
] [ 2drop f ] if ; inline
: define-tuple-predicate ( class -- ) : define-tuple-predicate ( class -- )
dup [ tuple-instance? ] curry define-predicate ; dup dup tuple-layout echelon>>
[ tuple-instance? ] 2curry define-predicate ;
: superclass-size ( class -- n ) : superclass-size ( class -- n )
superclasses but-last-slice superclasses but-last-slice
[ slot-names length ] map sum ; [ slot-names length ] map sum ;
: (instance-check-quot) ( class -- quot )
[
\ dup ,
[ "predicate" word-prop % ]
[ [ bad-slot-value ] curry , ] bi
\ unless ,
] [ ] make ;
: instance-check-quot ( class -- quot )
{
{ [ dup object bootstrap-word eq? ] [ drop [ ] ] }
{ [ dup "coercer" word-prop ] [ "coercer" word-prop ] }
[ (instance-check-quot) ]
} cond ;
: boa-check-quot ( class -- quot )
all-slots 1 tail [ class>> instance-check-quot ] map spread>quot ;
: define-boa-check ( class -- )
dup boa-check-quot "boa-check" set-word-prop ;
: generate-tuple-slots ( class slots -- slot-specs ) : generate-tuple-slots ( class slots -- slot-specs )
over superclass-size 2 + make-slots deprecated-slots ; over superclass-size 2 + make-slots deprecated-slots ;
@ -138,10 +168,12 @@ ERROR: bad-superclass class ;
outdated-tuples get [ all-slot-names ] cache drop ; outdated-tuples get [ all-slot-names ] cache drop ;
M: tuple-class update-class M: tuple-class update-class
[ define-tuple-layout ] {
[ define-tuple-slots ] [ define-tuple-layout ]
[ define-tuple-predicate ] [ define-tuple-slots ]
tri ; [ define-tuple-predicate ]
[ define-boa-check ]
} cleave ;
: define-new-tuple-class ( class superclass slots -- ) : define-new-tuple-class ( class superclass slots -- )
[ drop f f tuple-class define-class ] [ drop f f tuple-class define-class ]
@ -210,7 +242,7 @@ M: tuple-class reset-class
M: tuple-class rank-class drop 0 ; M: tuple-class rank-class drop 0 ;
M: tuple-class instance? M: tuple-class instance?
tuple-instance? ; dup tuple-layout echelon>> tuple-instance? ;
M: tuple clone M: tuple clone
(clone) dup delegate clone over set-delegate ; (clone) dup delegate clone over set-delegate ;
@ -226,6 +258,13 @@ M: tuple hashcode*
] 2curry each ] 2curry each
] recursive-hashcode ; ] recursive-hashcode ;
M: tuple-class new tuple-layout <tuple> ;
M: tuple-class boa
[ "boa-check" word-prop call ]
[ tuple-layout ]
bi <tuple-boa> ;
! Deprecated ! Deprecated
M: object get-slots ( obj slots -- ... ) M: object get-slots ( obj slots -- ... )
[ execute ] with each ; [ execute ] with each ;

View File

@ -28,9 +28,10 @@ IN: combinators
! spread ! spread
: spread>quot ( seq -- quot ) : spread>quot ( seq -- quot )
[ length [ >r ] <repetition> concat ] [ ] [
[ [ [ r> ] prepend ] map concat ] bi [ dup empty? [ [ >r ] swap [ r> ] 3append ] unless ] dip
append [ ] like ; append
] reduce ;
: spread ( objs... seq -- ) : spread ( objs... seq -- )
spread>quot call ; spread>quot call ;

View File

@ -63,6 +63,8 @@ IN: cpu.x86.intrinsics
: generate-write-barrier ( -- ) : generate-write-barrier ( -- )
#! Mark the card pointed to by vreg. #! Mark the card pointed to by vreg.
"val" get operand-immediate? "obj" get fresh-object? or [ "val" get operand-immediate? "obj" get fresh-object? or [
"obj" operand PUSH
! Mark the card ! Mark the card
"obj" operand card-bits SHR "obj" operand card-bits SHR
"cards_offset" f temp-reg v>operand %alien-global "cards_offset" f temp-reg v>operand %alien-global
@ -72,6 +74,8 @@ IN: cpu.x86.intrinsics
"obj" operand deck-bits card-bits - SHR "obj" operand deck-bits card-bits - SHR
"decks_offset" f temp-reg v>operand %alien-global "decks_offset" f temp-reg v>operand %alien-global
temp-reg v>operand "obj" operand [+] card-mark <byte> MOV temp-reg v>operand "obj" operand [+] card-mark <byte> MOV
"obj" operand POP
] unless ; ] unless ;
\ set-slot { \ set-slot {
@ -79,21 +83,19 @@ IN: cpu.x86.intrinsics
{ {
[ %slot-literal-known-tag "val" operand MOV generate-write-barrier ] H{ [ %slot-literal-known-tag "val" operand MOV generate-write-barrier ] H{
{ +input+ { { f "val" } { f "obj" known-tag } { [ small-slot? ] "n" } } } { +input+ { { f "val" } { f "obj" known-tag } { [ small-slot? ] "n" } } }
{ +clobber+ { "obj" } }
} }
} }
! Slot number is literal ! Slot number is literal
{ {
[ %slot-literal-any-tag "val" operand MOV generate-write-barrier ] H{ [ %slot-literal-any-tag "val" operand MOV generate-write-barrier ] H{
{ +input+ { { f "val" } { f "obj" } { [ small-slot? ] "n" } } } { +input+ { { f "val" } { f "obj" } { [ small-slot? ] "n" } } }
{ +clobber+ { "obj" } }
} }
} }
! Slot number in a register ! Slot number in a register
{ {
[ %slot-any "val" operand MOV generate-write-barrier ] H{ [ %slot-any "val" operand MOV generate-write-barrier ] H{
{ +input+ { { f "val" } { f "obj" } { f "n" } } } { +input+ { { f "val" } { f "obj" } { f "n" } } }
{ +clobber+ { "obj" "n" } } { +clobber+ { "n" } }
} }
} }
} define-intrinsics } define-intrinsics

View File

@ -196,32 +196,7 @@ M: no-method error.
" class." print " class." print
"Dispatching on object: " write object>> short. ; "Dispatching on object: " write object>> short. ;
M: bad-slot-value error. M: bad-slot-value summary drop "Bad store to specialized slot" ;
"Bad store to specialized slot" print
dup [ index>> 2 - ] [ object>> class all-slots ] bi nth
standard-table-style [
[
[ "Object" write ] with-cell
[ over object>> short. ] with-cell
] with-row
[
[ "Slot" write ] with-cell
[ dup name>> short. ] with-cell
] with-row
[
[ "Slot class" write ] with-cell
[ dup class>> short. ] with-cell
] with-row
[
[ "Value" write ] with-cell
[ over value>> short. ] with-cell
] with-row
[
[ "Value class" write ] with-cell
[ over value>> class short. ] with-cell
] with-row
] tabular-output
2drop ;
M: no-math-method summary M: no-math-method summary
drop "No suitable arithmetic method" ; drop "No suitable arithmetic method" ;
@ -238,9 +213,6 @@ M: check-method summary
M: not-a-tuple summary M: not-a-tuple summary
drop "Not a tuple" ; drop "Not a tuple" ;
M: not-a-tuple-class summary
drop "Not a tuple class" ;
M: bad-superclass summary M: bad-superclass summary
drop "Tuple classes can only inherit from other tuple classes" ; drop "Tuple classes can only inherit from other tuple classes" ;

View File

@ -4,7 +4,7 @@ USING: kernel math math.order strings arrays vectors sequences
accessors ; accessors ;
IN: grouping IN: grouping
TUPLE: abstract-groups { seq read-only: t } { n read-only: t } ; TUPLE: abstract-groups { seq read-only } { n read-only } ;
: check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline : check-groups dup 0 <= [ "Invalid group count" throw ] when ; inline

View File

@ -1,10 +1,10 @@
! Copyright (C) 2007, 2008 Slava Pestov. ! Copyright (C) 2007, 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel words sequences generic math namespaces USING: accessors arrays kernel words sequences generic math
quotations assocs combinators math.bitfields inference.backend namespaces quotations assocs combinators math.bitfields
inference.dataflow inference.state classes.tuple inference.backend inference.dataflow inference.state
classes.tuple.private effects inspector hashtables classes classes.tuple classes.tuple.private effects inspector hashtables
generic sets definitions ; classes generic sets definitions generic.standard slots.private ;
IN: inference.transforms IN: inference.transforms
: pop-literals ( n -- rstate seq ) : pop-literals ( n -- rstate seq )
@ -86,12 +86,24 @@ M: duplicated-slots-error summary
\ boa [ \ boa [
dup tuple-class? [ dup tuple-class? [
dup +inlined+ depends-on dup +inlined+ depends-on
tuple-layout [ <tuple-boa> ] curry [ "boa-check" word-prop ]
[ tuple-layout [ <tuple-boa> ] curry ]
bi append
] [ ] [
[ not-a-tuple-class ] curry time-bomb \ boa \ no-method boa time-bomb
] if ] if
] 1 define-transform ] 1 define-transform
: [tuple-boa] ( layout -- quot )
[ [ <tuple> ] curry ]
[
size>> 1 - [ 3 + ] map <reversed>
[ [ set-slot ] curry [ keep ] curry ] map concat
]
bi append ;
\ <tuple-boa> [ [tuple-boa] ] 1 define-transform
\ (call-next-method) [ \ (call-next-method) [
[ [ +inlined+ depends-on ] bi@ ] [ next-method-quot ] 2bi [ [ +inlined+ depends-on ] bi@ ] [ next-method-quot ] 2bi
] 2 define-transform ] 2 define-transform

View File

@ -142,11 +142,9 @@ M: object clone ;
M: callstack clone (clone) ; M: callstack clone (clone) ;
! Tuple construction ! Tuple construction
: new ( class -- tuple ) GENERIC: new ( class -- tuple )
tuple-layout <tuple> ;
: boa ( ... class -- tuple ) GENERIC: boa ( ... class -- tuple )
tuple-layout <tuple-boa> ;
! Quotation building ! Quotation building
: 2curry ( obj1 obj2 quot -- curry ) : 2curry ( obj1 obj2 quot -- curry )

View File

@ -1,10 +1,11 @@
! Copyright (C) 2007 Slava Pestov. ! Copyright (C) 2007 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
! Based on Slate's src/unfinished/interval.slate by Brian Rice. ! Based on Slate's src/unfinished/interval.slate by Brian Rice.
USING: kernel sequences arrays math combinators math.order ; USING: accessors kernel sequences arrays math math.order
combinators ;
IN: math.intervals IN: math.intervals
TUPLE: interval from to ; TUPLE: interval { from read-only } { to read-only } ;
C: <interval> interval C: <interval> interval
@ -13,26 +14,27 @@ C: <interval> interval
: closed-point ( n -- endpoint ) t 2array ; : closed-point ( n -- endpoint ) t 2array ;
: [a,b] ( a b -- interval ) : [a,b] ( a b -- interval )
>r closed-point r> closed-point <interval> ; >r closed-point r> closed-point <interval> ; foldable
: (a,b) ( a b -- interval ) : (a,b) ( a b -- interval )
>r open-point r> open-point <interval> ; >r open-point r> open-point <interval> ; foldable
: [a,b) ( a b -- interval ) : [a,b) ( a b -- interval )
>r closed-point r> open-point <interval> ; >r closed-point r> open-point <interval> ; foldable
: (a,b] ( a b -- interval ) : (a,b] ( a b -- interval )
>r open-point r> closed-point <interval> ; >r open-point r> closed-point <interval> ; foldable
: [a,a] ( a -- interval ) closed-point dup <interval> ; : [a,a] ( a -- interval )
closed-point dup <interval> ; foldable
: [-inf,a] ( a -- interval ) -1./0. swap [a,b] ; : [-inf,a] ( a -- interval ) -1./0. swap [a,b] ; inline
: [-inf,a) ( a -- interval ) -1./0. swap [a,b) ; : [-inf,a) ( a -- interval ) -1./0. swap [a,b) ; inline
: [a,inf] ( a -- interval ) 1./0. [a,b] ; : [a,inf] ( a -- interval ) 1./0. [a,b] ; inline
: (a,inf] ( a -- interval ) 1./0. (a,b] ; : (a,inf] ( a -- interval ) 1./0. (a,b] ; inline
: compare-endpoints ( p1 p2 quot -- ? ) : compare-endpoints ( p1 p2 quot -- ? )
>r over first over first r> call [ >r over first over first r> call [
@ -58,7 +60,7 @@ C: <interval> interval
: endpoint-max ( p1 p2 -- p3 ) [ endpoint> ] most ; : endpoint-max ( p1 p2 -- p3 ) [ endpoint> ] most ;
: interval>points ( int -- from to ) : interval>points ( int -- from to )
dup interval-from swap interval-to ; [ from>> ] [ to>> ] bi ;
: points>interval ( seq -- interval ) : points>interval ( seq -- interval )
dup first dup first
@ -71,11 +73,12 @@ C: <interval> interval
r> r> [ second ] both? 2array ; inline r> r> [ second ] both? 2array ; inline
: interval-op ( i1 i2 quot -- i3 ) : interval-op ( i1 i2 quot -- i3 )
pick interval-from pick interval-from pick (interval-op) >r {
pick interval-to pick interval-from pick (interval-op) >r [ [ from>> ] [ from>> ] [ ] tri* (interval-op) ]
pick interval-to pick interval-to pick (interval-op) >r [ [ to>> ] [ from>> ] [ ] tri* (interval-op) ]
pick interval-from pick interval-to pick (interval-op) >r [ [ to>> ] [ to>> ] [ ] tri* (interval-op) ]
3drop r> r> r> r> 4array points>interval ; inline [ [ from>> ] [ to>> ] [ ] tri* (interval-op) ]
} 3cleave 4array points>interval ; inline
: interval+ ( i1 i2 -- i3 ) [ + ] interval-op ; : interval+ ( i1 i2 -- i3 ) [ + ] interval-op ;
@ -150,7 +153,7 @@ C: <interval> interval
[ [ shift ] interval-op ] interval-integer-op interval-closure ; [ [ shift ] interval-op ] interval-integer-op interval-closure ;
: interval-shift-safe ( i1 i2 -- i3 ) : interval-shift-safe ( i1 i2 -- i3 )
dup interval-to first 100 > [ dup to>> first 100 > [
2drop f 2drop f
] [ ] [
interval-shift interval-shift
@ -188,17 +191,17 @@ SYMBOL: incomparable
: left-endpoint-< ( i1 i2 -- ? ) : left-endpoint-< ( i1 i2 -- ? )
[ swap interval-subset? ] 2keep [ swap interval-subset? ] 2keep
[ nip interval-singleton? ] 2keep [ nip interval-singleton? ] 2keep
[ interval-from ] bi@ = [ from>> ] bi@ =
and and ; and and ;
: right-endpoint-< ( i1 i2 -- ? ) : right-endpoint-< ( i1 i2 -- ? )
[ interval-subset? ] 2keep [ interval-subset? ] 2keep
[ drop interval-singleton? ] 2keep [ drop interval-singleton? ] 2keep
[ interval-to ] bi@ = [ to>> ] bi@ =
and and ; and and ;
: (interval<) ( i1 i2 -- i1 i2 ? ) : (interval<) ( i1 i2 -- i1 i2 ? )
over interval-from over interval-from endpoint< ; over from>> over from>> endpoint< ;
: interval< ( i1 i2 -- ? ) : interval< ( i1 i2 -- ? )
{ {
@ -209,10 +212,10 @@ SYMBOL: incomparable
} cond 2nip ; } cond 2nip ;
: left-endpoint-<= ( i1 i2 -- ? ) : left-endpoint-<= ( i1 i2 -- ? )
>r interval-from r> interval-to = ; >r from>> r> to>> = ;
: right-endpoint-<= ( i1 i2 -- ? ) : right-endpoint-<= ( i1 i2 -- ? )
>r interval-to r> interval-from = ; >r to>> r> from>> = ;
: interval<= ( i1 i2 -- ? ) : interval<= ( i1 i2 -- ? )
{ {
@ -228,18 +231,18 @@ SYMBOL: incomparable
swap interval<= ; swap interval<= ;
: assume< ( i1 i2 -- i3 ) : assume< ( i1 i2 -- i3 )
interval-to first [-inf,a) interval-intersect ; to>> first [-inf,a) interval-intersect ;
: assume<= ( i1 i2 -- i3 ) : assume<= ( i1 i2 -- i3 )
interval-to first [-inf,a] interval-intersect ; to>> first [-inf,a] interval-intersect ;
: assume> ( i1 i2 -- i3 ) : assume> ( i1 i2 -- i3 )
interval-from first (a,inf] interval-intersect ; from>> first (a,inf] interval-intersect ;
: assume>= ( i1 i2 -- i3 ) : assume>= ( i1 i2 -- i3 )
interval-to first [a,inf] interval-intersect ; to>> first [a,inf] interval-intersect ;
: integral-closure ( i1 -- i2 ) : integral-closure ( i1 -- i2 )
dup interval-from first2 [ 1+ ] unless [ from>> first2 [ 1+ ] unless ]
swap interval-to first2 [ 1- ] unless [ to>> first2 [ 1- ] unless ]
[a,b] ; bi [a,b] ;

View File

@ -5,16 +5,10 @@ arrays classes slots slots.private classes.tuple math vectors
quotations accessors combinators ; quotations accessors combinators ;
IN: mirrors IN: mirrors
: all-slots ( class -- slots ) TUPLE: mirror { object read-only } { slots read-only } ;
superclasses [ "slots" word-prop ] map concat ;
: object-slots ( obj -- seq )
class all-slots ;
TUPLE: mirror object slots ;
: <mirror> ( object -- mirror ) : <mirror> ( object -- mirror )
dup object-slots mirror boa ; dup class all-slots mirror boa ;
M: mirror at* M: mirror at*
[ nip object>> ] [ slots>> slot-named ] 2bi [ nip object>> ] [ slots>> slot-named ] 2bi
@ -24,7 +18,7 @@ M: mirror at*
{ {
{ [ dup not ] [ "No such slot" throw ] } { [ dup not ] [ "No such slot" throw ] }
{ [ dup read-only>> ] [ "Read only slot" throw ] } { [ dup read-only>> ] [ "Read only slot" throw ] }
{ [ 2dup class>> instance? not ] [ "Bad store to specialized slot" throw ] } { [ 2dup class>> instance? not ] [ class>> bad-slot-value ] }
[ offset>> ] [ offset>> ]
} cond ; inline } cond ; inline

View File

@ -161,7 +161,7 @@ M: virtual-sequence new-sequence virtual-seq new-sequence ;
INSTANCE: virtual-sequence sequence INSTANCE: virtual-sequence sequence
! A reversal of an underlying sequence. ! A reversal of an underlying sequence.
TUPLE: reversed { seq read-only: t } ; TUPLE: reversed { seq read-only } ;
C: <reversed> reversed C: <reversed> reversed
@ -177,9 +177,9 @@ INSTANCE: reversed virtual-sequence
! A slice of another sequence. ! A slice of another sequence.
TUPLE: slice TUPLE: slice
{ from read-only: t } { from read-only }
{ to read-only: t } { to read-only }
{ seq read-only: t } ; { seq read-only } ;
: collapse-slice ( m n slice -- m' n' seq ) : collapse-slice ( m n slice -- m' n' seq )
[ from>> ] [ seq>> ] bi >r tuck + >r + r> r> ; inline [ from>> ] [ seq>> ] bi >r tuck + >r + r> r> ; inline
@ -219,7 +219,7 @@ M: slice length [ to>> ] [ from>> ] bi - ;
INSTANCE: slice virtual-sequence INSTANCE: slice virtual-sequence
! One element repeated many times ! One element repeated many times
TUPLE: repetition { len read-only: t } { elt read-only: t } ; TUPLE: repetition { len read-only } { elt read-only } ;
C: <repetition> repetition C: <repetition> repetition

View File

@ -5,16 +5,16 @@ slots.private classes strings math ;
IN: slots IN: slots
ARTICLE: "accessors" "Slot accessors" ARTICLE: "accessors" "Slot accessors"
"For each tuple slot, methods are defined on two accessor words in the " { $vocab-link "accessors" } " vocabulary:" "For every tuple slot, a " { $emphasis "reader" } " method is defined in the " { $vocab-link "accessors" } " vocabulary. The reader is named " { $snippet { $emphasis "slot" } ">>" } " and given a tuple, pushes the slot value on the stack."
{ $list $nl
{ "The " { $emphasis "reader" } " is named " { $snippet { $emphasis "slot" } ">>" } " and pushes the value of a slot on the stack." } "Writable slots - that is, those not attributed " { $link read-only } " - also have a " { $emphasis "writer" } ". The writer is named " { $snippet "(>>" { $emphasis "slot" } ")" } " and stores a value into a slot. It has stack effect " { $snippet "( value object -- )" } ". If the slot is specialized to a specific class, the writer checks that the value being written into the slot is an instance of that class first."
{ "The " { $emphasis "writer" } " is named " { $snippet "(>>" { $emphasis "slot" } ")" } " and stores a value into a slot. It has stack effect " { $snippet "( value object -- )" } "." } $nl
} "In addition, two utility words are defined for each writable slot."
"In addition, two utility words are defined for each distinct slot name used in the system:" $nl
{ $list "The " { $emphasis "setter" } " is named " { $snippet ">>" { $emphasis "slot" } } " and stores a value into a slot. It has stack effect " { $snippet "( object value -- object )" } "."
{ "The " { $emphasis "setter" } " is named " { $snippet ">>" { $emphasis "slot" } } " and stores a value into a slot. It has stack effect " { $snippet "( object value -- object )" } "." } $nl
{ "The " { $emphasis "changer" } " is named " { $snippet "change-" { $emphasis "slot" } } ". It applies a quotation to the current slot value and stores the result back in the slot; it has stack effect " { $snippet "( object quot -- object )" } "." } "The " { $emphasis "changer" } " is named " { $snippet "change-" { $emphasis "slot" } } ". It applies a quotation to the current slot value and stores the result back in the slot; it has stack effect " { $snippet "( object quot -- object )" } "."
} $nl
"Since the reader and writer are generic, words can be written which do not depend on the specific class of tuple passed in, but instead work on any tuple that defines slots with certain names." "Since the reader and writer are generic, words can be written which do not depend on the specific class of tuple passed in, but instead work on any tuple that defines slots with certain names."
$nl $nl
"In most cases, using the setter is preferred over the writer because the stack effect is better suited to the common case where the tuple is needed again, and where the new slot value was just computed and so is at the top of the stack. For example, consider the case where you want to create a tuple and fill in the slots with literals. The following version uses setters:" "In most cases, using the setter is preferred over the writer because the stack effect is better suited to the common case where the tuple is needed again, and where the new slot value was just computed and so is at the top of the stack. For example, consider the case where you want to create a tuple and fill in the slots with literals. The following version uses setters:"
@ -96,7 +96,7 @@ $nl
{ { $snippet "offset" } " - an " { $link integer } " offset specifying where the slot value is stored inside instances of the relevant class. This is an implementation detail." } { { $snippet "offset" } " - an " { $link integer } " offset specifying where the slot value is stored inside instances of the relevant class. This is an implementation detail." }
{ { $snippet "class" } " - a " { $link class } " declaring the set of possible values for the slot." } { { $snippet "class" } " - a " { $link class } " declaring the set of possible values for the slot." }
{ { $snippet "initial" } " - an initial value for the slot." } { { $snippet "initial" } " - an initial value for the slot." }
{ { $snippet "read-only" } " - a boolean indicating whether the slot is read only, or can be written to." } { { $snippet "read-only" } " - a boolean indicating whether the slot is read only or not. Read only slots do not have a writer method associated with them." }
} } ; } } ;
HELP: define-typecheck HELP: define-typecheck

View File

@ -4,7 +4,7 @@ tools.test generic words parser ;
TUPLE: r/w-test foo ; TUPLE: r/w-test foo ;
TUPLE: r/o-test { foo read-only: t } ; TUPLE: r/o-test { foo read-only } ;
[ r/o-test new 123 >>foo ] [ no-method? ] must-fail-with [ r/o-test new 123 >>foo ] [ no-method? ] must-fail-with
@ -25,12 +25,12 @@ TUPLE: hello length ;
[ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
! See if declarations are cleared on redefinition ! See if declarations are cleared on redefinition
[ ] [ "IN: slots.tests TUPLE: r/w-test { foo read-only: t } ;" eval ] unit-test [ ] [ "IN: slots.tests TUPLE: r/w-test { foo read-only } ;" eval ] unit-test
[ t ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test [ t ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test
[ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test
[ ] [ "IN: slots.tests TUPLE: r/w-test { foo read-only: f } ;" eval ] unit-test [ ] [ "IN: slots.tests TUPLE: r/w-test foo ;" eval ] unit-test
[ f ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test [ f ] [ r/w-test \ foo>> method "foldable" word-prop ] unit-test
[ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test [ t ] [ r/w-test \ foo>> method "flushable" word-prop ] unit-test

View File

@ -43,7 +43,7 @@ TUPLE: slot-spec name offset class initial read-only reader writer ;
: writer-word ( name -- word ) : writer-word ( name -- word )
"(>>" swap ")" 3append (( value object -- )) create-accessor ; "(>>" swap ")" 3append (( value object -- )) create-accessor ;
ERROR: bad-slot-value value object index ; ERROR: bad-slot-value value class ;
: writer-quot/object ( slot-spec -- ) : writer-quot/object ( slot-spec -- )
offset>> , \ set-slot , ; offset>> , \ set-slot , ;
@ -57,8 +57,10 @@ ERROR: bad-slot-value value object index ;
[ offset>> , ] [ offset>> , ]
[ [
\ pick , \ pick ,
class>> "predicate" word-prop % dup class>> "predicate" word-prop %
[ [ set-slot ] [ bad-slot-value ] if ] % [ set-slot ] ,
class>> [ 2nip bad-slot-value ] curry [ ] like ,
\ if ,
] ]
bi ; bi ;
@ -158,7 +160,7 @@ ERROR: bad-slot-attribute key ;
dup empty? [ dup empty? [
unclip { unclip {
{ initial: [ [ first >>initial ] [ rest ] bi ] } { initial: [ [ first >>initial ] [ rest ] bi ] }
{ read-only: [ [ first >>read-only ] [ rest ] bi ] } { read-only [ [ t >>read-only ] dip ] }
[ bad-slot-attribute ] [ bad-slot-attribute ]
} case } case
] unless ; ] unless ;

View File

@ -558,7 +558,7 @@ $nl
{ { $snippet "{ \"name\" attributes... }" } " - a slot which can hold any object, with optional attributes" } { { $snippet "{ \"name\" attributes... }" } " - a slot which can hold any object, with optional attributes" }
{ { $snippet "{ \"name\" class attributes... }" } " - a slot specialized to a specific class, with optional attributes" } { { $snippet "{ \"name\" class attributes... }" } " - a slot specialized to a specific class, with optional attributes" }
} }
"Slot attributes are lists of slot attribute specifiers followed by values; a slot attribute specifier is one of " { $link initial: } " or " { $link read-only: } "." } "Slot attributes are lists of slot attribute specifiers followed by values; a slot attribute specifier is one of " { $link initial: } " or " { $link read-only } "." }
{ $examples { $examples
"A simple tuple class:" "A simple tuple class:"
{ $code "TUPLE: color red green blue ;" } { $code "TUPLE: color red green blue ;" }
@ -573,12 +573,12 @@ HELP: initial:
{ $values { "slot" "a slot name" } { "value" "any literal" } } { $values { "slot" "a slot name" } { "value" "any literal" } }
{ $description "Specifies an initial value for a tuple slot." } ; { $description "Specifies an initial value for a tuple slot." } ;
HELP: read-only: HELP: read-only
{ $syntax "TUPLE: ... { \"slot\" read-only: ? } ... ;" } { $syntax "TUPLE: ... { \"slot\" read-only } ... ;" }
{ $values { "slot" "a slot name" } { "?" "a boolean" } } { $values { "slot" "a slot name" } }
{ $description "Defines a tuple slot to be read-only. If a tuple has read-only slots, instances of the tuple should only be created by calling " { $link boa } ", instead of " { $link new } ". Using " { $link boa } " is the only way to set the value of a read-only slot." } ; { $description "Defines a tuple slot to be read-only. If a tuple has read-only slots, instances of the tuple should only be created by calling " { $link boa } ", instead of " { $link new } ". Using " { $link boa } " is the only way to set the value of a read-only slot." } ;
{ initial: read-only: } related-words { initial: read-only } related-words
HELP: SLOT: HELP: SLOT:
{ $syntax "SLOT: name" } { $syntax "SLOT: name" }

View File

@ -172,8 +172,7 @@ IN: bootstrap.syntax
"C:" [ "C:" [
CREATE-WORD CREATE-WORD
scan-word check-tuple-class scan-word [ boa ] curry define-inline
[ boa ] curry define-inline
] define-syntax ] define-syntax
"ERROR:" [ "ERROR:" [
@ -215,5 +214,5 @@ IN: bootstrap.syntax
"initial:" "syntax" lookup define-symbol "initial:" "syntax" lookup define-symbol
"read-only:" "syntax" lookup define-symbol "read-only" "syntax" lookup define-symbol
] with-compilation-unit ] with-compilation-unit

View File

@ -3,9 +3,9 @@ sequences.private accessors ;
IN: math.ranges IN: math.ranges
TUPLE: range TUPLE: range
{ from read-only: t } { from read-only }
{ length read-only: t } { length read-only }
{ step read-only: t } ; { step read-only } ;
: <range> ( a b step -- range ) : <range> ( a b step -- range )
>r over - r> >r over - r>