A statement acts: it assigns, calls, chooses, repeats, leaves, fails, emits, or runs tasks and waits for them. Statements are separated by semicolons, and an empty statement is allowed wherever one is, so a semicolon before end does no harm. Several words open statements only where they stand: next and fail before a name, concurrent and tape before a statement, and so on; everywhere else they are ordinary names.
statement
statement = [ action ] .A statement, or nothing.
Used in statement-sequence, if-statement, while-statement, repeat-statement, for-statement, case-statement, case-element, select-arm.
action
action = assignment-statement | call-statement | compound-statement | if-statement | while-statement | repeat-statement
| for-statement | case-statement | labeled-loop | leave-statement | next-statement | defer-statement
| dispose-statement | fail-statement | emit-statement | schedule-statement | select-statement | concurrent-block
| synchronized-statement | tape-window .A statement that does something.
Used in block, statement, repeat-statement, defer-statement, handler-section, lost-section, synchronized-statement, value-consumption, statement-consumption.
compound-statement
compound-statement = "begin" statement-sequence "end" .Statements between begin and end.
Used in action.
statement-sequence
statement-sequence = { inline-variable-section } statement { ";" { inline-variable-section } statement } .Statements separated by semicolons, with variable declarations where a statement may stand.
Used in compound-statement, concurrent-block, tape-window.
inline-variable-section
inline-variable-section = "var" variable-group .A variable declared where a statement stands, visible to the end of its statement sequence.
Used in statement-sequence, repeat-statement.
assignment-statement
assignment-statement = assignment-target ":=" ( scheduled-stream | expression ) [ value-consumption ] .A value is assigned, with what to do when the value’s call fails.
Used in action.
assignment-target
assignment-target = [ "value" ] identifier { selector } | "value" parenthesized-value { selector } .A variable, a field or element of one, or what a pointer points to.
Used in assignment-statement.
scheduled-stream
scheduled-stream = "schedule" identifier [ type-arguments ] actual-parameters [ "buffer" expression ]
[ process-placement ] .A stream fed by a generator running as a task, with a buffer of a given capacity.
Used in assignment-statement.
call-statement
call-statement = routine-name actual-parameters [ statement-consumption ] .A routine is called, with what to do when it fails.
Used in action.
routine-name
routine-name = identifier [ "." identifier ] .A routine’s name, qualified by its namespace when one is written.
Used in call-statement, function-call.
actual-parameters
actual-parameters = "(" [ expression { "," expression } ] ")" .The arguments in parentheses, which stand even when there are none.
Used in scheduled-stream, call-statement, schedule-statement, function-call.
if-statement
if-statement = "if" expression "then" statement [ "else" statement ] .A choice between two statements.
An
elsebelongs to the nearestif; a semicolon before it is refused.
Used in action.
while-statement
while-statement = "while" expression "do" statement .A loop that tests before each round.
Used in action, labeled-loop.
repeat-statement
repeat-statement = "repeat" { inline-variable-section } action { ";" { inline-variable-section } statement } "until"
expression .A loop that tests after each round.
Used in action, labeled-loop.
for-statement
for-statement = "for" identifier ( ":=" expression ( "to" | "downto" ) expression "do" statement
| "in" expression "do" statement [ statement-consumption ] [ lost-section ] ) .A counted loop, or a loop over the elements of a container or a stream.
Used in action, labeled-loop.
case-statement
case-statement = "case" expression "of"
( case-element { ";" case-element } [ ";" | "else" statement ] | [ "else" statement ] ) "end" .A choice by value, with arms for single values, ranges and the cases of a sum type.
A call in the selector writes no type arguments: the
ofbehind a name there is the case statement’s own.
Used in action.
case-element
case-element = case-label { "," case-label } ":" statement .Labels and the statement they lead to.
Used in case-statement.
case-label
case-label = identifier "(" "*" ")" | expression [ ".." expression ] .A value, a range, or a case of a sum type that binds nothing with *.
Used in case-element.
case-pattern
case-pattern = identifier "(" "*" ")" | cast-expression .The right side of an is test: a case of a sum type, binding nothing with *, its fields to names, or nothing at all.
Used in relation.
labeled-loop
labeled-loop = identifier ":" ( while-statement | repeat-statement | for-statement ) .A loop with a name that leave and next can address.
Used in action.
leave-statement
leave-statement = "leave" ( loop-target | (?! identifier - "when" ) ) [ when-guard ] .A statement that leaves the routine, or the named loop, when the guard holds.
A name behind
leaveis always its loop’s name, so a bareleavedirectly before anon failsection needs a semicolon.
Used in action.
next-statement
next-statement = "next" ( loop-target | (?! "." | identifier - "when" ) ) [ when-guard ] .A statement that goes on with the next round of the innermost or the named loop, when the guard holds.
A name behind
nextis always the name of the loop it continues, and a period behind it selects a field of a variable namednext, so a barenextdirectly before anon failsection or a unit’s final period stands insidebegin ... end.
Used in action.
loop-target
loop-target = identifier - "when" .The loop a leave or next addresses.
A loop named
whencannot be addressed: behindleaveandnextthe word always opens the guard.
Used in leave-statement, next-statement.
when-guard
when-guard = "when" expression .The condition under which leave or next acts.
whenis a word only here; anywhere else it is an ordinary name.
Used in leave-statement, next-statement.
defer-statement
defer-statement = "defer" [ until-owner ] action .A statement that runs when the routine, or the named one, or the program, ends.
Used in action.
until-owner
until-owner = "until" ( identifier | "program" ) .The routine, or the program, whose end runs a deferred statement or releases an allocation.
Used in defer-statement, allocation.
dispose-statement
dispose-statement = "dispose" expression .What a pointer points to is released.
Used in action.
fail-statement
fail-statement = "fail" (?= identifier ) expression .The routine fails with an error code of its domain.
failopens the statement only before a name, as an error domain’s codes are; anywhere else it is an ordinary name, sofail(...)calls a routine namedfail.
Used in action.
emit-statement
emit-statement = "emit" (?! "[" ) expression .A generator hands a value to whoever pulls from its stream, and waits for the next pull.
A bracket behind
emitselects an element of a variable namedemit. Inside a generator’s own body, a parenthesis behindemitopens the emitted value; anywhere elseemit(...)calls a routine namedemit.
Used in action.
schedule-statement
schedule-statement = "schedule" identifier [ type-arguments ] actual-parameters [ "into" identifier ]
[ process-placement ] .A task is created and made ready to run, joining the stream named behind into when one is.
Used in action.
process-placement
process-placement = "on" "process" .The work runs in a worker process of its own.
Used in scheduled-stream, schedule-statement.
select-statement
select-statement = "select" select-arm { select-arm } "end" [ statement-consumption ] .A wait on several streams at once, or until a timeout.
Used in action.
select-arm
select-arm = "on" ( "timeout" expression "do" statement | ( identifier - "timeout" ) "in" identifier "do" statement )
[ ";" ] .An arm that takes the next element of a stream, or the arm that runs when the wait times out.
Behind
onthe wordtimeoutalways opens the arm that runs when the wait times out, so no arm binds an element to the nametimeout.
Used in select-statement.
concurrent-block
concurrent-block = "concurrent" (?! ";" ) statement-sequence { handler-section } [ "on" "fail" "continue" [ ";" ] ]
[ lost-section [ ";" ] ] "end" .A block whose end waits for every task it scheduled, with sections for the failures and the lost workers of its tasks.
Before a semicolon
concurrentis an ordinary name, so the block’s first statement is never empty.
The section that discards every failure,
on fail continue, stands behind the sections that handle one.
Used in action.
handler-section
handler-section = "on" "fail" identifier "do" action [ ";" ] .A section that handles a failure of the binding’s error domain.
Used in concurrent-block.
lost-section
lost-section = "on" "lost" "do" action .A section that runs when a worker process ended before its work did.
Used in for-statement, concurrent-block.
synchronized-statement
synchronized-statement = "synchronized" action .A statement that runs without a task switch, so a task can update its parent’s state as one step.
Used in action.
tape-window
tape-window = "tape" (?! ";" ) statement-sequence "end" .Statements whose operations on tracked values are recorded on the gradient tape.
Before a semicolon
tapeis an ordinary name, so the window’s first statement is never empty.
Used in action.
value-consumption
value-consumption = "on" "fail" ( "leave" | "use" expression | identifier "do" action ) .What an assignment does when its call fails: pass the failure on, use another value, or handle it.
Used in assignment-statement.
statement-consumption
statement-consumption = "on" "fail" ( "leave" | "continue" | identifier "do" action ) .What a call, a loop or a select does when it fails: pass the failure on, discard it, or handle it.
A consumption binds to the innermost statement it can follow, so one meant for a loop wants a
begin ... endbody when the body is itself a call.
Used in call-statement, for-statement, select-statement.