http://t3x.org/t3x/uman.html

# A T3X9 Micro Manual

## Program

A program is a set of declarations followed by a compound statement. Here is the minimal T3X program:

 ```DO END ```

A comment is started with an exclamation point (!) and extends up to the end of the current line. Example:

Example: ```DO END ! Do nothing ```

## Declarations

### `CONST name = cvalue, ... ;`

Assign names to constant values.

Example: ```CONST false = 0, true = %1; ```

### ```VAR name, ... ; VAR name[cvalue], ... ; VAR name::cvalue, ... ;```

Define variables, vectors, and byte vectors, respectively. Different definitions may be mixed. Vector elements start at an index of 0.

Example: ```VAR stack[STACK_LEN], ptr; ```

### `STRUCT name = name_1, ..., name_N;`

Shorthand for

 ```CONST name_1 = 0, ..., name_N = N-1, name = N; ```

Used to impose structure on vectors and byte vectors.

Example: ```STRUCT POINT = PX, PY, PCOLOR; VAR p[POINT]; ```

### `DECL name(cvalue), ... ;`

Declare functions whose definitions follow later, where the cvalue is the number of arguments. Used to implement mutual recursion.

Example: ```DECL odd(1); even(x) RETURN x=0-> 1: odd(x-1); odd(x) RETURN x=1-> 1: even(x-1); ```

### `name(name_1, ...) statement`

Define function name with arguments name_1, ... and a statement as its body. The number of arguments must match any previous `DECL` of the same function.

The arguments of a function are only visible within the (statement) of the function.

Example: ```hello(s, x) DO VAR i; FOR (i=0, x) DO writes(s); writes("\n"); END END ```

(`Writes()` writes a string.)

## Statements

### `name := expression;`

Assign the value of an expression to a variable.

Example: ```DO VAR x; x := 123; END ```

### ```name[value]... := value; name::value := value;```

Assign the value of an expression to an element of a vector or a byte vector. Multiple subscripts may be applied to to a vector:

 ```vec[i][j]... := i*j; ```

In general, `vec[i][j]` denotes the j'th element of the i'th element of `vec`.

Note that the `::` operator is right-associative, `so v::x::i` equals `v::(x::i)`. This is particularly important when mixing subscripts, because

 ```vec[i]::j[k] := 0; ```

would assign 0 to the `j[k]`'th element of `vec[i]`. (This makes sense, because `vec[i]::j` would not deliver a valid address.)

### ```name(); name(expression_1, ...);```

Call the function with the given name, passing the values of the expressions to the function. An empty set of parentheses is used to pass zero arguments. The result of the function is discarded.

For further details see the description of function calls in the expression section.

### ```IF (condition) statement_1 IE (condition) statement_1 ELSE statement_2```

Both of these statements run statement_1, if the given condition is true.

In addition, `IE/ELSE` runs statement_2, if the conditions is false. In this case, `IF` just passes control to the subsequent statement.

Example: ```IE (0) IF (1) RETURN 1; ELSE RETURN 2; ```

The example always returns 2, because only an `IE` statement can have an `ELSE` branch. There is no "dangling else" problem.

### `WHILE (condition) statement`

Repeat the statement while the condition is true. When the condition is not true initially, never run the statement.

Example: ```! Count from 1 to 10 DO VAR i; i := 0; WHILE (i < 10) i := i+1; END ```

### ```FOR (name=expression_1, expression_2, cvalue) statement FOR (name=expression_1, expression_2) statement```

Assign the value of expression_1 to name, then compare name to expression_2. If cvalue is not negative, repeat the statement while `name < expression_2`. Otherwise repeat the statement while `name > expression_2`. After running the statement, add cvalue to name. Formally:

 ```name := expression_1; WHILE ( cvalue > 0 /\ name < expression \/ cvalue < 0 /\ name > expression ) DO statement; name := name + cvalue; END ```

When the cvalue is omitted, it defaults to 1.

Examples: ```DO VAR i; FOR (i=1, 11); ! count from 1 to 10 FOR (i=10, 0, %1); ! count from 10 to 1 END ```

### `LEAVE;`

