A Mica source is one unit, a program, a library or an object file, made of declarations, routines and a body. Its block declares, in any order and as often as it likes, its type parameters, imports, constants, types and variables; then its routines; then the statement that is its body. A routine has a block of its own, so routines nest.
compilation-unit
compilation-unit = unit-kind identifier ";" block "." .A unit: its kind, its name, its block and a final period.
unit-kind
unit-kind = "program" | "library" | "object" .What the unit becomes when it is linked.
Used in compilation-unit.
block
block = { declaration-section } { routine-declaration } action .Declarations, then routines, then the statement the block runs.
A section of declarations goes on as long as a line begins with a name, so a body that follows a section directly and begins with a name is read as one more declaration. Write the body as
begin ... end.
Routines nest at most sixteen deep. A callback’s body counts as the first level again, since a C library calls it directly.
Used in compilation-unit, routine-declaration.
declaration-section
declaration-section = generic-section | import-section | constant-section | type-section | variable-section .A section of declarations. No section follows a routine of the same block.
Used in block.
generic-section
generic-section = "gen" generic-parameter { generic-parameter } .The type parameters and value parameters that make the block’s routines generic.
Used in declaration-section.
generic-parameter
generic-parameter = identifier ( "is" identifier { "," identifier } | ":" identifier ) ";" .A type parameter with the capabilities it must offer, or a value parameter with its type.
Used in generic-section.
import-section
import-section = "imp" import-group { import-group } .Names taken from other units: the standard library std, the C surface cstd, a library by its name.
Used in declaration-section.
import-group
import-group = identifier ";" | ( "*" | import-member { "," import-member } ) ":" identifier ";" .A whole namespace, every name of a unit with *, or the listed names, each optionally under a name of its own.
*stands alone in its group and takes no other name.
Used in import-section.
import-member
import-member = identifier [ "=" identifier ] .A name to import, written Alias = Name to bind it under another name.
Used in import-group.
constant-section
constant-section = "const" constant-group { constant-group } .Named values.
Used in declaration-section.
constant-group
constant-group = constant-entry { "," constant-entry } ";" .One or more constants on a line.
Used in constant-section.
constant-entry
constant-entry = [ "exp" ] identifier ( "=" expression | ":" identifier "=" typed-constant-value ) .A constant, optionally exported with exp and optionally pinned to a named type.
Used in constant-group.
typed-constant-value
typed-constant-value = "(" expression { "," expression } ")" | (?! "(" ) expression .A typed constant’s value, or the list of an array constant in parentheses.
A typed constant’s value that opens with
(is read as a list, so it holds expressions only.
Used in constant-entry.
type-section
type-section = "type" type-declaration { type-declaration } .Named types.
Used in declaration-section.
type-declaration
type-declaration = [ "exp" ] identifier [ type-parameters ] "=" type-denoter ";" .A type, optionally exported, optionally generic over the type parameters behind of.
Used in type-section.
type-parameters
type-parameters = "of" ( identifier | "(" identifier { "," identifier } ")" ) .One type parameter, or several in parentheses.
Used in type-declaration.
variable-section
variable-section = "var" variable-group { variable-group } .Variables.
Used in declaration-section.
variable-group
variable-group = identifier ":" value-type [ "absolute" expression | ":=" expression ] ";"
| identifier "," identifier { "," identifier } ":" value-type ";" .Variables of one type; a single variable may carry an initial value or the fixed address of a device register.
An initial value and an absolute address each belong to one variable, and they exclude each other.
Used in variable-section, inline-variable-section.
routine-declaration
routine-declaration = [ "exp" ] ( intrinsic-declaration | [ "heapless" ] routine-heading ";" block ";" ) .A routine with its block, or the declaration of an intrinsic; exp exports it and heapless promises that it never uses the heap.
expstands in front ofheapless.
Used in block.
intrinsic-declaration
intrinsic-declaration = "intrinsic" identifier ";" .A word of the language’s own math vocabulary, declared by a unit that provides it.
Used in routine-declaration.
routine-heading
routine-heading = function-heading | procedure-heading | task-heading | generator-heading | callback-heading .The heading of one of the five kinds of routine.
Used in routine-declaration.
function-heading
function-heading = "function" identifier formal-parameters ":" result-type [ fails-clause ] .A function answers a value.
Used in routine-heading.
procedure-heading
procedure-heading = "procedure" identifier formal-parameters [ fails-clause ] .A procedure answers nothing.
Used in routine-heading.
task-heading
task-heading = "task" identifier formal-parameters [ fails-clause ] .A task runs beside the routine that schedules it.
Used in routine-heading.
generator-heading
generator-heading = "generator" identifier formal-parameters ":" "stream" "of" type-reference [ fails-clause ] .A generator answers a stream of the values it emits.
Used in routine-heading.
callback-heading
callback-heading = "callback" identifier formal-parameters [ ":" result-type ] [ fails-clause ] .A callback is a routine a C library calls back into; it answers a value or nothing, as the C slot does.
Used in routine-heading.
formal-parameters
formal-parameters = "(" [ parameter-group { "," parameter-group } ] ")" .The parameters in parentheses, which stand even when there are none.
Used in function-heading, procedure-heading, task-heading, generator-heading, callback-heading.
parameter-group
parameter-group = parameter-name { "," parameter-name } ":" parameter-type | parameter-name ":" conformant-schema
| identifier ":" "pointer" conformant-schema .Parameters of one type, or a parameter that takes any array of an element type with its bounds.
A conformant array parameter has a group of its own; its writable form behind
pointercannot beconst.
Used in formal-parameters.
parameter-name
parameter-name = [ "const" ] identifier .A parameter, which const makes read-only.
Used in parameter-group.
parameter-type
parameter-type = pointer-tensor-type | value-type .A parameter’s type.
Used in parameter-group.
conformant-schema
conformant-schema = "array" "[" identifier ".." identifier ":" type-name "]" "of" type-name .An array of any bounds: the two names receive the caller’s bounds, of the type behind the colon.
Used in parameter-group.
result-type
result-type = [ "tracked" (?= identifier | "array" ) ] ( shape-form | (?! "tensor" "of" ) type-reference ) .The type a function answers.
trackedpairs the type with the gradient tape only before a type’s name orarray; anywhere else it is the name of a type. A type namedtensortakes no type arguments here:tensor ofwould begin a tensor without its rank, which is refused.
Used in function-heading, callback-heading.
fails-clause
fails-clause = "fails" type-name .The error domain a routine may fail with.
Used in function-heading, procedure-heading, task-heading, generator-heading, callback-heading, stream-type.