git @ Cat's Eye Technologies Strelnokoff / master doc / Strelnokoff.md
master

Tree @master (Download .tar.gz)

Strelnokoff.md @masterview markup · raw · history · blame

The Strelnokoff Programming Language

Language Version 1.1.

Overview

A Strelnokoff program consists of a list of assignments. Execution proceeds as follows. An assignment is chosen non-deterministically (which is to say, we don't know the method by which assignments are chosen; there might be a pattern or it might be totally random), the expression on the right-hand side of the assignment is evaluated to obtain a value, and the variable named on the left-hand side of the assignment is updated with that value. This process repeats until conditions are such that execution terminates.

Syntax

Strelnokoff = {Assignment}.
Assignment  = Variable "=" Expression0.
Expression0 = Expression1 {"=" Expression1 | ">" Expression1}.
Expression1 = Expression2 {"+" Expression2 | "-" Expression2}.
Expression2 = Expression3 {"*" Expression3 | "/" Expression3}.
Expression3 = ["PRINT"] ["CHAR"] Primitive.
Primitive   = Variable
            | IntegerLiteral
            | CharLiteral
            | "(" Expression0 ")".

Runtime Model

Expressions may evaluate to integers. Updatable variables may contain integers. No bound is imposed by the language definition on the magnitude of these integers. They may even be negative.

Note: Any concrete implementation of Strelnokoff will have limits, so if an implementation cannot handle integers beyond a certain magnitude, that should not by itself be considered a violation of this specification. The reference implementation supports arbitrary precision arithmetic (so-called "bigints") an an option which may be selected by use of a command-line flag.

Expression Evaluation

Expressions in Strelnokoff look like the usual arithmetic expressions: they consist of the usual binary operators with the usual precedence and the usual rule that parenthesized sub- expressions have higher precedence. Hence, expression evaluation happens, for the most part, in the conventional way. However, there are some additional considerations:

  • Boolean expressions (=, >) evaluate to 1 if true and 0 if false.
  • Evaluating an expression may have side-effects. For this reason, we define evaluation of arguments of operators to occur in the left-to-right order.
  • Multiplication is short-circuiting: if the left-hand side evaluates to 0, the result is 0 and the right-hand side will not be evaluated.
  • If an attempt is made to divide by 0, the result is 0.
  • Division is integer division; it rounds towards negative infinity.

There are two modifiers that may precede any (sub-)expression: PRINT and CHAR. These are, in essence, unary prefix operators (or perhaps two parts of the same unary prefix operator). Evaluating a PRINT expression will output the value of the expression, as a decimal number, to the standard output stream after that value has been computed. The PRINT expression itself will also evaluate to that value.

If CHAR is included in the expression, i.e. PRINT CHAR, an ASCII or character will be output instead. If the value of the expression is outside of the ASCII range, the behaviour is undefined. The grammar allows CHAR is to be present before a (sub-)expression without PRINT; in this case the behaviour is undefined.

Termination

If the program enters a state such that none of the assignments in the program would change the state of the program, the program is considered to have terminated.

Note: The implementations of Strelnokoff included in this distribution do not currently implement this check. This should be regarded as a technical shortcoming only, and not reflective of the definition of the language. There is a plan in place that a future version of the reference implementation will implement this check.

Historical Notes

In version 1.0, there were no conditions defined under which the execution of a Strelnokoff program would terminate. In version 1.1 this is defined.

In version 1.0, a description of the syntax was written in the comments of the Perl implementation, but it did not match the implementation. The syntax suggested that PRINT could contain only a variable reference, when the implementation allowed it to in fact contain any sub-expression. In version 1.1, PRINT has been turned into an operator, effectively adopting the latter behaviour.

The EBNF grammar of version 1.0 also suggested that some variables could be arrays that could be indexed, but this was never implemented and it was unclear how it was intended to combine with scalar variables as well. Here we make it explicit that there are no arrays in version 1.1. In addition, the grammar for version 1.0 suggested that the language supported input with an INPUT expression. There is no INPUT form in version 1.1.