home
table of contents
Math & Computer Science
November 2001
email

Yet Another scripting language - parts 2 and 3

This page is a continuation of the discussion of "yet another scripting language", a scripting language that I am proposing to create. The ongoing presentation is broken up into sections, each section discussing some aspect of the language.

All specifications in these pages are tentative and are subject to revision.

Part 2. Arithmetic

Part 2.1 Precision of number types

RSL will support unlimited size integers (bignums) and floating point with arbitrarily large exponents and specifiable, arbitrarily large mantissa sizes. I expect to pick up an existing package.

Complex number, rational arithmetic, vectors, and matrices may or may not be included.

Part 2.2 Infix arithmetic operators

RSL will support infix notation for the standard arithmetic operators, i.e., '+', '-', '*', '/', and '^' (exponentiation).

Part 2.3 Standard math functions

RSL will provide as builtin functions the usual suite of math functions including the transcendental functions.

Part 3. Formalization of flow control constructs

This is not a full formalization of the grammar of the flow control constructs; however it is more formal that a simple natural language discussion.

3.1 Terminology

EOL             End of line - the normal statement terminator
indent          An increase of indentation level
unindent        A decrease of indentation level
INDENT          The total indentation
stmt            A statement
p-stmt          Part of the text of a statement
e-stmt          Concluding part of the text of a statment
[]              Encloses text repeat one or more times
<>              Encloses optional text

3.2 Indentation

RSL is a block structured language. Blocks are delimited both by explicit delimiters and by indentation level. The two modes of delimiting must be in agreement.

3.3 Statement format

There are three formats for statements:

(a)  INDENT stmt          EOL   // Single line statement
(b)  INDENT stmt [; stmt] EOL   // Multiple statements on a line
(c)  [ INDENT P p-stmt    EOL]  // Stmt extending across lines
       INDENT E e-stmt    EOL   // Last part of multi-line stmt
Illustrations
(a)     x = y + z
(b)     t = x ; x = y; y = t
(c)     P x = alpha
        P   + beta
        E   + gamma
Note 1: Code for statements used in illustrations is illustrative only and does not imply a commitment to any particular syntax.

Note 2: The provisions for multiple statements on a line and for statements extending across multiple lines are tentative. I may decide to drop them.

3.4 Block structure

A block body (BODY) consists a sequence of intermixed statements and blocks, all with the same indentation level. More formally;

BODY := [INDENT (stmt | BLOCK)]
Note: The formalities aren't quite consistent here but it should be clear.

A block consists of a block initiator (B-STMT), an increase in indentation level, a block body, and a block terminator (END). More formally:

BLOCK := INDENT B-STMT indent BODY END
The END may either be "unindent end" or "end unindent" depending on the style setting. There differing opinions as to whether the block terminator should be indented to the block initiator or to the block body. The majority (wrong headed in my view) indent to the block initiator; the minority (right headed but outnumbered) indent to the block body. Thus either
        while foo
           body
        end
(majority style) or
        while foo
           body
           end
(minority style). The style may be selected at the beginning of an interactive session or file and must be consistent for the remainder of the session/file.

The end statement may be blank or it may contain further text. If it does contain further text it must begin with the keyword for the block that it is paired with.

3.4.1 Optional end

In certain situations the end statement (but not the unindent) may be deleted. These occur when there is a series of co-ordinated block initiators. Thus, in illustration,

        begin
           when C1
              B1
           when C2
              B2
           end
           
        if C1
           B1
        else
           B2
        end if

3.5 Block initiator format

A block initiator consists of a flow control verb (FC-VERB) and its arguments. The flow control verbs are:

Verb Arguments Remarks
begin (none) Begins a block executed once
for var, generator The variable name assumes a sequence of values, once per iteration, as specified by the generator.
while boolean begins a block executed while the boolean expression is true
switch value Begins a switch/case structure
case val [, val]: Individual cases in a switch/case structure. See switch/case.
if boolean The block is executed if the boolean is true. It may begin a coordinated if/elif/else sequence.
elif boolean The block is executed if the boolean is true. It is an intermediate conditional in an if/elif/else sequence.
else (none) The terminal block in an if/elif/else sequence. It is executed only if all preceding conditionals are false. The else verb can also follow a sequence of when blocks. In such case it is equivalent to when true
loop (none) The block is executed indefinitely until the block is terminated from within the block.
when boolean The block is executed if the boolean expression is true. Control then transfers to the beginning of the loop or, in for begin blocks, to the termination of the block. See the section on when for details.
init (none) May occur only at the beginning of an enclosing block. There may be more than one init block. It is executed only once within a loop.

The when and init blocks may not appear in if, elif, and else block bodies at the primary level. The init block may appear in a switch block body at the primary level but not in a case block body at the primary level. The when block may not appear in either case or switch block bodies at the primary level.

3.6 Block compression

If the block body consists of a single statement the statement may follow the control verb and its arguments on the same line. In this case the END is deleted. Illustration:

        while i <= j
           k = (i+j)/2
           if (a[k] <= test) i = k+1
           else              j = k-1
           end
If, elif, else, case, and when statements may also a begin, loop, for, while, or switch block initiator on the same line. Thus:
        if foo loop
           when C1 S1
           when C2 S2
           end loop

3.7 The if/elif/else structure

The if/elif/else structure is provided primarily as a convenience for compact code. It can always be replaced by a begin/when sequence. Thus

A:      if   C1 S1
        elif C2 S2
        else    S3
can be replaced by
B:      begin
           when C1 S1
           when C2 S2
           else    S3
           end
The latter form is equivalent to the Dijkstra guarded if (without the indeterminancy) and is preferable. Note that in (B) the execution of a when clause is followed by a transfer to the end of the block.

3.8 The switch statement

The basic form of the switch statement is:

        switch value
           init code  --- optional ---
           case value-list: (block)
           case value-list: (block)
           ...
           default: (block) --- optional ---
           end switch
Note: This format has not been finalized.

3.9 The Dijkstra guarded loop

The basic form is

        loop
           when C1 S1
           ...
           end loop
The loop continues to execute as long as any the when conditionals are satisfied. It is legal to use other loop forms and to intersperse regular statements and blocks. Thus:
        for i in 0...n
           when C1
           when C2
           when C3
           end
executes until i>n or C1, C2, and C3 are all false.

3.10 Irregular loop execution

The normal mode of execution of a loop is to execute the entire body of the loop and then determine at the control point whether the loop is to be continued or terminated. Sometimes it is desirable to either (a) terminate the loop from a point inside the loop body (in C, break) or (b) prematurely return to the control point after executing only part of the loop.

For termination from within the loop body one can use the "fail if" statement. It has the following form:

        fail if boolean
If the boolean evaluates as true there is an immediate exit from the loop. The "fail if" command must be at the loop's primary level of indentation. Thus the following code is NOT legal
        while foo
           //code
           if bazfaz
              // special case code
              fail if bar
              end
           // more code
           end
The following code is legal:
        while foo
           // code
           if bazfaz
              // special case code
              bad = true
              end
           fail if bad
           // more code
           end
Note: This scheme is still under consideration

The transfer to the control point after only executing part of the loop body (in C, continue) is handled by using a "when" statement. Thus:

        for i in 0...n
           // code
           when C1
           // more code
           end
If C1 is true we go onto to the next iteration without executing the "more code" section. Again, the "when" must be at the loop body's primary level of indentation.


This page was last updated November 11, 2001.

home
table of contents
Math & Computer Science
November 2001
email