Chapter 3

Basic Elements of
Telescript Syntax

The first step in learning to program in the Telescript language is to learn the basic elements of Telescript syntax: expressions, statements, and declarations. You'll see how they're combined in meaningful groups called blocks, how you can add comments throughout, and how you can use preprocessor directives.

Expressions

An expression is, simply put, an element of Telescript code that describes a value or a computation of a value. The Telescript language defines many different kinds of expressions. To get a feel for expressions, read through this list of the most common kinds of Telescript expressions, described in the chapters of this section. Each expression listed has an accompanying example. Don't worry about exact syntax for now--you'll read about it in later chapters.

895.7

is a literal expression whose value is the real number 895.7.

InventoryRecord(5, 'M')

is a constructor expression that creates a new instance of the class InventoryRecord. (The values in parentheses are initialization arguments necessary to instantiate InventoryRecord.) The expression's value is the new InventoryRecord object.

temperature = 72

is an assignment expression that assigns the integer 72 to the local variable temperature. Its value is 72, but this is a case where the resultant value isn't typically important--the assignment is the important part of the expression. (We assume in this example that temperature is a variable that can accept a value of 72. It may be an integer variable, for example.)

temperature

is an access expression whose value is the object assigned to the local variable temperature. If the variable was assigned the integer 72 as it was in the previous expression, this expression's value would be 72--the object specified by the variable.

365 + 12

is an operator expression that has the operator + to compute the sum of the two integers 365 and 12. It has the value 377, the result of the operation.

tireStore.order()

is a request expression that calls the operation order on an object named tireStore. Its value is whatever object is returned by the operation.

temperature@Integer

is an assertion expression that says to the compiler that the object specified by the variable temperature is a member of the class Integer.

There are a few other kinds of expressions that you'll read about later in this book--cascade expressions, escalation expressions, and special getter and setter expressions, for example.

Notice in the preceding examples that one or more expressions may be used within a larger expression. The operator expression 365 + 12, for example, uses the two literal expressions 365 and 12 as components along with the operator +.

When you consider expressions, it's important to note that although they usually have a value (a specified object or the result of a computation), expressions occasionally have no value at all. For example, not all operations return results, so a request expression might not return a value. The value of such an expression would be nil.

Statements

The next basic element of Telescript syntax is the statement. A statement describes an action to be taken. That action may be calling an operation, controlling the flow of program execution, assigning a value to a local variable, or any number of other actions.

Creating statements is a fundamental part of Telescript programming; we'll spend a large part of this book learning about actions that can be described within a statement. We'll also learn the Telescript keywords (listed in Appendix B) that control many of those actions. For now, we'll take a simple look at the form of a statement, and observe this basic rule of statement syntax:

Each statement must end in a semicolon.

The semicolon separates one statement from another and will do so, in fact, without a line feed between statements. If you have the evil inclination to do so, you can write a whole series of statements all in a single line of text--as long as the statements are separated by semicolons. As it turns out, putting line feeds in the text of Telescript code has no effect--other than legibility--unless it falls within a string or it's used to end a comment line (as described later in this chapter).

There is one exception to the semicolon rule: you don't need a semicolon after the final statement of a script or the final statement in a block (a sequence of statements contained within a pair of curly brackets). It does no harm to put a semicolon in either of these locations, however, and it's a good habit to put a semicolon at the end of each statement no matter where it falls.

Take a look at three typical statements in a snippet of Telescript code:

pause = timeKeeper.halt(25+waitTime);
ledger.billTime(workTime);
if pause >= 50 {dispatcher.notify();};
The first statement calls the operation halt on an object named timeKeeper. It supplies as an argument the expression 25+waitTime, which adds 25 to whatever value is stored in the variable waitTime. It then assigns the value returned by the operation to the variable pause.

The second statement simply calls the operation billTime on an object named ledger. It supplies the value stored in the variable workTime as an argument for the operation. If the operation returns a result, it's ignored here.

The third statement is a bit more complex. It tests the operator expression pause >= 50 to see if it's true. If so, it executes the statement in brackets that calls the operation notify on an object named dispatcher. If not, execution skips the statement in brackets. Notice that there are two semicolons at the end of this statement--one at the end of the nested statement (the statement in the brackets), the other at the end of the statement outside the brackets.