Leave the innermost `WHILE` or `FOR` loop, passing control to the first statement following the loop.

Example: ```DO VAR i; ! Count from 1 to 50 FOR (i=1, 100) IF (i=50) LEAVE; END ```

### `LOOP;`

Re-enter the innermost `WHILE` or `FOR` loop. `WHILE` loops are re-entered at the point where the condition is tested, and `FOR` loops are re-entered at the point where the counter is incremented.

Example: ```DO VAR i; ! This program never prints X FOR (i=1, 10) DO LOOP; T.WRITE(1, "X", 1); END END ```

### `RETURN expression;`

Return a value from a function. For further details see the description of function calls in the expression section.

Example: ```inc(x) RETURN x+1; ```

### `HALT cvalue;`

Halt program and return the given exit code to the operating system.

Example: ```HALT 1; ```

### ```DO statement ... END DO declaration ... statement ... END```

Compound statement of the form `DO` ... `END` are used to place multiple statements in a context where only a single statement is expected, like selection, loop, and function bodies.

A compound statement may declare its own local variables, constant, and structures (using `VAR`, `CONST`, or `STRUCT`). A local variable of a compound statement is created and allocated at the beginning of the statement is ceases to exist at the end of the statement.

Note that the form

 ```DO declaration ... END ```

also exists, but is essentially an empty statement.

Example: ```DO var i, x; ! Compute 10 factorial x := 1; for (i=1, 10) x := x*i; END ```

### ```DO END ;```

These are both empty statements or null statements. They do not do anything when run and may be used as placeholders where a statement would be expected. They are also used to show that nothing is to be done in a specific situation, like in

 ```IE (x = 0) ; ELSE IE (x < 0) statement; ELSE statement; ```

Example: ```FOR (i=0, 100000) DO END ! waste some time ```

## Expressions

An expression is a variable or a literal or a function call or a set of operators applied to one of these. There are unary, binary, and ternary operators.

Examples: ```-a ! negate a b*c ! product of b and c x->y:z ! if x then y else z ```

In the following, the symbols X, Y, and Z denote variables or literals.

These operators exist (P denotes precedence, A associativity):

Operator P A Description
`X[Y]` 9L the Y'th element of the vector X
`X::Y` 9R the Y'th byte of the byte vector X
`-X` 8- the negative value of X
`~X` 8- the bitwise inverse of X
`\X` 8- logical NOT of X
`@X` 8- the address of X
`X*Y` 7L the product of X and Y
`Y/Y` 7L the integer quotient of X and Y
`X mod Y` 7L the division remainder of X and Y
`X+Y` 6L the sum of X and Y
`X-Y` 6L the difference between X and Y
`X&Y` 5L the bitwise AND of X and Y
`X|Y` 5L the bitwise OR of X and Y
`X^Y` 5L the bitwise XOR of X and Y
`X<<Y` 5L X shifted to the left by Y bits
`X>>Y` 5L X shifted to the right by Y bits
`X<Y` 4L %1, if X is less than Y, else 0
`X>Y` 4L %1, if X is less than Y, else 0
`X<=Y` 4L %1, if X is less/equal Y, else 0
`X>=Y` 4L %1, if X is greater/equal Y, else 0
`X=Y` 3L %1, if X equals Y, else 0
`X\=Y` 3L %1, if X does not equal Y, else 0
`X/\Y` 2L if X then Y else 0 (short-circuit AND)
`X\/Y` 1L if X then X else Y (short-circuit OR)
`X->Y:Z` 0- if X then Y else Z

Higher precedence means that an operator binds stronger, e.g. `-X::Y` actually means `-(X::Y)`.

Left-associativity (L) means that `x+y+z = (x+y)+z` and right-associativity (R) means that `x::y::z = x::(y::z)`.

## Conditions

A condition is an expression appearing in a condition context, like the condition of an `IF` or `WHILE` statement or the first operand of the `X->Y:Z` operator.

In an expression context, the value 0 is considered to be "false", and any other value is considered to be true.

Examples: ```X=X ! true 1=2 ! false "x" ! true 5>7 ! false ```

The canonical truth value, as returned by `1=1`, is `%1`.

