]> gitweb.factorcode.org Git - factor.git/commitdiff
Allow variants to be spread across multiple parsing words with a VARIANT-MEMBER:...
authorDoug Coleman <doug.coleman@gmail.com>
Fri, 2 Jul 2010 20:02:52 +0000 (15:02 -0500)
committerDoug Coleman <doug.coleman@gmail.com>
Fri, 9 Jul 2010 18:32:08 +0000 (13:32 -0500)
extra/variants/variants-docs.factor
extra/variants/variants-tests.factor
extra/variants/variants.factor

index 9a230a85352b39f92e75a086283abc3a35f4d532..e23b3ee8941256a2b8a2417df94c31605533e71c 100644 (file)
@@ -13,7 +13,7 @@ VARIANT: class-name
     .
     .
     ; """ }
-{ $description "Defines " { $snippet "class-name" } " as a union of the following " { $link singleton-class } " and " { $link tuple-class } " definitions. Each " { $snippet "singleton" } " word is defined as a " { $snippet "singleton-class" } ", and each " { $snippet "tuple" } " word is defined aas a " { $snippet "tuple-class" } " with the given set of " { $snippet "slot" } "s, using the same syntax for slot specifiers as " { $link POSTPONE: TUPLE: } ". Typed tuple slots can recursively reference the variant " { $snippet "class-name" } " being defined. For " { $snippet "tuple" } " types, a " { $link boa } " constructor word " { $snippet "<tuple>" } " is defined as well." }
+{ $description "Defines " { $snippet "class-name" } " as a union of the following " { $link singleton-class } " and " { $link tuple-class } " definitions. Each " { $snippet "singleton" } " word is defined as a " { $snippet "singleton-class" } ", and each " { $snippet "tuple" } " word is defined as a " { $snippet "tuple-class" } " with the given set of " { $snippet "slot" } "s, using the same syntax for slot specifiers as " { $link POSTPONE: TUPLE: } ". Typed tuple slots can recursively reference the variant " { $snippet "class-name" } " being defined. For " { $snippet "tuple" } " types, a " { $link boa } " constructor word " { $snippet "<tuple>" } " is defined as well." }
 { $examples { $code """
 USING: kernel variants ;
 IN: scratchpad
@@ -24,6 +24,18 @@ VARIANT: list
     ;
 """ } } ;
 
+HELP: VARIANT-MEMBER:
+{ $description "Defines a new member of a variant class without restricting such definitions to a single statement or source file. The variant class should be listed first, and the class member should follow." }
+{ $examples { $code """
+USING: kernel variants ;
+IN: scratchpad
+
+VARIANT: list ;
+
+VARIANT-MEMBER: list nil
+VARIANT-MEMBER: list cons: { { first object } { rest list } }
+""" } } ;
+
 HELP: match
 { $values { "branches" array } }
 { $description "Dispatches on the type of the value on the top of the stack. If the type is a " { $link singleton-class } ", the corresponding quotation is called with the underlying stack unchanged. If the type is a " { $link tuple-class } ", the tuple slots are pushed onto the stack by order of arguments." }
@@ -58,6 +70,7 @@ ARTICLE: "variants" "Algebraic data types"
 "The " { $vocab-link "variants" } " vocabulary provides syntax and combinators for defining and manipulating algebraic data types."
 { $subsections
     POSTPONE: VARIANT:
+    POSTPONE: VARIANT-MEMBER:
     variant-class
     match
 } ;
index ef48b36b9c7afa51f4fac84bd670e4d8092b3e04..f49cda6a993c3af5243fb220558980b18f12603b 100644 (file)
@@ -19,3 +19,21 @@ VARIANT: list
 
 [ 4 ]
 [ 5 6 7 8 nil <cons> <cons> <cons> <cons> list-length ] unit-test
+
+
+VARIANT: list2 ;
+VARIANT-MEMBER: list2 nil2
+VARIANT-MEMBER: list2 cons2: { { first object } { rest list2 } }
+
+[ t ] [ nil2 list2? ] unit-test
+[ t ] [ 1 nil2 <cons2> list2? ] unit-test
+[ f ] [ 1 list2? ] unit-test
+
+: list2-length ( list2 -- length )
+    {
+        { nil2  [ 0 ] }
+        { cons2 [ nip list2-length 1 + ] }
+    } match ;
+
+[ 4 ]
+[ 5 6 7 8 nil2 <cons2> <cons2> <cons2> <cons2> list2-length ] unit-test
index 5cb786afde568cb9a7489ded970b84b20395593d..df948b18635ba6cce3d9d1b162314f1b5ab733ec 100644 (file)
@@ -18,9 +18,15 @@ M: variant-class initial-value*
 : define-variant-member ( member -- class )
     dup array? [ first3 pick [ define-tuple-class-and-boa-word ] dip ] [ dup define-singleton-class ] if ;
 
-: define-variant-class ( class members -- )
-    [ [ define-mixin-class ] [ t "variant" set-word-prop ] [ ] tri ] dip
-    [ define-variant-member swap add-mixin-instance ] with each ;
+: define-variant-class ( class -- )
+    [ define-mixin-class ] [ t "variant" set-word-prop ] bi ;
+
+: define-variant-class-member ( class member -- )
+    define-variant-member swap add-mixin-instance ;
+
+: define-variant-class-members ( class members -- )
+    [ dup define-variant-class ] dip
+    [ define-variant-class-member ] with each ;
 
 : parse-variant-tuple-member ( name -- member )
     create-class-in tuple
@@ -38,7 +44,12 @@ M: variant-class initial-value*
 SYNTAX: VARIANT:
     CREATE-CLASS
     parse-variant-members
-    define-variant-class ;
+    define-variant-class-members ;
+
+SYNTAX: VARIANT-MEMBER:
+    scan-word
+    scan parse-variant-member
+    define-variant-class-member ;
 
 MACRO: unboa ( class -- )
     <wrapper> \ boa [ ] 2sequence [undo] ;