Help - Language - Squeak Semi-formally - 4

Previous - Squeak Semi-formally

4. Statements

We arrive finally at the statements of Squeak, that the user needs to make Squeak do anything. I start with the very basic one:

assignment_op = ":=" | "_".

This is a binary term, used e.g.  thus: myArray := #(5 'a' #(5 'a')). This declares the variable "myArray" and assigns it the constant array "#(5 'a' #(5 'a'))" (showing a reflexive feature possible in Smalltalk that may interest logicians).

The term ":="  is the classical Smalltalk operator of assignment. In Squeak one can also write instead an underscore: "_" which is displayed as left-arrow (but at present not in all fonts of Squeak).

message_expression = unary_expression | binary_expression | keyword_expression.

These are the three basic kinds of messages described in the previous section. The basis for these expressions is

primary = variable_name | argument_name | literal | block | brace_expression | "(" expression ")".

The first three of these are names for constants in Squeak; the last three names for expressions in Squeak that Squeak can calculate a value for.

unary_object_description = primary | unary_expression.
unary_expression = unary_object_description unary_selector.

These two define the first of the three kinds of message_expression in Squeak. For the second kind there are the following definions:

binary_object_description = unary_object_description | binary_expression.
binary_expression = binary_object_description binary_selector unary_object_description.

Next, there is the last kind of message_expression, for which we need the following:

keyword_expression = binary_object_description [keyword binary_object_description]+.

At this point the three kinds of messages of Squeak are defined.

The next point is to define sequences of messages and relate them to methods. The first  is done as follows:

message_pattern = [unary_selector | binary_selector argument_name | [keyword argument_name]+.

The second thus:

method = message_pattern [temporaries] [primitive_declaration] [statements].

The extra in method compared to message_pattern consists of the wherewithall to make more complicated calculations and logical decisions, and is defined as follows, insofar as the necessary definitions have not been given yet:

primitive_declaration = "<" "primitive:" decimal_digits ">".

Squeak's Virtual Machine comes with a considerable number of basic operations implemented by primitives, all of which have a unique identifying number. (There are efforts to add names to these, so that users have a better idea what they do, but sofar this has not been done. To change primitives one has to change and recompile Squeak's Virtual Machine, and indeed manage some programming in C or C++).

To define statements we need to define the following

expression = [variable_name assignment_op]* (primary | message_expression | cascaded_message_expression)

which is the somewhat misleading term used for a single statement of Squeak. The only undefined term in it is defined thus:

cascaded_message_expression = message_expression [";" ( unary_selector | binary_selector unary_object_description | [keyword binary_object_description]+ ) ]+.

Note this is much like message_expression. The basic difference is related to the ";" which in turn is a way to return  everything calculated to the initial object named in the message_expression. (This is explained elsewhere in more detail.)

We arrive at statements, which in fact are sequences of  expression

statements = [expression "."]* ["^"] expression ["."].

The "^" is a constant of Squeak that in fact assures that Squeak returns the value it has calculated.  This is always the last statement in a block or method (but because of logical alternatives needs not be the last line in the block or method). 

Note also that expressions are separated by dots, and that it is a convention not to write a dot behind the last expression in statements.

Finally, we come to a  powerful implementation of a basic method in mathematical logic, called lambda-conversion. In Squeak this is implemented by so-called blocks, defined thus:

block = "[" [[":" argument_name]+ "|"] [temporaries] [statements] "]".

It should be noted that as of version 2.6, Squeak has block local temporaries in a somewhat limited form. Squeak does not yet handle blocks as full closures -- block arguments are actually compiled as "hidden" temporaries and block local temps have the same name scope as the method temps.

To finish this semi-formal specification of the Squeak Language, it remains to mention

comment = """ [character | """ """ | "'"]* """.

A comment may appear anywhere in Squeak code, and simply acts the same as whitespace as far as Squeak is concerned.

Previous - Squeak Semi-formally