]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/alien/syntax/syntax-docs.factor
alien.syntax: clarify that we can dispatch off ENUM: members
[factor.git] / basis / alien / syntax / syntax-docs.factor
index b7c77dd1547bc25a288ad6d4f30b945505b0e7af..8a72fe2bd69333e4d16e525fc5a801b08da8c87a 100644 (file)
@@ -1,6 +1,6 @@
 IN: alien.syntax
-USING: alien alien.c-types alien.parser alien.libraries
-classes.struct help.markup help.syntax see ;
+USING: alien alien.c-types alien.enums alien.libraries classes.struct
+help.markup help.syntax see ;
 
 HELP: DLL"
 { $syntax "DLL\" path\"" }
@@ -26,7 +26,7 @@ HELP: LIBRARY:
 { $notes "Logical library names are defined with the " { $link add-library } " word." } ;
 
 HELP: FUNCTION:
-{ $syntax "FUNCTION: return name ( parameters ) ;" }
+{ $syntax "FUNCTION: return name ( parameters )" }
 { $values { "return" "a C return type" } { "name" "a C function name" } { "parameters" "a comma-separated sequence of type/name pairs; " { $snippet "type1 arg1, type2 arg2, ..." } } }
 { $description "Defines a new word " { $snippet "name" } " which calls the C library function with the same " { $snippet "name" } " in the logical library given by the most recent " { $link POSTPONE: LIBRARY: } " declaration."
 $nl
@@ -40,17 +40,12 @@ $nl
 }
 "You can define a word for invoking it:"
 { $unchecked-example
-    "LIBRARY: foo\nFUNCTION: void the_answer ( c-string question, int value ) ;"
+    "LIBRARY: foo\nFUNCTION: void the_answer ( c-string question, int value )"
     "\"the question\" 42 the_answer"
     "The answer to the question is 42."
 } }
 "Using the " { $link c-string } " type instead of " { $snippet "char*" } " causes the FFI to automatically convert Factor strings to C strings. See " { $link "c-strings" } " for more information on using strings with the FFI."
