5. Control structure and local declarations
The control and declaration structure is given by <ClosedExp>:
<ClosedExp> ::= { <ExpSeq> } <ExpSeq> ::= <Exp>-Opt <ExpSeq> ::= <ExpSeq> ; <Exp>-Opt
This produces a TDF sequence if there is more than one <Exp>-Opt; if there is only one it is simply the production for <Exp>-Opt; any empty <Exp>-Opt produce make_top.
<ClosedExp> ::= <ConditionalExp> <ClosedExp> ::= <RepeatExp> <ClosedExp> ::= <LabelledExp> <ClosedExp> ::= <Local_Defn>
The effect of these, together with the expansion of <Assertion> is given below.
5.1. ConditionalExp and Assertion
<ConditionalExp> ::= ? { <ExpSeq> | <LabelSetting>-Opt <ExpSeq> } <LabelSetting> ::= : <Label> :
This produces a TDF conditional. The scope of a LABEL <ident> which may be introduced by <Label> is the first <ExpSeq>. A branch to the second half of the conditional will usually be made by the failure of an <Assertion> ( ie a TDF _test) in the first half.
<Assertion> ::= <Query> ( <Exp> <Ntest> <Exp> <FailDest>-Opt ) <Query> ::= ?
The assertion will be translated as an integer_test
<Query> ::= F?
The assertion will be translated as a floating_test with a wrap error_treatment.
<Query> ::= *?
The assertion will be translated as a pointer_test.
<Query> ::=.?
The assertion will be translated as an offset_test.
<Query> ::= P?
The assertion will be translated as a proc_test.
<FailDest> ::= | <Label>
The <Assertion> will produce the appropriate _test on its component <Exp>s. If the test fails, then control will pass to the <FailDest>-Opt. If <FailDest>-Opt is not empty, this is the <Label>. Otherwise, the <Assertion> must be in the immediate context of a <ConditionalExp> or <RepeatExp> with an empty <LabelSetting>-Opt; in which case this is treated as an anonymous label and control passes to there. For example, the following <Conditional> delivers the maximum of two integers:
?{ ?(a >= b); a | b }
This is equivalent to:
?{ ?(a >= b | L ); a | :L: b }
without the hassle of having to invent the LABEL name, L.
5.2. RepeatExp
<RepeatExp> ::= Rep <Starter>-Opt { <LabelSetting>-Opt <ExpSeq> } <Starter> = ( <ExpSeq> )
This produces a TDF repeat. The loop will usually repeat by an <Assertion> failing to the <LabelSetting>-Opt; an empty <LabelSetting>-Opt will follow the same conventions as one in a <Conditional>. An empty <Starter>-Opt will produce make_top.
5.3. LabelledExp
<LabelledExp> ::= Labelled { <ExpSeq> <Places> } <Places> ::= <Place> <Places> ::= <Places> <Place> <Place> ::= | : <Label> : <ExpSeq>
This produces a TDF labelled with the obvious parameters. The scope of any LABEL <idents> introduced by the <Label>s is the <LabelledExp>.
5.4. Local_Defn
A <Local_Defn> introduces an <ident> as a TAG for the scope of the component <ClosedExp>. Any containing an <Access> visible is also available globally - however it will only make sense in the constructor env_offset.
<Local_Defn> ::= Var <ident> <Access>-Opt <VarInit> <ClosedExp> <VarInit> ::= = <Exp>
This <Local_Defn> produces a TDF variable with the obvious parameters.
<Local_Defn> ::= Var <ident> <Access>-Opt : <Shape> <VarInit>-Opt <ClosedExp>
Also a TDF variable. An empty <VarInit>-Opt gives make_value(<Shape>) as the initialisation to the variable. Using this form of variable definition also has the advantage of allowing one to use the simple form of the contents operation (* in section 3.2.7).
<Local_Defn> ::= Let <ident> <Access>-Opt = <Exp> <ClosedExp>
This produces a TDF identify with the obvious parameters.