As you can see, each of these statements defines an action or a group of actions. Each statement ends in a semicolon. And the statements together define a set of actions and the order in which those actions are executed.

The third statement illustrates another important rule of statement syntax:

One or more statements may be nested within another statement.

If so, the nested statement (or statements) are enclosed in parentheses or brackets, as you'll read later.

Statements as Expressions and Vice Versa

Telescript syntax allows some ambiguity between statements and expressions: A statement can be used as an expression, and an expression can be used as a statement.

An Expression as a Statement

Using a single expression as a statement is simple: you add a semicolon after the expression. You saw this in the second statement example in the last section:

ledger.billTime(workTime);
This statement is simply an operation call on an object, which--as you may recall--is a request expression.

It's important to note that whenever an expression is used as a statement, any value it returns is usually discarded. In the previous example, if the billTime operation returns a value, that value is ignored and is discarded as execution passes on to the next statement.

Expressions used as statements are typically operation calls. In an operation-call statement, the action described is the method that executes when the operation is called.

Another common expression often used alone as a statement is an assignment expression. The action described is the action of assignment.

A Statement as an Expression

To use a value-producing statement as an expression, enclose the statement in parentheses. The parentheses ensure that the statement's value isn't discarded so that you can treat it as an expression.

Declarations

The third basic element of Telescript code is the declaration, something that looks like a statement and defines an action, but is a special case. A declaration creates and names a property or a variable that is local to the block in which it's created. (You'll read about blocks in just a bit.)

Take a look at some examples of declarations:

tally: Integer;
roscoe: Agent;
temperature: Real = 98.6;
In the first declaration, a variable named tally is created to refer to an instance of the class Integer. In the second declaration, a variable named roscoe is created to refer to a member of the abstract class Agent. And in the third declaration, a variable named temperature is created to refer to an instance of the class Real (which defines real numbers); the variable is then assigned a value of 98.6.

Notice that the semicolon rule of statements also applies to declarations: You must end each declaration with a semicolon unless it falls at the end of a script or a block. Notice also that each declaration starts with a string of characters--an identifier, used in later statements to refer to the variable. The identifier is followed by a colon and then a class name. The class name specifies the type of variable to be created. The third example shows an option of declaration: an assignment can be added to a declaration.

The three examples show a lexical convention of Telescript programming: Class names all start with an upper-case letter; all other names (including variables in this case) start with a lower-case letter. Note that this is strictly a programming convention--it's not enforced by the Telescript language.

You'll read about declaration syntax in detail in Chapter 6.

Blocks

A block is a sequence of statements and declarations enclosed in curly brackets ({}). A block defines a sequence of statements and declarations for execution; it also defines the duration of any variables declared within the block.

When a block is executed, each of its statements is executed in logical order, starting from the first statement in the block. Statements are executed consecutively unless a program-flow statement (such as the if statement you saw earlier) branches the execution. The block's execution ends when the last statement in the block is executed, or when execution branches to a statement outside the block as the result of a program-flow statement.

The Telescript language doesn't require (as do other languages) that all declarations must appear at the beginning of a block of statements. Declarations may be interspersed throughout statements.

Nesting

A block can contain other blocks nested within it, a common occurrence where a program-flow statement may cause execution to skip one block and jump to another block. For example, consider this block:

