Language summary

This language summary is highly incomplete. Have a look at the *.am files in the example and test directories to see samples of the code that Amber can process.

Quick links

Amber script file

An Amber script file consists of:

Additionally, classes may be placed in separate files located within the library search path.

The following example has two instructions and one feature declaration:

print("The version number is ") print_line(version_number) private version_number do result := "5.3 beta" end end

The filename suffix for Amber source texts is '.am'.

Assignment Instruction

The symbol for assignment is ":=", which can be pronounced "is assigned".

To the left of the assignment symbol is a "writable", which can be an attribute of the enclosing class, or a local variable. It can also be the 'result' keyword, which indicates the result to be returned from a function.

To the right of the assignment symbol is the expression that will be assigned to the left-hand-side:

length := "some_string".count result := length + 1

Check instruction

A check instruction checks (at runtime) that an assertion holds. It comprises the 'check' keyword followed by an expression, for example:

check count > 0 and count <= limit

A check failure will be reported if the expression evaluates to 'false'.

By default, runtime monitoring of check instructions is disabled. To enable it, add the "--check" option to the amber command line.

Feature call

Feature call is denoted by a dot. To find the feature, Amber looks first in the class of the call target, then in the ancestors of that class.

As in other modern multiple-inheritance scripting languages (such as Perl 6 and Python 2.3 onwards), the C2 method resolution order is used.

Informally, this means that Amber examines the parentclasses left-to-right, depth-first, and ignores all but the last occurrence of any class that is found more than once.

If Instruction

The simplest form of "If" instruction has a test and a "then" part:

if some_boolean_valued_expression then zero_or_more_instructions end

An "else" part can also be included:

if expression then then_instructions else else_instructions end

There can be one or more "elseif" parts, and also nested "If" instructions:

if some_expression then then_instructions elseif another_expression then elseif_instructions elseif yet_another_expression then if some_other_expression then nested_then_instructions else nested_else_instructions end else yet_more_instructions end

Loop Instruction

There is only one loop construct - but it's a powerful one. A loop starts with the "loop" keyword, and ends with the "repeat" keyword. Here's an infinite loop:

loop print_line("Hello forever...") repeat

We can add an "until" clause to the top of the loop, in which case the loop body will execute zero or more times:

-- print the numbers from 1 to 5 inclusive: i := 0 loop until i = 5 i := i + 1 print_line(i) repeat

By putting the "until" clause at the end, the loop body will execute at least once:

loop do_something until some_condition_is_true repeat

It's often useful to exit from the middle of the loop body:

loop read_line until end_of_input do_something_with(last_line) repeat

An Amber loop can even have multiple exits:

print_line("Enter pairs of numbers, and I'll tell you which is greater.") loop print_line("Enter the first number...") read_line until end_of_input first := last_line print_line("Enter the second number...") until end_of_input second := last_line if first > second then print_line("The first is greater.") elseif second > first then print_line("The second is greater.") else print_line("The two numbers are equal.") end print_line("Another (y/n)?") read_line until end_of_input or last_line.item(1) /= 'y' repeat

See also Loop Invariant and Loop Variant.

Loop Invariant

A Loop Invariant is a boolean-valued expression that is evaluated each time through a loop. If the Loop Invariant evaluates to false, an exception is raised.

Syntactically, the Loop Invariant precedes the loop exit (and the Loop Invariant, if there is one).

By "and-ing" the loop exit condition with the Loop Invariant, we obtain a condition that holds true immediately upon loop exit. Here's a trivial example:

i := 0 loop invariant i >= 0 and i <= 5 until i >= 5 i := i + 1 do_something repeat -- At this point: i >= 0 and i <= 5 and i >= 5, i.e. i = 5

Loop Variant

A Loop Variant is an integer-valued expression that is evaluated each time through a loop. If the Loop Variant becomes negative, or fails to decrease from one execution of the loop body to the next, an exception is raised.

The Loop Variant is used to ensure termination of the loop - or rather, to raise an exception if termination may not occur.

Syntactically, the Loop Variant precedes the loop exit. It is executed at the position in which it appears in the code.

i := 0 loop variant 5 - i until i = 5 i := i + 1 -- If this line is omitted, the loop variant will fail print_line(i) repeat

Precondition

A precondition checks (at runtime) that a routine was called under the correct conditions. The precondition may may not reference any local variables, but may test the values of the routine arguments and of other queries.

A precondition comprises the 'require' keyword followed by zero or more expressions, for example:

factorial(n) require n >= 0 -- factorial(n) not defined for n < 0 do ... end

A precondition failure will be reported if any of the expressions evaluates to 'false'.

By default, the runtime monitoring of preconditions is disabled. To enable it, add the "--check" option to the amber command line.

Postcondition

A postcondition checks (at runtime) that a routine has met its specification. The postcondition may not reference any local variables, but may test the values of other queries.

A postcondition comprises the 'ensure' keyword followed by zero or more expressions, for example:

factorial(n) do ... ensure result > 0 end

A postcondition failure will be reported if any of the expressions evaluates to 'false'.

By default, runtime monitoring of postconditions is disabled. To enable it, add the "--check" option to the amber command line.

String constants

Simple string constants are enclosed by doublequotes, and may not contain line ending characters. Escape characters may be used within simple string constants (see Lexical Elements for details).

Multiline string constants are enclosed by three doublequotes, and may contain line ending characters. No escape codes are recognised within multiline string constants.

When the opening triple doublequotes appear at the start of a line, the following line ending is not included in the string. This enables the contents of a multiline string constant to be cut-and-pasted in a natural way.

s := "A simple string" s := "A \"simple\" string with escape codes\n" s := """Backslashes (\) and quotes (") are not escaped""" s := """ A three line string cut-and-pasted from another file. """

sh: /home/web/cgi/eiffelzone/comments.exe: No such file or directory