There are five types of token in Come Here:
"
) with any number of printable characters (other than quotation marks) between them;//
.The whitespace characters are the space, carriage return and tab characters. Whitespace is required only to separate two numbers, two identifiers or two keywords where they appear consecutively, but may be used between tokens anywhere in the code. It is never required to separate tokens of different types. Come Here is a free-form language, i.e. all whitespace characters are equivalent, and two or more consecutive whitespace characters are equivalent to a single whitespace.
A statement consists of a keyword, usually followed by one or more arguments. Multiple arguments to a statement are not delimited in any way.
A label may prefix any statement. A label is always a literal number, never a string, variable or arithmetic expression. No statement may have more than one label, and no two statements may have the same label.
statement ::= number statement-body statement ::= statement-body statement-body ::= comment statement-body ::= call-statement statement-body ::= ask-statement statement-body ::= tell-statement statement-body ::= come-from-statement comment ::= 'NOTE' token comment ::= comment token call-statement ::= 'CALL' expression variable-name ask-statement ::= 'ASK' variable-name tell-statement ::= 'TELL' expression tell-statement ::= tell-statement expression come-from-statement ::= 'COME' 'FROM' expression
Wherever a number immediately precedes a statement body, it is interpreted as part of the preceding statement if and only if it is required by that statement's syntax. Otherwise, it is a label. For example, a label can be commented out by immediately preceding it with NOTE
, but if there are other tokens between NOTE
and the number, it remains active as a label.
The syntax of expressions is defined according to this BNF:
expression ::= expression '+' term expression ::= expression '-' term expression ::= term term ::= term '*' factor term ::= term '//' factor term ::= term 'MOD' factor term ::= factor factor ::= 'SGN' factor factor ::= '(' expression ')' factor ::= number factor ::= string factor ::= variable-name
The symbols +
, -
, *
and //
and the keywords MOD
and SGN
are arithmetic operators. Their semantics are described in section 3.5.
The program counter starts at the beginning of the program, and normally advances through the code one statement at a time in the same manner as most imperative programming languages. Every statement is executed at the time that the program counter reaches it, even if the statement has no effect, in which case the execution consists of doing nothing. Immediately after a labelled statement is executed, the program counter may jump to another part of the program depending on COME FROM
statements in the program code.
As the program is running, it is necessary to monitor the values of all variable and computed arguments to COME FROM
statements in the program to ensure that they reference labels that exist in the program.
More about the COME FROM
statement is given in section 4.5.
The program halts when the last statement has just been executed, unless a COME FROM
statement causes a jump at this point.
The signed integer is the only data type in Come Here, but there is no defined limit on its size. Because of the language's syntactical limitations, only a non-negative integer can be written as a literal value in code.
A string appearing in an expression is treated as its integer representation. This representation is a sum of character values, where the nth (starting from zero) character's value is the character's code number in the implementation character set multiplied by the nth power of the character set size.
There are three predefined constants that may be used in expressions. Each of them represents the code of a specific character in the platform's character set:
QUOTE
– the double quote character (");NEXT
– the newline (line feed) control character;BLANK
– the form feed control character.A variable is identified by a name consisting of lower case letters. When the program starts all variables are unassigned. A variable holds an integer value. If a variable is used in an expression in the statement (other than a COME FROM
statement) being executed before it has been assigned a value, a run-time error occurs.
The six arithmetic operators are defined as follows:
x + y
is the sum of x
and y
;x - y
is the remnant after subtracting y
from x
;x * y
is the product of x
and y
;x // y
is the floor (rounded-down integer part) of x
divided by y
;x MOD y
is the value that is congruent to x
modulo y
, lies between 0
and y
and is not equal to y
;SGN x
is 0-1
, 0
or 1
if x
is negative, zero or positive respectively.SGN
is the only unary operator; the others are always binary operators.
The NOTE
statement takes one or more arguments, each of which is any token except for any keyword that begins a statement (NOTE
, CALL
, TELL
, ASK
, COME
). Any symbol, including one that is not defined in Come Here, is valid as an argument to NOTE
, as is any sequence of uppercase letters that is not a statement-beginning keyword. Quotation marks occurring within a NOTE
statement must still delimit correctly formed strings.
A NOTE
statement is a comment, i.e. it has no effect on the execution of the program.
The CALL
statement always takes two arguments, the first of which is any expression and the second of which is a variable name. It assigns the value of the first argument to its second.
The ASK
statement takes one argument, which is a variable name. It receives a line of text from the standard input, and assigns the numerical representation of it (excluding the terminating newline) to the named variable.
The TELL
statement takes one or more arguments. It writes to the standard output, in the order that they appear in the statement, the string represented by each of its arguments.
If the standard output is a VDU, any occurrence in the represented string of a form feed character is rendered by clearing the screen or console window.
The result of TELL
ing a negative number or a number representing a string containing an internal null character is currently undefined.
The COME FROM
statement takes an expression as its argument. It has no effect upon execution. Instead, the program counter automagically jumps to a COME FROM
statement immediately after executing the statement whose label is equal to the value of the COME FROM
statement's argument. This COME FROM
statement is then the next statement to be executed.
A COME FROM
statement whose argument contains one or more variables will have no effect unless all its variables have been assigned values.
A run-time error occurs when and if either of these happens:
COME FROM
statement references the label of the statement just executed;COME FROM
statement references a label that does not exist.An implementation may store data in any suitable manner. The integer range supported by any implementation need not be unlimited, but must be sufficient to accommodate an arbitrary string of 80 characters.
If the result of a calculation exceeds the range of the implementation's method of storing integers, a run-time error will occur.
In order to support the COME FROM
statement, it is necessary to monitor the values of arguments to all COME FROM
statements. Not all of these need to be evaluated after every statement is executed; it is sufficient to check, whenever a variable is assigned a new value, those COME FROM
statements that depend on it.
As an exception to the above, it is permissible to optimise the COME FROM
mechanism. For example, a COME FROM
argument that has a finite number of possible values may be treated as conditional jumps from the relevant statement labels. If all of the possible argument values are existent labels, it is then not necessary to constantly monitor the value of this argument.
Any implementation's optimisation of COME FROM
must not alter the behaviour of the program, including when or if a run-time error is generated because of missing or duplicate statement labels.