classes.struct: fix some bugs

- STRUCT: foo<ENTER> in listener threw an error
- S{ did not throw an error when used with non-struct types
- attempting to subclass a struct class now fails
- forgetting a struct class now removes the corresponding C type
- 'see'ing a struct class now indents correctly
db4
Slava Pestov 2009-09-10 15:59:27 -05:00
parent d9ebfe5f48
commit d5bc1ceca2
4 changed files with 64 additions and 56 deletions

View File

@ -18,12 +18,12 @@ IN: classes.struct.prettyprint
: pprint-struct-slot ( slot -- ) : pprint-struct-slot ( slot -- )
<flow \ { pprint-word <flow \ { pprint-word
{ f <inset {
[ name>> text ] [ name>> text ]
[ c-type>> dup string? [ text ] [ pprint* ] if ] [ c-type>> dup string? [ text ] [ pprint* ] if ]
[ read-only>> [ \ read-only pprint-word ] when ] [ read-only>> [ \ read-only pprint-word ] when ]
[ initial>> [ \ initial: pprint-word pprint* ] when* ] [ initial>> [ \ initial: pprint-word pprint* ] when* ]
} cleave } cleave block>
\ } pprint-word block> ; \ } pprint-word block> ;
: pprint-struct ( struct -- ) : pprint-struct ( struct -- )

View File

@ -1,31 +1,16 @@
! (c)Joe Groff bsd license ! (c)Joe Groff bsd license
USING: accessors alien alien.c-types alien.libraries USING: accessors alien alien.c-types alien.structs.fields ascii
alien.structs.fields alien.syntax ascii assocs byte-arrays assocs byte-arrays classes.struct classes.tuple.private
classes.struct classes.tuple.private combinators combinators compiler.tree.debugger compiler.units destructors
compiler.tree.debugger compiler.units destructors
io.encodings.utf8 io.pathnames io.streams.string kernel libc io.encodings.utf8 io.pathnames io.streams.string kernel libc
literals math mirrors multiline namespaces prettyprint literals math mirrors multiline namespaces prettyprint
prettyprint.config see sequences specialized-arrays prettyprint.config see sequences specialized-arrays system
system tools.test ; tools.test parser lexer eval ;
SPECIALIZED-ARRAY: char SPECIALIZED-ARRAY: char
SPECIALIZED-ARRAY: int SPECIALIZED-ARRAY: int
SPECIALIZED-ARRAY: ushort SPECIALIZED-ARRAY: ushort
IN: classes.struct.tests IN: classes.struct.tests
<<
: libfactor-ffi-tests-path ( -- string )
"resource:" (normalize-path)
{
{ [ os winnt? ] [ "libfactor-ffi-test.dll" ] }
{ [ os macosx? ] [ "libfactor-ffi-test.dylib" ] }
{ [ os unix? ] [ "libfactor-ffi-test.so" ] }
} cond append-path ;
"f-cdecl" libfactor-ffi-tests-path "cdecl" add-library
"f-stdcall" libfactor-ffi-tests-path "stdcall" add-library
>>
SYMBOL: struct-test-empty SYMBOL: struct-test-empty
[ [ struct-test-empty { } define-struct-class ] with-compilation-unit ] [ [ struct-test-empty { } define-struct-class ] with-compilation-unit ]
@ -278,15 +263,6 @@ STRUCT: struct-test-equality-2
] with-destructors ] with-destructors
] unit-test ] unit-test
STRUCT: struct-test-ffi-foo
{ x int }
{ y int } ;
LIBRARY: f-cdecl
FUNCTION: int ffi_test_11 ( int a, struct-test-ffi-foo b, int c ) ;
[ 14 ] [ 1 2 3 struct-test-ffi-foo <struct-boa> 4 ffi_test_11 ] unit-test
STRUCT: struct-test-array-slots STRUCT: struct-test-array-slots
{ x int } { x int }
{ y ushort[6] initial: ushort-array{ 2 3 5 7 11 13 } } { y ushort[6] initial: ushort-array{ 2 3 5 7 11 13 } }
@ -350,3 +326,27 @@ STRUCT: struct-that's-a-word { x int } ;
[ -77 ] [ S{ struct-that's-a-word { x -77 } } clone x>> ] unit-test [ -77 ] [ S{ struct-that's-a-word { x -77 } } clone x>> ] unit-test
! Interactive parsing of struct slot definitions
[
"USE: classes.struct IN: classes.struct.tests STRUCT: unexpected-eof-test" <string-reader>
"struct-class-test-1" parse-stream
] [ error>> error>> unexpected-eof? ] must-fail-with
! S{ with non-struct type
[
"USE: classes.struct IN: classes.struct.tests TUPLE: not-a-struct ; S{ not-a-struct }"
eval( -- value )
] must-fail
! Subclassing a struct class should not be allowed
[
"USE: classes.struct IN: classes.struct.tests STRUCT: a-struct { x int } ; TUPLE: not-a-struct < a-struct ;"
eval( -- )
] must-fail
! Remove c-type when struct class is forgotten
[ ] [
"USE: classes.struct IN: classes.struct.tests TUPLE: a-struct ;" eval( -- )
] unit-test
[ f ] [ "a-struct" c-types get key? ] unit-test

View File

@ -6,7 +6,7 @@ combinators combinators.short-circuit combinators.smart
definitions functors.backend fry generalizations generic.parser definitions functors.backend fry generalizations generic.parser
kernel kernel.private lexer libc locals macros make math kernel kernel.private lexer libc locals macros make math
math.order parser quotations sequences slots slots.private math.order parser quotations sequences slots slots.private
specialized-arrays vectors words specialized-arrays vectors words summary namespaces assocs
compiler.tree.propagation.transforms ; compiler.tree.propagation.transforms ;
FROM: slots => reader-word writer-word ; FROM: slots => reader-word writer-word ;
IN: classes.struct IN: classes.struct
@ -15,16 +15,23 @@ SPECIALIZED-ARRAY: uchar
ERROR: struct-must-have-slots ; ERROR: struct-must-have-slots ;
M: struct-must-have-slots summary
drop "Struct definitions must have slots" ;
TUPLE: struct TUPLE: struct
{ (underlying) c-ptr read-only } ; { (underlying) c-ptr read-only } ;
TUPLE: struct-slot-spec < slot-spec TUPLE: struct-slot-spec < slot-spec
c-type ; c-type ;
PREDICATE: struct-class < tuple-class \ struct subclass-of? ; PREDICATE: struct-class < tuple-class
superclass \ struct eq? ;
: struct-slots ( struct-class -- slots ) M: struct-class valid-superclass? drop f ;
"struct-slots" word-prop ;
GENERIC: struct-slots ( struct-class -- slots )
M: struct-class struct-slots "struct-slots" word-prop ;
! struct allocation ! struct allocation
@ -175,36 +182,27 @@ M: struct-class writer-quot
[ c-type>> c-type-align ] [ max ] map-reduce ; [ c-type>> c-type-align ] [ max ] map-reduce ;
PRIVATE> PRIVATE>
M: struct-class c-type M: struct-class c-type name>> c-type ;
name>> c-type ;
M: struct-class c-type-align M: struct-class c-type-align c-type c-type-align ;
"struct-align" word-prop ;
M: struct-class c-type-getter M: struct-class c-type-getter c-type c-type-getter ;
drop [ swap <displaced-alien> ] ;
M: struct-class c-type-setter M: struct-class c-type-setter c-type c-type-setter ;
[ c-type-getter ] [ c-type-unboxer-quot ] [ heap-size ] tri
'[ @ swap @ _ memcpy ] ;
M: struct-class c-type-boxer-quot M: struct-class c-type-boxer-quot c-type c-type-boxer-quot ;
(boxer-quot) ;
M: struct-class c-type-unboxer-quot M: struct-class c-type-unboxer-quot c-type c-type-boxer-quot ;
(unboxer-quot) ;
M: struct-class heap-size M: struct-class heap-size c-type heap-size ;
"struct-size" word-prop ;
M: struct byte-length M: struct byte-length class "struct-size" word-prop ; foldable
class "struct-size" word-prop ; foldable
! class definition ! class definition
<PRIVATE <PRIVATE
: make-struct-prototype ( class -- prototype ) : make-struct-prototype ( class -- prototype )
[ heap-size <byte-array> ] [ "struct-size" word-prop <byte-array> ]
[ memory>struct ] [ memory>struct ]
[ struct-slots ] tri [ struct-slots ] tri
[ [
@ -237,8 +235,9 @@ M: struct byte-length
: (define-struct-class) ( class slots offsets-quot -- ) : (define-struct-class) ( class slots offsets-quot -- )
[ [
empty?
[ struct-must-have-slots ] [ struct-must-have-slots ]
[ drop redefine-struct-tuple-class ] if-empty [ redefine-struct-tuple-class ] if
] ]
swap '[ swap '[
make-slots dup make-slots dup
@ -254,6 +253,9 @@ PRIVATE>
: define-union-struct-class ( class slots -- ) : define-union-struct-class ( class slots -- )
[ union-struct-offsets ] (define-struct-class) ; [ union-struct-offsets ] (define-struct-class) ;
M: struct-class reset-class
[ call-next-method ] [ name>> c-types get delete-at ] bi ;
ERROR: invalid-struct-slot token ; ERROR: invalid-struct-slot token ;
: struct-slot-class ( c-type -- class' ) : struct-slot-class ( c-type -- class' )
@ -277,6 +279,7 @@ ERROR: invalid-struct-slot token ;
scan { scan {
{ ";" [ f ] } { ";" [ f ] }
{ "{" [ parse-struct-slot over push t ] } { "{" [ parse-struct-slot over push t ] }
{ f [ unexpected-eof ] }
[ invalid-struct-slot ] [ invalid-struct-slot ]
} case ; } case ;

View File

@ -252,8 +252,13 @@ M: tuple-class update-class
[ [ "slots" word-prop ] dip = ] [ [ "slots" word-prop ] dip = ]
bi-curry* bi and ; bi-curry* bi and ;
: valid-superclass? ( class -- ? ) GENERIC: valid-superclass? ( class -- ? )
[ tuple-class? ] [ tuple eq? ] bi or ;
M: tuple-class valid-superclass? drop t ;
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 valid-superclass? [ bad-superclass ] unless drop ;