## Function Calls

When a function call appears in an expression, the result of the function, as returned by `RETURN` is used as an operand.

A function call is performed as follows:

Each actual argument in the call

 ```function(argument_1, ...) ```

is passed to the function and bound to the corresponding formal argument ("argument") of the receiving function. The function then runs its statement, which may produce a value via `RETURN`. When no `RETURN` statement exists in the statement, 0 is returned.

Function arguments evaluate from the left to the right, so in

 ```f(a,b,c); ```

A is guaranteed to evaluate before B and C and B is guaranteed to evaluate before C.

Example: ```pow(x, y) DO VAR a; a := 1; WHILE (y) DO a := a*x; y := y-1; END RETURN a; END DO VAR x; x := pow(2,10); END ```

## Literals

### Integers

An integer is a number representing its own value. Note that negative numbers have a leading '`%`' sign rather than a '`-`' sign. While the latter also works, it is, strictly speaking, the application of the '`-`' operator to a positive number, so it may not appear in cvalue contexts.

In T3X9r2 and later releases, integers may have a '`0x`' prefix (after the '`%`' prefix, if that also exists). In this case, the subsequent digits will be interpreted as a hexa-decimal number.

Examples: ```0 12345 %1 0xfff %0xABC ```

### Characters

Characters are integers internally. They are represented by single characters enclosed in single quotes. In addition, the same escape sequences as in strings may be used.

Examples: ```'x' '\\' ''' '\e' ```

### Strings

A string is a byte vector filled with characters. Strings are delimited by '`"`' characters and NUL-terminated internally. All characters between the delimiting double quotes represent themselves. In addition, the following escape sequences may be used to include some special characters:

SequenceCharacterDescription
`\a`BELBell
`\b`BSBackspace
`\e`ESCEscape
`\f`FFForm Feed
`\n`LFLine Feed (newline)
`\q`"Quote
`\r`CRCarriage Return
`\s` Space
`\t`HTHorizontal Tabulator
`\v`VTVertical Tabulator
`\\`\Backslash

Examples: ```"" "hello, world!\n" "\qhi!\q, she said" ```

### Packed Tables

Packed tables are only included and T3X9r2 and later releases.

A packed table is a byte vector literal. It is a set of cvalues delimited by square brackets and separated by commas. Note that string notation is a short and portable, but also limited, notation for byte vectors. For instance, the byte vectors

 ```"HELLO" PACKED [ 'H', 'E', 'L', 'L', 'O', 0 ] ```

are identical. Byte vectors can contain any values in the range from 0 to 255.

Examples: ```PACKED [ 1 ] PACKED [ 1, 2, 3 ] PACKED [ 14, 'H', 'i', 15 ] ```

### Tables

A table is a vector literal, i.e. a sequence of values. It is delimited by square brackets and elements are separated by commas. Table elements can be cvalues, strings, and tables.

Examples: ```[1, 2, 3] ["5 times -7", %35] [[1,0,0],[0,1,0],[0,0,1]] ```

### Dynamic Tables

The dynamic table is a special case of the table in which one or multiple elements are computed at program run time. Dynamic table elements are enclosed in parentheses. E.g. in the table

 ```["x times 7", (x*7)] ```

the value of the second element would be computed and filled in when the table is being evaluated. Note that dynamic table elements are being replaced in situ, and remain the same only until they are replaced again.

Multiple dynamic elements may be enclosed by a single pair of parentheses. For instance, the following tables are the same:

 ```[(x), (y), (z)] [(x, y, z)] ```

## Cvalues

A cvalue (constant value) is an expression whose value is known at compile time. In full T3X, this is a large subset of full expressions, but in T3X9, it it limited to the following:

• integers
• characters
• constants

as well as (given that X and Y are one of the above):

• `X+Y`
• `X*Y`

## Naming Conventions

Symbolic names for variables, constants, structures, and functions are constructed from the following alphabet:

• the characters `a`-`z`
• the digits `0`-`9`
• the special characters '`_`' and '`.`'

The first character of a name must be non-numeric, the remaining characters may be any of the above.

