]> gitweb.factorcode.org Git - factor.git/commitdiff
redefine C-TYPE: to forward declare opaque C types; make C type definition and redefi...
authorJoe Groff <arcata@gmail.com>
Mon, 28 Sep 2009 03:11:51 +0000 (22:11 -0500)
committerJoe Groff <arcata@gmail.com>
Mon, 28 Sep 2009 03:12:00 +0000 (22:12 -0500)
basis/alien/c-types/c-types-docs.factor
basis/alien/c-types/c-types-tests.factor
basis/alien/c-types/c-types.factor
basis/alien/parser/parser.factor
basis/alien/syntax/syntax-docs.factor
basis/alien/syntax/syntax.factor

index 4f7083673726f6b5e824a5ca7731378d6a1a52d2..eb4be08764c767bffe9c9e9e01ecd2debbc097c8 100755 (executable)
@@ -88,16 +88,24 @@ HELP: uint
 { $description "This C type represents a four-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to 32 bits; output values will be returned as " { $link math:integer } "s." } ;
 HELP: long
 { $description "This C type represents a four- or eight-byte signed integer type. On Windows and on 32-bit Unix platforms, it will be four bytes. On 64-bit Unix platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
+HELP: intptr_t
+{ $description "This C type represents a signed integer type large enough to hold any pointer value; that is, on 32-bit platforms, it will be four bytes, and on 64-bit platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
 HELP: ulong
 { $description "This C type represents a four- or eight-byte unsigned integer type. On Windows and on 32-bit Unix platforms, it will be four bytes. On 64-bit Unix platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
+HELP: uintptr_t
+{ $description "This C type represents an unsigned integer type large enough to hold any pointer value; that is, on 32-bit platforms, it will be four bytes, and on 64-bit platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
+HELP: ptrdiff_t
+{ $description "This C type represents a signed integer type large enough to hold the distance between two pointer values; that is, on 32-bit platforms, it will be four bytes, and on 64-bit platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
+HELP: size_t
+{ $description "This C type represents unsigned size values of the size expected by the platform's standard C library (usually four bytes on a 32-bit platform, and eight on a 64-bit platform). Input values will be converted to " { $link math:integer } "s and truncated to the appropriate size; output values will be returned as " { $link math:integer } "s." } ;
 HELP: longlong
 { $description "This C type represents an eight-byte signed integer type. Input values will be converted to " { $link math:integer } "s and truncated to 64 bits; output values will be returned as " { $link math:integer } "s." } ;
 HELP: ulonglong
 { $description "This C type represents an eight-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to 64 bits; output values will be returned as " { $link math:integer } "s." } ;
 HELP: void
-{ $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definitionor an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
+{ $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definition or for an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
 HELP: void*
-{ $description "This C type represents a pointer to C memory. " { $link byte-array } " and " { $link alien } " values can be passed as inputs, but see " { $link "byte-arrays-gc" } " for notes about passing byte arrays into C functions. Output values are returned as " { $link alien } "s." } ;
+{ $description "This C type represents a pointer to C memory. " { $link byte-array } " and " { $link alien } " values can be passed as " { $snippet "void*" } " function inputs, but see " { $link "byte-arrays-gc" } " for notes about passing byte arrays into C functions. " { $snippet "void*" } " output values are returned as " { $link alien } "s." } ;
 HELP: char*
 { $description "This C type represents a pointer to a C string. See " { $link "c-strings" } " for details about using strings with the FFI." } ;
 HELP: float
index f48ed50a34c6f7fbb4476e22ac81191822dba658..d134d571896c9f79c8c068320fafb61db890daaa 100755 (executable)
@@ -1,6 +1,6 @@
 USING: alien alien.syntax alien.c-types alien.parser
-kernel tools.test sequences system libc alien.strings
-io.encodings.utf8 math.constants classes.struct ;
+eval kernel tools.test sequences system libc alien.strings
+io.encodings.utf8 math.constants classes.struct classes ;
 IN: alien.c-types.tests
 
 CONSTANT: xyz 123
@@ -15,28 +15,28 @@ UNION-STRUCT: foo
     { a int }
     { b int } ;
 
-[ f ] [ "char*"  parse-c-type c-type void* c-type eq? ] unit-test
-[ t ] [ "char**" parse-c-type c-type void* c-type eq? ] unit-test
+[ f ] [ char  resolve-pointer-type c-type void* c-type eq? ] unit-test
+[ t ] [ char* resolve-pointer-type c-type void* c-type eq? ] unit-test
 
 [ t ] [ foo heap-size int heap-size = ] unit-test
 
 TYPEDEF: int MyInt
 
-[ t ] [ int c-type MyInt c-type eq? ] unit-test
-[ t ] [ void* c-type "MyInt*" parse-c-type c-type eq? ] unit-test
+[ t ] [ int   c-type MyInt                      c-type eq? ] unit-test
+[ t ] [ void* c-type MyInt resolve-pointer-type c-type eq? ] unit-test
 
 TYPEDEF: char MyChar
 
-[ t ] [ char c-type MyChar c-type eq? ] unit-test
-[ f ] [  void*               c-type "MyChar*" parse-c-type c-type eq? ] unit-test
-[ t ] [ "char*" parse-c-type c-type "MyChar*" parse-c-type c-type eq? ] unit-test
+[ t ] [ char  c-type MyChar                      c-type eq? ] unit-test
+[ f ] [ void* c-type MyChar resolve-pointer-type c-type eq? ] unit-test
+[ t ] [ char* c-type MyChar resolve-pointer-type c-type eq? ] unit-test
 
 [ 32 ] [ { int 8 } heap-size ] unit-test
 
 TYPEDEF: char* MyString
 
-[ t ] [ char* c-type  MyString                c-type eq? ] unit-test
-[ t ] [ void* c-type "MyString*" parse-c-type c-type eq? ] unit-test
+[ t ] [ char* c-type MyString                      c-type eq? ] unit-test
+[ t ] [ void* c-type MyString resolve-pointer-type c-type eq? ] unit-test
 
 TYPEDEF: int* MyIntArray
 
@@ -59,3 +59,44 @@ os windows? cpu x86.64? and [
 [ -10 ] [ -10 char c-type-clamp ] unit-test
 [ 127 ] [ 230 char c-type-clamp ] unit-test
 [ t ] [ pi dup float c-type-clamp = ] unit-test
+
+C-TYPE: opaque
+
+[ t ] [ void* c-type opaque resolve-pointer-type c-type eq? ] unit-test
+[ opaque c-type ] [ no-c-type? ] must-fail-with
+
+[ """
+    USING: alien.syntax ;
+    IN: alien.c-types.tests
+    FUNCTION: opaque return_opaque ( ) ;
+""" eval( -- ) ] [ no-c-type? ] must-fail-with
+
+C-TYPE: forward
+STRUCT: backward { x forward* } ;
+STRUCT: forward { x backward* } ;
+
+[ t ] [ forward c-type struct-c-type? ] unit-test
+[ t ] [ backward c-type struct-c-type? ] unit-test
+
+DEFER: struct-redefined
+
+[ f ]
+[
+
+    """
+    USING: alien.c-types classes.struct ;
+    IN: alien.c-types.tests
+
+    STRUCT: struct-redefined { x int } ;
+    """ eval( -- )
+
+    """
+    USING: alien.syntax ;
+    IN: alien.c-types.tests
+
+    C-TYPE: struct-redefined
+    """ eval( -- )
+
+    \ struct-redefined class?
+] unit-test
+
index ab1c9df77e14b6c0859c7aba9ce243b85728e79a..dec7f92501459779cfaacc8ca716ceca59c4b907 100755 (executable)
@@ -53,7 +53,7 @@ ERROR: no-c-type name ;
 PREDICATE: c-type-word < word
     "c-type" word-prop ;
 
-UNION: c-type-name string word ;
+UNION: c-type-name string c-type-word ;
 
 ! C type protocol
 GENERIC: c-type ( name -- c-type ) foldable
@@ -62,6 +62,9 @@ GENERIC: resolve-pointer-type ( name -- c-type )
 
 << \ void \ void* "pointer-c-type" set-word-prop >>
 
+: void? ( c-type -- ? )
+    { void "void" } member? ;
+
 M: word resolve-pointer-type
     dup "pointer-c-type" word-prop
     [ ] [ drop void* ] ?if ;
@@ -75,6 +78,7 @@ M: string resolve-pointer-type
     ] if ;
 
 : resolve-typedef ( name -- c-type )
+    dup void? [ no-c-type ] when
     dup c-type-name? [ c-type ] when ;
 
 : parse-array-type ( name -- dims c-type )
@@ -91,10 +95,8 @@ M: string c-type ( name -- c-type )
     ] if ;
 
 M: word c-type
-    "c-type" word-prop resolve-typedef ;
-
-: void? ( c-type -- ? )
-    { void "void" } member? ;
+    dup "c-type" word-prop resolve-typedef
+    [ ] [ no-c-type ] ?if ;
 
 GENERIC: c-struct? ( c-type -- ? )
 
@@ -310,7 +312,7 @@ CONSTANT: primitive-types
     }
 
 SYMBOLS:
-    ptrdiff_t intptr_t size_t
+    ptrdiff_t intptr_t uintptr_t size_t
     char* uchar* ;
 
 [
@@ -471,9 +473,10 @@ SYMBOLS:
         [ >float ] >>unboxer-quot
     \ double define-primitive-type
 
-    \ long \ ptrdiff_t typedef
-    \ long \ intptr_t typedef
-    \ ulong \ size_t typedef
+    \ long c-type \ ptrdiff_t typedef
+    \ long c-type \ intptr_t typedef
+    \ ulong c-type \ uintptr_t typedef
+    \ ulong c-type \ size_t typedef
 ] with-compilation-unit
 
 M: char-16-rep rep-component-type drop char ;
index 16a994a8a7722e26ddf77e8bde24c69d723337a1..89e83a1d9bf8532a0313e440a0c0e275dcf140c2 100644 (file)
@@ -1,9 +1,9 @@
 ! Copyright (C) 2008, 2009 Slava Pestov, Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors alien alien.c-types arrays assocs
-combinators combinators.short-circuit effects grouping
-kernel parser sequences splitting words fry locals lexer
-namespaces summary math vocabs.parser ;
+USING: accessors alien alien.c-types arrays assocs classes
+combinators combinators.short-circuit compiler.units effects
+grouping kernel parser sequences splitting words fry locals
+lexer namespaces summary math vocabs.parser ;
 IN: alien.parser
 
 : parse-c-type-name ( name -- word )
@@ -25,10 +25,17 @@ IN: alien.parser
     [ parse-c-type ] if ; 
 
 : reset-c-type ( word -- )
+    dup "struct-size" word-prop
+    [ dup [ forget-class ] [ { "struct-size" } reset-props ] bi ] when
     { "c-type" "pointer-c-type" "callback-effect" "callback-abi" } reset-props ;
 
 : CREATE-C-TYPE ( -- word )
-    scan current-vocab create dup reset-c-type ;
+    scan current-vocab create {
+        [ fake-definition ]
+        [ set-word ]
+        [ reset-c-type ]
+        [ ]
+    } cleave ;
 
 : normalize-c-arg ( type name -- type' name' )
     [ length ]
index e04f6a471de4fb8c8fb723620e20ac5737f3a924..dbfc067bc6284acdc94bc920a688b7d14dff28ac 100644 (file)
@@ -1,5 +1,5 @@
 IN: alien.syntax
-USING: alien alien.c-types alien.parser classes.struct help.markup help.syntax ;
+USING: alien alien.c-types alien.parser classes.struct help.markup help.syntax see ;
 
 HELP: DLL"
 { $syntax "DLL\" path\"" }
@@ -65,6 +65,16 @@ HELP: C-ENUM:
     { $code "CONSTANT: red 0" "CONSTANT: green 1" "CONSTANT: blue 2" }
 } ;
 
+HELP: C-TYPE:
+{ $syntax "C-TYPE: type" }
+{ $values { "type" "a new C type" } }
+{ $description "Defines a new, opaque C type. Since it is opaque, " { $snippet "type" } " will not be directly usable as a parameter or return type of a " { $link POSTPONE: FUNCTION: } " or as a slot of a " { $link POSTPONE: STRUCT: } ". However, it can be used as the type of a pointer (that is, as " { $snippet "type*" } ")." $nl
+{ $snippet "C-TYPE:" } " can also be used to forward-declare C types to enable circular dependencies. For example:"
+{ $code """C-TYPE: forward 
+STRUCT: backward { x forward* } ;
+STRUCT: forward { x backward* } ; """ } }
+{ $notes "Primitive C types are also displayed using " { $snippet "C-TYPE:" } " syntax when they are displayed by " { $link see } "." } ;
+
 HELP: CALLBACK:
 { $syntax "CALLBACK: return type ( parameters ) ;" }
 { $values { "return" "a C return type" } { "type" "a type name" } { "parameters" "a comma-separated sequence of type/name pairs; " { $snippet "type1 arg1, type2 arg2, ..." } } }
index 85b763ba51e312aa3443d09437d59a903467de07..e27a5ef122e1664bc03779ab6d39fcb67c51e9cf 100644 (file)
@@ -32,7 +32,7 @@ SYNTAX: C-ENUM:
     [ [ create-in ] dip define-constant ] each-index ;
 
 SYNTAX: C-TYPE:
-    "Primitive C type definition not supported" throw ;
+    void CREATE-C-TYPE typedef ;
 
 ERROR: no-such-symbol name library ;