-{ $notes "Note that the parentheses and commas are only syntax sugar and can be omitted; they serve no purpose other than to make the declaration easier to read. The following definitions are equivalent:"
-{ $code
-    "FUNCTION: void glHint ( GLenum target, GLenum mode ) ;"
-    "FUNCTION: void glHint GLenum target GLenum mode ;"
-}
-"To make a Factor word with a name different from the C function, use " { $link POSTPONE: FUNCTION-ALIAS: } "." } ;
+{ $notes "To make a Factor word with a name different from the C function, use " { $link POSTPONE: FUNCTION-ALIAS: } "." } ;
 
 HELP: FUNCTION-ALIAS:
 { $syntax "FUNCTION-ALIAS: factor-name
@@ -70,34 +65,55 @@ HELP: TYPEDEF:
 { $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ;
 
 HELP: ENUM:
-{ $syntax "ENUM: type/f words... ;" }
-{ $values { "type" "a name to typedef to int or f" } { "words" "a sequence of word names" } }
-{ $description "Creates a sequence of word definitions in the current vocabulary. Each word pushes an integer according to the rules of C enums." }
-{ $notes "This word emulates a C-style " { $snippet "enum" } " in Factor. While this feature can be used for any purpose, using integer constants is discouraged unless it is for interfacing with C libraries. Factor code should use " { $link "words.symbol" } " or " { $link "singletons" } " instead." }
+{ $syntax "ENUM: type words... ;" "ENUM: type < base-type words..." }
+{ $values { "type" { $maybe "a name to typedef to int" } } { "words" "a sequence of word names" } }
+{ $description "Creates a c-type that boxes and unboxes integer values to symbols. A singleton is defined for each member word which allows generic dispatch on the enum's members. The base c-type can optionally be specified and defaults to " { $link int } ". A constructor word " { $snippet "<type>" } " is defined for converting from integers to singletons. The generic word " { $link enum>number } " converts from singletons to integers. Enum-typed values are automatically prettyprinted as their singleton words. Unrecognizing enum numbers are kept as numbers." }
 { $examples
     "Here is an example enumeration definition:"
     { $code "ENUM: color_t red { green 3 } blue ;" }
-    "It is equivalent to the following series of definitions:"
-    { $code "CONSTANT: red 0" "CONSTANT: green 3" "CONSTANT: blue 4" }
+    $nl
+    "The following expression returns true:"
+    { $code "3 <color_t> [ green = ] [ enum>number 3 = ] bi and" }
+    $nl
+    "Here is a version where the C-type takes a single byte:"
+    { $code "ENUM: tv_peripherals_1 < uchar"
+            "{ appletv 1 } { chromecast 2 } { roku 4 } ;"
+    }
+    $nl
+    "The same as above but four bytes instead of one:"
+    { $code "ENUM: tv_peripherals_4 < uint"
+            "{ appletv 1 } { chromecast 2 } { roku 4 } ;"
+    }
+    $nl
+    "We can define a generic and dispatch on it:"
+    { $code "ENUM: tv_peripherals_4 < uint"
+            "{ appletv 1 } { chromecast 2 } { roku 4 } ;"
+            ""
+            "GENERIC: watch-device ( device -- )"
+            "M: appletv watch-device drop \"watching appletv\" print ;"
+            "M: chromecast watch-device drop \"watching chromecast\" print ;"
+            ""
+            "appletv watch-device"
+    }
 } ;
 
 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 " { $link pointer } "."
+{ $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 " { $link pointer } "." $nl
 { $snippet "C-TYPE:" } " can also be used to forward declare C types, allowing circular dependencies to occur between types. For example:"
-{ $code """C-TYPE: forward 
+{ $code "C-TYPE: forward
 STRUCT: backward { x forward* } ;
-STRUCT: forward { x backward* } ; """ } }
+STRUCT: forward { x backward* } ;" } }
 { $notes "Primitive C types are displayed using " { $snippet "C-TYPE:" } " syntax when they are " { $link see } "n." } ;
 
 HELP: CALLBACK:
-{ $syntax "CALLBACK: return type ( parameters ) ;" }
+{ $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, ..." } } }
 { $description "Defines a new function pointer C type word " { $snippet "type" } ". The newly defined word works both as a C type and as a wrapper for " { $link alien-callback } " for callbacks that accept the given return type and parameters. The ABI of the callback is decided from the ABI of the active " { $link POSTPONE: LIBRARY: } " declaration." }
 { $examples
     { $code
-        "CALLBACK: bool FakeCallback ( int message, void* payload ) ;"
+        "CALLBACK: bool FakeCallback ( int message, void* payload )"
         ": MyFakeCallback ( -- alien )"
         "    [| message payload |"
         "        \"message #\" write"
@@ -120,11 +136,21 @@ HELP: typedef
 
 { POSTPONE: TYPEDEF: typedef } related-words
 
-HELP: c-struct?
-{ $values { "c-type" "a C type" } { "?" "a boolean" } }
-{ $description "Tests if a C type is a structure defined by " { $link POSTPONE: STRUCT: } "." } ;
-
 HELP: C-GLOBAL:
 { $syntax "C-GLOBAL: type name" }
 { $values { "type" "a C type" } { "name" "a C global variable name" } }
-{ $description "Defines a new word named " { $snippet "name" } " which accesses a global variable in the current library, set with " { $link POSTPONE: LIBRARY: } "." } ;
+{ $description "Defines a getter " { $snippet "name" } " and setter " { $snippet "set-name" } " for the global value in the current library, set with " { $link POSTPONE: LIBRARY: } "." } ;
+
+HELP: INITIALIZE-ALIEN:
+{ $syntax "INITIALIZE-ALIEN: type ... ;" }
+{ $description "Initializes a " { $snippet "type" } " using the provided definition." } ;
+
+ARTICLE: "alien.enums" "Enumeration types"
+"The " { $vocab-link "alien.enums" } " vocab contains the implementation for " { $link POSTPONE: ENUM: } " C types, and provides words for converting between enum singletons and integers. It is possible to dispatch off of members of an enum."
+$nl
+"Defining enums:"
+{ $subsection POSTPONE: ENUM: }
+"Defining enums at run-time:"
+{ $subsection define-enum }
+"Conversions between enums and integers:"
+{ $subsections enum>number number>enum } ;