Upper and lower case is not distinguished, the symbolic names

 ```FOO Foo foo ```

are all considered to be equal.

By convention,

• `CONST` names are all upper-case
• `STRUCT` names are all upper-case
• global `VAR` names are capitalized
• local `VAR` names are all lower-case
• function names are all lower-case

Keywords, like `VAR`, `IF`, `DO`, etc, are sometimes printed in upper case in documentation, but are usually in lower case in actual programs.

There is a single name space without any shadowing in T3X:

• all global names must be different
• no local name may have the same name as a global name
• all local names in the same scope must be different

The latter means that local names may be re-used in subsequent scopes, e.g.:

 ```f(x) RETURN x; g(x) RETURN x; ```

would be a valid program. However,

 ```f(x) DO VAR x; END !!! WRONG !!! ```

would not be a valid program, because `VAR x;` redefines the argument of F.

## Built-In Functions

The following library functions exist in T3X9. They resemble the functions of the T3X core module of the full language, i.e. a T3X9 program can be compiled by a T3X compiler by adding the following code to the top of the program:

 ```MODULE name(t3x); OBJECT t[t3x]. ```

These functions are built into the T3X9 compiler, though, and do not have to be declared in any way. The '`.`' in the function names resembles the message operator of the full language.

T3X9r3 accepts (and ignores) the above declarations at the beginning of a program. A program containing these declarations can be compiled by any T3X compiler.

### `T.MEMCOMP(b1, b2, len)`

Compare the first LEN bytes of the byte vectors B1 and B2. Return the difference of the first pair of mismatching bytes. A return code of 0 means that the compared regions are equal.

Example: ```t.memcomp("aaa", "aba", 3) ! gives 'b'-'a' = %1 ```

### `T.MEMCOPY(bs, bd, len)`

Copy LEN bytes from the byte vector BS (source) to the byte vector BD (destination). Return 0.

Example: ```DO VAR b:100; t.memcopy("hello", b, 5); END ```

### `T.MEMFILL(bv, b, len)`

Fill the first LEN bytes of the byte vector BV with the byte value B. Return 0.

Example: ```DO VAR b:100; t.memfill(b, 0, 100); END ```

### `T.MEMSCAN(bv, b, len)`

Locate the first occurrence of the byte value B in the first LEN bytes of the byte vector BV and return its offset in the vector. When B does not exist in the given region, return -1.

Example: ```t.memscan("aaab", 'b', 4) ! returns 3 ```

### `T.READ(fd, buf, len)`

Read up to LEN characters from the file descriptor FD into the buffer BUF. Return the number of characters actually read. Return -1 in case of an error.

Example: ```DO b::100; t.read(0, b, 99); END ```

### `T.WRITE(fd, buf, len)`

Write LEN characters from the buffer BUF to the file descriptor FD. Return the number of characters actually written. Return -1 in case of an error.

Example: ```t.write(1, "hello, world!\n", 14); ```

## Release 2 Built-Ins

The following functions are only available in T3X9 Release 2, but not in the compiler described in the book.

### `T.CREATE(path)`

Create a file with the given PATH, open it, and return its file descriptor. In case of an error, return -1.

Example: ```t.create("new-file"); ```

### `T.OPEN(path, mode)`

Open file PATH in the given MODE, where 0=read-only, 1=write-only, and 2=read/write. Return -1 in case of an error.

Example: ```t.open("existing-file", 0); ```

### `T.CLOSE(fd)`

Close the file descriptor FD. Return 0 for success and -1 in case of an error.

Example: ```DO var fd; fd := t.create("file"); if (fd >= 0) t.close(); END ```

### `T.RENAME(path, new)`

Rename the file given in PATH to NEW. Return 0 for success and -1 in case of an error.

Example: ```t.rename("old-name", "new-name"); ```

### `T.REMOVE(path)`

Remove the file given in PATH. Return 0 for success and -1 in case of an error.

Example: ```t.remove("temp-file"); ```

 ```sum(k, v) DO var i, n; n := 0; FOR (i=0, k) n := n+v[i]; RETURN n; END ```
 ```sum(5, [(a,b,c,d,e)]) ```