A programming language for 'Golfing' in an assembly-like environment.
- Spice is an interpreted assembly-like language with a handful of operators:
ADD
,SUB
,MUL
,DIV
,MOD
,PUT
,GET
,SWI
,BRK
,ALS
,OUT
,LOD
,SIN
,COS
,TAN
,POW
,REA
,CLR
,LEN
,NUL
- Spice programs are split into two sections;
declaration
andinstruction
split with an@
character. - All values are dynamically sized
double
arrays with the exception of string literals,"Some string"
, which may be used in OUT statements, but not stored - The end of instructions is denoted by a user-defined character - the first character of the program
An example program is given below:
;input;result;@
OUT "Input a number:";
REA input;
OUT "Number is" input;
MOD 10 input result;
OUT input "mod 10 is" result;
ALS OUT SAY;
SAY "Now SAY is a valid operator";
LOD .\module.spice input;
BRK 1 0 result;
Invoking a Spice program takes the following format:
spice.exe .\prog.spice outputLevel
Where spice.exe
is the interpreter, .\prog.spice
is a valid Spice source file and outputLevel is a number denoting the verbosity of the program.
Output levels are:
- PROGRAM = 0 (Least verbose, program output only)
- ERROR = 1
- DEBUG = 2
- INFO = 3 (Most verbose)
In the above program, ;
is declared as the program delimiter (note newline characters are still accepted with a non-newline separator). Following the delimiter declaration is the declaration of all variables used in the program. In a module the order of varable declaration is important, as values passed to a module may be loaded into each variable in declaration order (see LOD
).
Instructions may only be used after declaration is complete, denoted by the '@
' character.
In any case where a single value is expected but an array is passed, the value resolves to the 0th element (in both setting and getting values). Empty arrays have an implicit value of 0
. For example, ADD a b c
where a
, b
and c
are all arrays is equivalent to (not valid Spice code): ADD a[0] b[0] c[0]
.
Add, subtract, multiply, divide, modulus, power
Format:
<OP> x y z
Explanation:
The operator is applied to x
and y
and the result stored in z
. x
and y
may be value literals or variable names. z
must be a variable name.
Eg.
ADD 3 5 result
is the equivalent toresult = 3 + 5
POW 2 3 result
is the equivalent toresult = 2^3
Sin, Cos, Tan
Format:
<OP> x y
Explanation:
The operator is applied to x
and the result stored in y
. x
may be a value literal or variable name. y
must be a variable name.
Eg.
SIN 5 result
is the equivalent toresult = Sin(5)
Insert into array
Format:
PUT x y z
Explanation:
The value of z
is inserted into the array y
at position x
. x
is floored, to become the index. z
may be a value literal or a variable. A list must be initalised with a value to be able to insert into it - eg ADD 50 0 y
will add 50
at index 0
. The value of x
must not be outside the range 0 to array length - 1.
Eg.
PUT 1.2 array 6
is the equivalent toarray[1] = 6
PUT 5.7 array 10.8
is the equivalent toarray[5] = 10.8
Retrieve from array
Format:
GET x y z
Explanation:
The value at index x
of the array, y
, is stored in the variable z
. x
is floored, to become the index. The value of x
must not be outside the range 0 to array length - 1.
Eg.
GET 1.2 array var
is the equivalent tovar = array[1]
GET 5 array var
is the equivalent tovar = array[5]
Format:
SWI x y z
Explanation:
If x
is less than y
, the program counter is set to the zero-indexed operation number of z
. The operation count begins from after the '@
' program split. x
, y
and z
may all be value literals or variable names.
Eg.
SWI 1.2 5 6
results in the program jumping to line 6 as 1.2 is less than 5SWI 2 0 0
results in the program continuing as if SWI had been a NUL statement
Format:
BRK x y z
Explanation:
If x
is less than y
, the program ends. Otherwise, z
is set to the absolute difference between x
and y
. x
and y
may both be value literals or variable names, z
must be a variable name.
Eg.
BRK 1.2 5 var
results in the program terminating as 1.2 is less than 5BRK 3 1 var
results in the program continuing, with var having the value 2
Alias an operator
Format:
ALS x y
Explanation:
The OP x
(which must be a valid OP keyword, eg, ADD
, OUT
, PUT
etc) is aliased to y
.
Eg.
ALS GET RETRIEVE
results inRETRIEVE
being an alias toGET
ALS BRK END_IF_LSS_THN
results inEND_IF_LSS_THN
being an alias toBRK
Output to the console
Format:
OUT a b c d <...> x y z
Explanation:
The value literals or variable values of any following argument is printed to the console. The arguments may be a double value literal, a variable name or a "string literal"
. A string literal may span multiple lines,
Eg.
OUT var "hello" 200.2
results in the value ofvar
, the stringhello
and200.2
being printed to the console.
Invoke a Spice source file with the given argument(s)
Format:
LOD source.path arguments z
Explanation:
The 'module' in the source file at source.path
is loaded into its own context. Modules from the standard library may be accessed through std::module.spice
.
The declared values for the module are set as they are initalised to the value(s) of arguments
. To instead set the value of ony the first variable to the enitre value of arguments
the syntax ^arguments
should be used.
Modules must declare the variable return
which is passed back to the calling program and assigned to the passed variable z
. Module invocations may be nested indefinitely.
Eg. Module source (module.spice):
;input1;input2;return@
OUT input1 input2;
ADD 100 0 return;
This module is called in the following context:
...
PUT 0 array 50
PUT 1 array 100
LOD .\module.spice array result
This results in the values 50
and 100
being output to the console. result
is equal to 100
when control returns to the main program.
If instead LOD .\module.spice array result
was used, the module would have input1
initalised to [50, 100]
and would output "[50, 100] [0]
".
Read value(s) from the console
Format:
REA input
Explanation:
The program outputs a '>
' character and waits for the user to input some value(s). Values must be double literals or hex (denoted by #
eg #AA0BB9
) separated by ',
' (note the space character).
Eg.
REA value
where user enters1200
results invalue
being set to1200
REA value
where user enters#0x4007B425F202107B
results invalue
being set to2.962963
Reset a variable
Format:
CLR x
Explanation:
The value of x
is cleared. x
is set to an empty array/an implicit value of 0
.
Eg.
CLR value
-value
is equal to[]
/0
Get the length of a variable
Format:
LEN x y
Explanation:
The length of x
is stored in y
.
Eg.
LEN arr count
-count
is equal to the length of arr
A no-op
Format:
NUL a b c <...> x y z
Explanation:
A no-op, nothing happens. Any arguments are not resolved, and so it may be used as a method for adding comments. A NUL op does count towards line/op count for SWI
statements.
Eg.
NUL This is a comment 100! woo-hoo!
- Nothing happens.