TI Release
Release 1
Author
Kevin P. Albrecht
Date
17 May 2001
E-mail
Website
Twist is a new programming
language designed for elegance and simplicity.
It strives to become a language for easily working with strings and
files.
[see SCANNER.HH:
Scanner::SkipBlankSpaces ()]
Comments are treated as
whitespace by the Twist Interpreter's parser.
There are two types of comments: one-line and multi-line. A one-line
comment consists of the token `[[` and everything after it on the line. A multi-line comment consists of the tokens
`[` and `]` and everything between them.
If a multi-line comment is never completed, an error will occur.
Example:
var x: 0 [[ This is a one line comment!
if 1 > x
[This is a ...
multiple line comment!]
sayn [this is also a valid
comment] "x is less than 1"
end
If the implicit option (see Declaratives) is on, a variable is automatically
declared by the interpreter the first time that a value is assigned to it. However, if the explicit option is on (which
is default), then before a value can be assigned to a variable, it must be
declared with the var keyword as follows (the parts in blue are optional):
var variable_name
: expression
If the assignment expression is
omitted, the interpreter will automatically initialize variable_name with an empty string.
After the declaration of a
variable, a value can be assigned to it using the following syntax:
variable_name
: expression
All variables are stored
internally as strings. However, it is
easy to treat the variables as other data types when desired. The bool, int, rat, and str keywords return values that
fit in one of the contexts. All
operators transform the data to match the relevant context automatically.
Boolean Context
[see VALUE.HH:
Value::Bool(char*)]
[see PARSER.HH: Parser::Parse
()]
When a variable is used in the
boolean context (used with a Boolean operator), it is considered false if it
matches any of the following: "false", "0", "0.",
"0.0", "0.00", "0.000", "0.0000", or
"0.00000".
There are also two constants
set by the interpreter when the program starts that can be used for the boolean
context: 'true' and 'false'. The 'true' value is set to "1" and the
'false' value is set to "0".
The bool keyword will return either a "1" or "0".
Integer Context
Integers are whole
numbers.
The int keyword will truncate the mantissa (fractional part of a
rational number) if the value in the variable is a rational number. If the value in the variable is a
non-number, it will return “0”.
Rational Context
A rational number can be a
whole number or a number with a fractional part.
The rat keyword will return the same value that is currently in the
variable if it is a whole number. If
the value in the variable is a non-number, it will return “0”.
String Context
A string is any sequence of
characters.
The str keyword will always
return the same value that it is given.
It is included only for completeness.
There is a constant set by the interpreter when the program starts: nl. It indicates a line
break:
say “This is on one line.”
& nl & “And this is on another.”
[see COMMON.HH: Common::Common
( )]
A declarative is an optional
statement at the beginning of a program. Only one declarative is allowed per
program. The syntax of the declarative
is as follows (the parts in blue are optional):
? option option option...
Currently, there is only one
option: implicit/explicit. By default,
variables must be declared using the variable ( var ) keyword. If the 'implicit' declarative is used,
variables are automatically declared by the interpreter the first time they are
used in the program. The 'explicit' declarative is included for completeness.
An expression is made up of
variables, literals, and operators. All
expressions evaluate to a number result, a string result, or a boolean
result. The following table shows the
order of operations for all of the operators in Twist (in order from lowest to
highest):
Precedence |
Operator |
Name |
Arg(s) |
Type |
Return Type |
Example |
1 |
is |
is |
2 |
string |
boolean |
“dog”
is “dog” |
1 |
isnot |
is not |
2 |
string |
boolean |
“dog”
isnot “dug” |
1 |
@ |
character get |
2 |
str, num |
one-char string |
“dog”@1
is “d” |
1 |
= |
equal to |
2 |
number |
boolean |
1 = 1 |
1 |
<> |
not equal to |
2 |
number |
boolean |
1
<> 2 |
1 |
< |
less than |
2 |
number |
boolean |
1
< 2 |
1 |
> |
greater than |
2 |
number |
boolean |
2
> 1 |
1 |
<= |
less than or equal |
2 |
number |
boolean |
1
<= 1 |
1 |
>= |
greater than or equal |
2 |
number |
boolean |
2
>= 0 |
2 |
+ |
unary plus |
1 |
number |
number |
+1 |
2 |
- |
unary minus |
1 |
number |
number |
-10 |
2 |
+ |
plus |
2 |
number |
number |
1 + 2 |
2 |
- |
minus |
2 |
number |
number |
15 –
2 |
2 |
& |
concatenate string |
2 |
string |
string |
“I’m
” & “Bob.” |
2 |
or |
relational or |
2 |
boolean |
boolean |
true
or false |
3 |
* |
multiply |
2 |
number |
number |
2 * 2 |
3 |
/ |
divide |
2 |
number |
number |
1 / 2 |
3 |
and |
relational and |
2 |
boolean |
boolean |
true
and true |
4 |
not |
relational not |
1 |
boolean |
boolean |
not
false |
4 |
int |
int conversion |
1 |
any |
integer |
int
“1” |
4 |
rat |
rat conversion |
1 |
any |
rational |
rat
“1.2222” |
4 |
str |
str conversion |
1 |
any |
string |
str
10 |
4 |
bool |
bool conversion |
1 |
any |
boolean |
bool
0 |
4 |
( ) |
parentheses |
1 |
any |
any |
5 *
(2 + 1) |
The mrand command generates a
pseudo-random number between the given bounds.
mrand
variable, lower_bound_expression, upper_bound_expression
A line label is used to give a
name to a line so that a goto can jump to that location. Line labels look like this:
:label_name
statement
As the above indicates, a line
label may be on its own line or placed on the same line as a statement. At almost any point in a program, program
control can jump to a location using a matching goto command as follows:
goto label_name
If the same label name is
declared multiple times, the last one declared will be jumped to when goto is called. There is a
special line label, start, that if declared, will automatically be jumped to
when the program begins:
:start
The if structure will execute all the statements within only if the
boolean expression evaluates to be true:
if expression
statements…
end
The loop structure will execute all the statements within while the
boolean expression evaluates to be true:
loop expression
statements…
end
[see
TREE.HH: TreeNode::SetValue, ::SetValueD, ::SetContent]
All variables have a built-in
position pointer which can be used by the string manipulation commands to
search and modify strings. The position
of the string pointer is only reset to 0 when the szero command is used or when a string with a shorter length than the
current string is assigned to the variable.
The ‘@’ allows direct access to
a single character of a string. It can
be used to get a character out of a string or set one character in a
string. Both of these are demonstrated
here:
destination_of_character_variable = string_expression @ number_expression
string_variable @ number_expression = expression
Moves
the string pointer to the position after the next occurrence of the search
string. If the search cannot be found, auto will be set to “snext 0”.
snext
var, search_string
Put
the substring from source variable between the current position and the
position of the search string into the destination variable. Moves the string pointer to the position
before the next occurrence of the search string. If the search cannot be found, auto will be set to “sget 0”.
sget
source_var, destination_var, search_string
Moves
the string pointer to the beginning of the string.
szero
var
These
commands open a file as specified in their only argument. If the file is already open, auto will be set to “fin opened-already” or
“fout not-opened”. If there is another
error opening the file, auto will be set to
“fin 0” or “fout 0”.
fin
filename_expression
fout
filename_expression
Closes
a file opened by fin or fout.
If the file is already closed, auto will be set to “fclose closed-already”.
fclose
filename_expression
Gets the next line from the
specified file. If the end of the file
has been reached, auto is set to “fgetline eof”.
fgetline
filename_expression, variable
Output the string equivalent of
the expression to the specified file. fputn does the same, but also adds a newline character to the output.
fput filename_expression,
output_expression
Output the string equivalent of
the expression to the console. putn does the same, but also adds a newline character to the output.
put output_expression
Gets a line of input from the
console.
getline
variable
A statement is usually contained
on one line. To put more than one
statement on a line, follow the statement with a semicolon ( ; ).
A block is a simple structure
that allows variable inside of it to be invisible outside that block:
block
statements…
end
(empty body)
-------------------
Program Error Codes
-------------------
P01: Invalid command line
argument
The interpreter cannot determine the meaning of a command line
argument passed to it.
P02: Error opening file
The file specified does not exist, is write protected, or is in-
accessible in some way.
------------------
Syntax Error Codes
------------------
S01: Undefined token
The scanner encountered a token that is not defined by the
language.
S02: Undefined identifier
The program is trying to access a variable that has not been
declared.
To solve this problem, declare all variables before they are used
or
use the 'implicit' declarative in the declarative statement at the
beginning of the program.
S03: Unexpected token
The parser expected a token other than the one shown. Be sure that
the statement causing the error follows the described syntax.
S04: Unexpected end-of-file
The parser encountered the end of the file before it expected.
S05: Missing end-of-line
S06: Missing assignment
operator
S07: Missing right parenthesis
S08: Invalid expression
S09: Identifier already
declared
S10: Type is incompatible
S11: Connot assign a new value
to a constant
S12: Nesting too deep
S13: Invalid parsing point
S14: Only one declarative
sequence allowed per program
S15: Subroutine already
declared
-------------------
Runtime Error Codes
-------------------
R01: Code segment overflow
R02: Runtime error
R03: Divide by zero
R04: Runtime stack overflow
error
R05: Runtime stack empty
R06: Invalid execution point
R07: Too many gotos were
executed
R08: Invalid assignment
R09: Attempted to call
undefined routine
Programs are currently limited
to a length of about 20,000 tokens, but when programs of that length become
useful, it shouldn't be too hard to increase that size.