Simple-Script

Simple-Script is a simple expression language.  A Simple-Script program consists of a string with expressions embedded within it, enclosed in braces. The result of evaluating a Simple-Script program is the same string, but with the expressions replaced by their values (converted to strings). For example:

Program:
{a := 1 ; b := 2 }{a} plus {b} is {a+b}
Result:
1 plus 2 is 3

Programs are evaluated within the context of an initial environment, which is a mapping from variable names to data items.

Data

Data Types

Simple-Script data items have the following types:

Number
Numbers are 64 bit floating point numbers.
String
Strings are sequences of 0 or more unicode characters
Vector
Vectors are sequences of 0 or more Simple-Script data items. Note that vectors are (currently) mutable, as in Java. For example {a:= 0,..4 ; b := a ; b[0] := 99 ; a[0] } is 99! This "feature" may disappear in future versions, so don't count on it.
Trivial
There is only one item of the Trivial type, it is called the trivial object.

Conversions

Numbers can convert to strings. Vectors convert to strings by catenation of the (conversions of) their elements. The trivial object converts to the empty string.

Since there is no Boolean type, the Number type doubles as a Boolean type. Any value sufficiently close to zero (the fuzz factor is 1 millionth in the current implementation) is considered false. All other values are true.

Since there is no integer type, the Number type triples as an integer type. Where integers are needed, a double can be converted using the formula floor(x+FUZZ), where FUZZ is about 1 millionth.

White-space

Within braces, C and C++ style comments are treated as white-space, as are blanks, tabs, and newlines. Note that either kind of comment can include } characters, which, since they are commented, do not terminate the expression.

White-space serves only to separate tokens.

Expressions

The various kinds of expressions are discussed in the following sections in order of precedence, from highest to lowest, except has noted.

In the following, E, F, and G are Simple-Script expressions.

Literals

Numeric literals are sequences of 1 or more decimal digits with an optional decimal point.

String literals are enclosed in double quotes. The following escape sequences are possible:

\n ASCII char 10
\t ASCII char 9
\" Double quote

\\

Backslash
\uwxyz Unicode character. w, x, y, and z must be digits or letters from a to f. wxyz is interpreted as a hexadecimal number specifying the unicode position of the character.

Variables

Variables are written as a sequence of one or more letters, digits, and underscores, starting with a letter and ending with a letter or digit; furthermore all keywords are reserved and can not be used as variables. Variable's names are case sensitive.

Variables need not (indeed can not) be declared.

A variable used as an expression must have been assigned to a value within the current environment.

Control constructs

(E)
Parentheses are used to override or emphasize the default grouping.
if E0 then F1 elseif E1 then F2 elseif E2 then F2 else G end
If expressions provide conditional evaluation. As many elseif clauses as desired may be used. The else clause is optional. The semantics are probably what you would expect: expressions Ei are evaluated in sequence until one is found that evaluates to true, then the corresponding Fi is evaluated and its result is the if's result; if no Ei is true, then the result is G, or, in the absence of an else clause, the trivial object..
while E do F end
Again the semantics are probably what you would expect: E and then F are evaluated repeatedly until E evaluates to false. The result is the trivial object.
for v in E do F end
E must evaluate to a vector. F is evaluated once for each item in E, with variable v assigned that item. The result is a vector of results of F. For example a sum of squares of vector A can be calculated by:

sum for a in A do a*a end

Subscript

E[F]
E must evaluate to a vector and F to a number. The result is item F (considered as an integer, and counting from 0) of E.

Unary Arithmetic operations

All unary arithmetic operations have the same precedence.

sum E
E must evaluate to a vector of numbers. The result is the sum of the numbers in the vector.
count E
E must evaluate to a vector of numbers. The result is the number of  numbers in the vector that are not zero.
average E
E must evaluate to a vector of numbers. The result is the average. If the vector is of length 0, the average is 0.0.
# E
E must evaluate to a vector. The result is the length of the vector.
- E
E must evaluate to a number. The result is the negation of the number.

Binary Operators

Operands are evaluated from left to right. Both operands are evaluated. associativity is left.

E*F and E/F
E and F must evaluate to numbers. A zero divided by zero is 0.0. Otherwise dividing by a zero is not allowed.
E+F and E-F
E and F must evaluate to numbers.
E++F
The result is the catenation of E and F, converted to strings.
E,..F
E and F must evaluate to numbers. The result is a vector of integers starting with E (converted to an integer) and going up to but not including F (converted to an integer).

Relational operators

Relations are neither left nor right associative, but are chaining, meaning, for example that a _< b < c is true only if both a is less than or equal to b and b is less than c. Operands are evaluated, from left to right, only until a chain of relations is shown to be false. All relational operators share the same precedence.

Comparison of numbers obeys tricotomy: one of E<F, E=F, or E>F will be true, usually the one you expect. Numbers are considered equal if they are within a fuzz factor of each other. The fuzz factor is about 1 in a million. Equality is, thus, not transitive!

E=F and E~=F
Equal and not-equal. Numbers can be compared to numbers, strings to strings, vectors to vectors (recursively). No conversions are made. The result is 0 (false) or 1 (true).
E<F, E_<F, E>F, E>_F
Less than, less or equal, greater than, and greater or equal. E and F must evaluate to numbers. The result is 0 (false) or 1 (true).

Logical operators

~E
Same as if E then 0 else 1 end
E /\ F
Same as if E then F else 0 end
E \/ F
Same as if E then 1 else F end
E => F
Same as if E then F else 1 end

Assignment

id := F or id[E0] := F or id[E0][E1] := F etc.
Assignment to a variable that does not exist creates the variable -- so watch your spelling! Assignment to an existing vector can extend the length of the vector by up to one place. Assignment to a new vector must be to item 0. For examples: a[0][0] := 1.0 is ok, unless a has a value that is not a vector or a[0] has a value that is not a vector. a[1][0] := 1.0 is ok only if a has a value that is a vector of length 1 or more and a[1] either didn't previously exist, or was a vector. a[0][1] := 1.0 is ok only if a has a value that is a vector of at least length 1 and a[0] is a vector of at least length 1. F is evaluated first, then E0, then E1, etc. The result of an assignment is the trivial object.

Sequential composition

E F or E;F
E is evaluated, then F. The result is the result of F. The semicolon is required when F starts with a minus sign (-).