## 5.1 The Base Language

### Declarations

<in statement> ::=

D `in` S |  | `local` D `in` S `end`

<in expression> ::=

D `in` [ S ]`` E |  | `local` D `in` [ S ]`` E `end`

The following rule makes implicit declarations explicit, i. e., declarations only name variables between `local` and `in`. We need an auxiliary definition: The function PV returns the set of pattern variables of a statement (or expression). Furthermore, we call a position p in a given statement S a pattern position iff the following holds: If the subterm at position p of S is replaced by a fresh variable `X`, then `X` PV(S[`X`/p]).

D | PV(D)
--- | ---
D1`` D2 | PV(D1) PV(D2)
x | {x}
`(`S`)` | PV(S)
`(`D `in` S`)` | PV(S) - PV(D)
`local` D `in` S `end` | PV(S) - PV(D)
`proc` ...`{`E`` ...`}` ...`end` | PV(E)
`fun` ...`{`E`` ...`}` ...`end` | PV(E)
`class` E`` ...`end` | PV(E)
`functor` E`` ...`end` | PV(E)
E`=` ... | PV(E)
otherwise |

E | PV(E)
--- | ---
x | {x}
`(`E`)` | PV(E)
`(`D `in` [ S ]`` E`)` | (PV(S) PV(E)) - PV(D)
`local` D `in` [ S ]`` E `end` | (PV(S) PV(E)) - PV(D)
E1`=` E2 | PV(E1) PV(E2)
`[`E1`` ...`` En`]` | PV(E1) ... PV(En)
E1`|`E2 | PV(E1) PV(E2)
E1`#`...`#`En | PV(E1) ... PV(En)
l`(`[ f1`:` ]`` E1`` ...`` [ fn`:` ]`` En`` [ `...` ]`)` | PV(E1) ... PV(En)
otherwise |

<statement> ::=

`local` D `in` S `end` |  | `local` x1`` ...`` xn `in` D'`` S `end`

if D is not a sequence of distinct variables and where {x1, ..., xn} = PV(D) and D' is D with singleton variables and escapes in pattern position removed.

<statement> ::=

x`= local` D `in` [ S ]`` E `end` |  | `local` `X` `in` `X``=` x `local` D `in` [ S ]`` `X``=` E `end end`

### Grouping

<statement> ::=

`(`S`)` |  | S

<expression> ::=

`(`E`)` |  | E

### Procedure Definitions

<statement> ::=

`proc` ...`{`E`` P1`` ...`` Pn`}` SE `end` |  | `local` `X` `in` `X``=` E `proc` ...`{``X``` P1`` ...`` Pn`}` SE `end end`

if E is no variable.

<statement>, <expression> ::=

`fun` ...`lazy` ...`{`E1`` P1`` ...`` Pn`}` E2 `end` |  | `fun` ...`{`E1`` `X1``` ...`` `X` n`} {`Value.byNeed` fun {$} case` `X1``#`...`#``X` n `of` P1`#`...`#`Pn `then` E2 `end end} end`

where all occurrences of `lazy` are removed from the procedure flags.

<statement>, <expression> ::=

`fun` ...`{`E1`` P1`` ...`` Pn`}` E2 `end` |  | `proc` ...`{`E1`` P1`` ...`` Pn`$}` E2 `end`

if no `$` occurs in P1 ... Pn and no `lazy` occurs in the procedure flags.

<statement>, <expression> ::=

`proc` ...`{`E1`` P1`` ...`` Pk`` ...`` Pn`}` E2 `end` |  | `proc` ...`{`E1`` P1`` ...`` Pk'`` ...`` Pn`}` `X``=` E2 `end`

if `$` occurs in Pk and no other `$` occurs in P1 ... Pn and no `lazy` occurs in the procedure flags. Pk' is the result of replacing the `$` in Pk by `X`.

<statement>, <expression> ::=

`proc` ...`{`E`` P1`` ...`` Pn`}` S `end` |  | `proc` ...`{`E`` `X1``` ...`` `X` n`} case` `X1``#`...`#``X` n `of` P1`#`...`#`Pn `then` S `end end`

if P1 ... Pn are not distinct variables and no `$` occurs in P1 ... Pn and no `lazy` occurs in the procedure flags.

<statement> ::=

x`= proc` ...`{$` ...`}` SE `end` |  | `proc` ...`{`x`` ...`}` SE `end`

### Applications

Actual arguments are evaluated from left to right and after the designator expression.

<statement> ::=

`{`E1`` ...`` Ek`` ...`` En`}` |  | `local` `X` `in` `X``=` Ek`{`E1`` ...`` `X``` ...`` En`} end`

if Ek is no variable and all Ei with i < k are variables.

<statement> ::=

x`= {`E`` E1`` ...`` En`}` |  | `{`E`` E1`` ...`` En`` x`}`

if no `$` occurs in E1 ... En in pattern position.

<statement> ::=

x`= {`E`` E1`` ...`` Ek`` ...`` En`}` |  | `{`E`` E1`` ...`` Ek'`` ...`` En`}`

if `$` occurs in Ek in pattern position and no other `$` occurs in E1 ... En in pattern position. Ek' is the result of replacing the `$` in pattern position in Ek by x.

### Boolean and Pattern-Matching Conditionals

<else statement>, <else expression> ::=

`elseif` ... |  | `else if` ...`end`

<else statement>, <else expression> ::=

`elsecase` ... |  | `else case` ...`end`

<statement> ::=

`if` E `then` S `end` |  | `if` E `then` S `else skip end`

<expression> ::=

`if` E1 `then` E1 `end` |  | `if` E1 `then` E2 `else raise error(kernel(noElse` ...`)` ...`) end end`

where the omitted parts of the exception are implementation-dependent.

