7. The Complete Syntax

Here is the complete syntax of Som in a simplified BNF. Do note that it might be incomplete due to the continuing development of the Som language. The irony of this has been duly noted.

program = toplevel* toplevel = import_statement | module_definition | value_definition | type_definition | extern_definition import_statement = "use" LONG_LIDENT | "from" LONG_LIDENT "use" "*" | "from" LONG_LIDENT "use" (LONG_IDENT ",")* LONG_IDENT module_definition = "mod" "{" toplevel* "}" value_definition = "let" LIDENT pattern* "=" expression type_definition = "type" PIDENT* UIDENT "is" type | "type" PIDENT* UIDENT "of" complex_type extern_definition = "ext" LIDENT ":" type | "ext" LIDENT "as" LIDENT pattern* ":" type complex_type = "|"? variant ("|" variant)* | "{" (field ("," field)*)? "}" variant = UIDENT (type (";" type)*)? field = LIDENT ":" type type = forall_type forall_type = (PIDENT+ ".")? function_type function_type = (function_type "->")? tuple_type tuple_type = constructed_type (";" constructed_type)* constructed_type = effect_type LONG_UIDENT? effect_type = "!"* atom_type atom_type = "(" type ")" | PRIMITIVE_TYPE | PIDENT | LONG_UIDENT pattern = atom_pattern atom_pattern = LIDENT | "_" expression = let_epxr | sequence_expr let_epxr = "let" LIDENT pattern* "=" let_epxr "in" let_epxr sequence_expr = (sequence_expr ",")? lambda_expr lambda_expr = ("\\" pattern* "->") tuple_expr tuple_expr = contraint_expr (";" constraint_expr)* constraint_expr = BASIC_EXPR (":" type)?

The meaning of the tokens such as LIDENT are as follows:

tokenmeaning
IDENTAny identifier, such as foo, Bar or baz'
LIDENTA lowercase identifier, such as foo
UIDENTAn uppercase identifier, such as Bar
PIDENTA lowercase identifier starting with a ', such as 'var
LONG_*The qualified version of the identifier, such as foo::Bar
PRIMITIVE_TYPEA primitive type, such as $i.s.32 or $f.*
BASIC_EXPRA simple expression, such as 1 + 2 or "foo"