 upper     = [A-Z]
 alpha     = [A-Za-z]
 digit     = [0-9]
-number    = digit+                        => [[ string>number ]]
-
-length    =  ws "["~ ws number ws "]"~
-
-type      =  ws "<"~ ws any-type ws ">"~
-
-uint      = "uint"                        => [[ uint ]]
-u8        = "u8"                          => [[ u8 ]]
-u16       = "u16"                         => [[ u16 ]]
-u32       = "u32"                         => [[ u32 ]]
-u64       = "u64"                         => [[ u64 ]]
-
-int       = "int"                         => [[ int ]]
-i8        = "i8"                          => [[ i8 ]]
-i16       = "i16"                         => [[ i16 ]]
-i32       = "i32"                         => [[ i32 ]]
-i64       = "i64"                         => [[ i64 ]]
-
-f32       = "f32"                         => [[ f32 ]]
-f64       = "f64"                         => [[ f64 ]]
-
-bool      = "bool"                        => [[ bool ]]
-str       = "str"                         => [[ str ]]
-data      = "data"~ length?               => [[ <data> ]]
-void      = "void"                        => [[ void ]]
-
+number    = digit+                         => [[ string>number ]]
+
+length    = ws "["~ ws number ws "]"~
+value     = ws "="~ ws number
+
+type      = ws "<"~ ws any-type ws ">"~
+
+uint      = "uint"                         => [[ uint ]]
+u8        = "u8"                           => [[ u8 ]]
+u16       = "u16"                          => [[ u16 ]]
+u32       = "u32"                          => [[ u32 ]]
+u64       = "u64"                          => [[ u64 ]]
+
+int       = "int"                          => [[ int ]]
+i8        = "i8"                           => [[ i8 ]]
+i16       = "i16"                          => [[ i16 ]]
+i32       = "i32"                          => [[ i32 ]]
+i64       = "i64"                          => [[ i64 ]]
+
+f32       = "f32"                          => [[ f32 ]]
+f64       = "f64"                          => [[ f64 ]]
+
+bool      = "bool"                         => [[ bool ]]
+str       = "str"                          => [[ str ]]
+data      = "data"~ length?                => [[ <data> ]]
+void      = "void"                         => [[ void ]]
+
+enum-value-name = upper (upper|digit|[_])* => [[ first2 swap prefix >string ]]
+enum-value = enum-value-name value?        => [[ >array ]]
 enum-values = (ws enum-value ws)*
-enum-value = enum-value-name (ws "="~ ws number)?
-enum-value-name = upper (upper|digit|[_])* => [[ first2 swap prefix >string ]]
 enum      = "enum"~ ws "{"~ ws enum-values ws "}"~ => [[ <enum> ]]
 
 uints     = uint|u8|u16|u32|u64


SYMBOL: user-types

EBNF: (parse-schema) [=[

space     = [ \t\n]

floats    = f32|f64
primitive = uints|ints|floats|bool|str|data|void|enum

optional  = "optional"~ type               => [[ <optional> ]]
list      = "list"~ type length?           => [[ first2 <list> ]]
map       = "map"~ type type               => [[ first2 <map> ]]

struct-field-name = alpha+                 => [[ >string ]]
struct-field = struct-field-name ws ":"~ ws any-type => [[ >array ]]
struct-fields = (ws struct-field ws)*
struct    = "struct"~ ws "{"~ ws struct-fields ws "}"~ => [[ <struct> ]]

union-member  = any-type value?            => [[ >array ]]
union-members = union-member (ws "|"~ ws union-member)* => [[ first2 swap prefix ]]
union     = "union"~ ws "{"~ ws ("|"?)~ ws union-members? ws ("|"?)~ ws "}"~ => [[ <union> ]]

aggregate = optional|list|map|struct|union

defined   = user-type-name => [[ lookup-user-type ]]

any-type  = aggregate|primitive|defined

user-type-name = (alpha|digit)+            => [[ >string ]]
user-type = "type"~ ws user-type-name ws any-type
          => [[ first2 [ insert-user-type ] [ 2array ] 2bi ]]

schema = (ws user-type ws)* => [[ <schema> ]]