{
	pause = timeKeeper.halt(25+waitTime);
	ledger.billTime(workTime);
	if pause >= 50
		{
		dispatcher.notify();
		timeKeeper.overTime = true;
		}
	else
		{
		timeKeeper.overTime = false;
		};
}
The block contains two nested blocks within it. The first nested block is contained in the first half of an if/else statement (following the keyword if). That block isn't executed unless the expression pause >= 50 evaluates to true. The second nested block is contained in the second half of the if/else statement (following the keyword else). That block isn't executed unless the expression pause >= 50 evaluates to false. (Don't worry about the syntax of the program-flow if/else statement for now. It will be covered in detail in Chapter 7.)

Local Variables

Any variables declared within a block are local to that block (and any nested blocks within). This means that a local variable (and quite often the object to which it points) exists only until the block finishes execution. As a consequence, two independent (that is, unnested) blocks can use variables of the same name without any confusion. For example, two independent blocks can each have a variable named roscoe. One roscoe will have no affect on the other. You'll find more details about the scope of variables in Chapter 7.

Uses

Blocks are used in Telescript for two principal purposes: to define the methods of a class and to define options in program-flow statements.

Within a class definition you'll find a block of code for each of the class's methods. A method block starts execution when the method's operation is called. When the block finishes execution, the operation is completed.

You'll also find blocks used in program-flow statements (as you saw in the last code snippet) to define a distinct set of statements that may or may not be executed. In this role, a block provides a starting and ending point for optional execution.

You should also note that an entire script, whether it's enclosed in brackets or not, is considered a block by Telescript. Execution of the script starts at the first statement in the block and ends at the last statement. Any variables declared within the script are local only to the script.

Comments

The next component of Telescript code we look at--the comment--isn't necessary for the successful execution of a script, but it is indispensable for making code understandable to human eyes. Telescript offers two varieties of comment, one delimited by /* and */, the other delimited by // and a Line Feed (<LF>). This code example uses both varieties:

{
pause = timeKeeper.halt(25+waitTime);
ledger.billTime(workTime);
if pause >= 50
	{
	//Record the fact that the halt time was too long.
	dispatcher.notify();
	timeKeeper.overTime = true;
	}
else
	{
	/* Record the fact that the halt wasn't too long.
	   This allows the timeKeeper to tally without debit.*/
	timeKeeper.overTime = false;
	};
}
Whenever the Telescript compiler encounters the opening delimiter of a comment (a /* or a //), it ignores all the text following until after the closing delimiter of the comment (a */ or <LF> respectively). Between comment delimiters you're free to ignore all the rules of Telescript syntax to make your code legible to other programmers--and to yourself when you later confront the code you wrote in a late-night deadline blur.

Note that it's easier to use comments bounded by /* and */ if you're writing multiple lines of comments--you can put as many line feeds as you want in your comment text without adding new delimiters for each line of text. You can't, however, nest /* */ comments because the Telescript compiler thinks the first */ it encounters is the end of the outer comment. Use the // comments for nesting--for example, if you turn statements of Telescript code into comments for debugging.

Breaks and Program Tokens

Another element of Telescript syntax that promotes legible code is the break. A break is a space (the character <SPACE>), a horizontal tab (<HT>), a line feed (<LF>), or any number of these characters in any combination. Breaks in source code separate program tokens. A program token is one or more characters in source code that are interpreted by the compiler as a single programming element. An operator such as + is a token, an identifier like mangos is a token, a class name such as Agent is a token, and so on.

You can put breaks anywhere before the first token, after the last token, or between tokens to make your code more legible. The examples of code you've seen thus far have had plenty of breaks--spaces, horizontal tabs, and line feeds--to format the text of the code. Breaks are optional between most tokens. For example, the compiler reads the expression 2 + 2 to mean the same thing as the expression 2+2.

You must put a break between any two tokens that consist only of the characters in the ranges '0' through '9', 'A' through 'Z', and 'a' through 'z'. The break tells the compiler where one token ends and the next token begins. For example, consider the line

if pause >= 50
from the last example code. Every break in this line is optional except for the break between "if" and "pause".

Preprocessing Directives

Telescript source code is compatible with the C preprocessor, so you can use preprocessor directives such as #include and #define to include text in your code and to define abbreviations. If you're not familiar with C preprocessor directives, you'll find them described in any standard ANSI C text.

* * *

Now that you're familiar with the basic elements of Telescript syntax, you can concentrate on some specifics of syntax. The next chapter starts with request expressions that use an object's features.

3 - Basic Elements of Telescript Syntax
Expressions
Statements
Statements as Expressions and Vice Versa
An Expression as a Statement
A Statement as an Expression
Declarations
Blocks
Nesting
Local Variables
Uses
Comments
Breaks and Program Tokens
Preprocessing Directives

TS Ref - 26 JUN 1996

Generated with Harlequin WebMaker