<statement>, <expression> ::=

`if` E `then` SE1 `else` SE2 `end` |  | `case` E `of true then` SE1`[] false then` SE2 `else raise error(kernel(boolCaseType` ...`)` ...`) end end`

where the omitted parts of the exception are implementation-dependent.

<statement>, <expression> ::=

`case` E `of` ...`end` |  | `local` `X` `in` `X``=` E `case` `X` `of` ...`end end`

if E is no variable.

<statement>, <expression> ::=

`case` E `of` C1`[]` ...`[]` Cn `end` |  | `case` E `of` C1`[]` ...`[]` Cn `else raise error(kernel(noElse` ...`)` ...`) end end`

where the omitted parts of the exception are implementation-dependent.

Missing: expansion of `case` statement/expression to `cond`

### Locks

<statement>, <expression> ::=

`lock` E `then` SE `end` |  | `local` `X` `in` `X``=` E `lock` `X` `then` SE `end end`

if E is no variable.

<statement> ::=

x`= lock` E1 `then` E2 `end` |  | `lock` E1 `then` x`=` E2 `end`

### Threads

<statement> ::=

x`= thread` E `end` |  | `thread` x`=` E `end`

### Exception Handling

<statement>, <expression> ::=

`try` SE1 `catch` C1`[]` ...`[]` Cn`` [ `finally` S ]`end` |  | `try` SE1 `catch` `X` `then case` `X` `of` C1`[]` ...`[]` Cn `else raise` `X` `end end` [ `finally` S ]`end`

if C1`[]` ...`[]` Cn does not have the form x `then` SE2.

In the following rule, the intermediate variable `X` ensures that x is only bound iff evaluation of E does not raise an exception.

<statement> ::=

x`= try` E`` [ `catch` y `then` E ]`` [ `finally` S ]`end` |  | `try` `X` `in` `X``=` E`` x`=` `X``` [ `catch` y `then` x`=` E ]`` [ `finally` S ]`end`

<statement> ::=

`try` ...`finally` S `end` |  | `local` `X` `in` `X``= try try` ...`end unit catch` `Y` `then ex(``Y``) end` S `case` `X` `of ex(``Z``) then raise` `Z` `end else skip end end`

<statement> ::=

`try` SE `end` |  | SE

### Exception Raising

<statement> ::=

`raise` E `end` |  | `{`Exception.raise`` E`}`

<statement> ::=

x`= raise` E `end` |  | `raise` E `end`

### Equations

<statement> ::=

E1 = E2 |  | `local` `X` `in` `X``=` E1`` `X``=` E2 `end`

if E1 is no variable.

### Operators

<expression> ::=

o`` E |  | `{`x`` E`}`

where o {`!!`, `~`} and x = CV(o).

<expression> ::=

E1`` o`` E2 |  | `{`x`` E1`` E2`}`

where o {`.`, `^`, `*`, `/`, `div`, `mod`, `+`, `-`, `==`, `\=`, `<`, `=<`, `>`, `>=`} and x = CV(o).

CV(o) denotes the Core variable to which operation o is bound. The following table summarizes in which module from ``The Oz Base Environment'' each operator is available, e. g., `+` is available as `Number.'+'`, which means that CV(o) = ``Number.'+'``.

Operators | Located in Module
--- | ---
`!!` `.` `==` `\=` `<` `=<` `>` `>=` | `Value`
`~` `*` `+` `-` | `Number`
`div` `mod` | `Int`
`/` | `Float`
`^` | `Record`

<expression> ::=

E1 `andthen` E2 |  | `if` E1 `then` E2 `else false end`

<expression> ::=

E1 `orelse` E2 |  | `if` E1 `then true else` E2 `end`

### Records

<expression>, <pattern> ::=

`[`EP1`` ...`` EPn`]` |  | EP1`|`...`|`EPn`|nil`

<expression>, <pattern> ::=

EP1`|`EP2 |  | `'|'(`EP1`` EP2`)`

<expression>, <pattern> ::=

EP1`#`...`#`EPn |  | `'#'(`EP1`` ...`` EPn`)`

Missing: dots, omitted features

### Uniform State

<statement> ::=

x`= @`E |  | `local` `X` `in` `X``=` E`` x`= @``X` `end`

if E is no variable.

<statement> ::=

E1`.`E2`:=` E3 |  | E1`#`E2`:=` E3

<statement> ::=

x`=` E1`.`E2`:=` E3 |  | x`=` E1`#`E2`:=` E3

<statement> ::=

E1`:=` E2 |  | `local` `X` `in` `X``=` E1`` `X``:=` E2 `end`

if E1 is no variable.

<statement> ::=

x`:=` E |  | `local` `X` `in` `X``=` E`` `x``:=` `X` `end`

if E is no variable.

<statement> ::=

x`=` E1`:=` E2 |  | `local` `X` `in` `X``=` E1`` x`=` `X``:=` E2 `end`

if E1 is no variable.

<statement> ::=

x`=` y`:=` E |  | `local` `X` `in` `X``=` E`` x`=` y`:=` `X` `end`

if E is no variable.

### Wildcard

<expression> ::=

`_` |  | `local` `X` `in` `X` `end`

<pattern> ::=

`_` |  | `X`

### Named Constants

<expression>, <label>, <feature> ::=

`unit` |  | ``Unit.'unit'``

<pattern> ::=

`unit` |  | `!`Unit.'unit'``

<expression>, <label>, <feature> ::=

`true` |  | ``Bool.'true'``

<pattern> ::=

`true` |  | `!`Bool.'true'``

<expression>, <label>, <feature> ::=

`false` |  | ``Bool.'false'``

<pattern> ::=

`false` |  | `!`Bool.'false'``