Basilisk is a C-based procedural programming language.
A basilisk program is a set of variable and function definitions.
The order of those definitions matters (a variable/function needs to be defined before it can be used).
Whitespace is ignored.
The entry point of the program is the function main()
.
Definitions are the basic building blocks of basilisk programs. Functions can be defined only in the root context of the program (i.e. not inside another function). Variables can be defined in the root context of the program - becoming global - or inside a function - becoming local.
identifier
=
expression;
The data type for all variables is a double
.
When defined inside a function, the variable is local, otherwise it is global.
A function argument is considered a local variable.
There is currently no difference between a variable definition and assignment, therefore:
- When a local variable is defined with the same identifier as a global one, it overshadows the global one for the duration of the function scope.
- When a local variable is defined with the same identifier as an already existing one, the value is overwritten.
- When a global variable is defined with the same identifier as an already existing one, the value is overwritten. Due to how global variables are initialized, the last value assigned to the global variable is used for the whole program.
identifier
(
identifier-list) {
statement-block}
The data type returned by each function, as well as of each argument, is a double.
The statements in the function's body get executed in sequence and a value is returned by the return statement.
A function with no return statement returns the value 0.0
.
A statement can be understood as a command of the program (e.g. return statement), which has no value. These statements form the bodies of functions. Every statement is ended by a semicolon.
identifier
=
expression;
The variable assignment statement is currently the same as a variable definition, with the same behaviour. The only difference is that a variable assignment statement can't be outside of a function.
expression
;
A discard statement evaluates an expression and immediately discards the resulting value. This is used to execute functions whose return value you don't care about.
return
expression;
A return statement immediately ends the execution of a function, returning the provided value.
An expression is a tree of operations that has a value. Basilisk supports expressions made up of the following operations, in order of increasing precedence:
- Precedence 0:
- Function call -
f(
expression-list)
where expression-list is a comma separated list of top-level expressions - Identifier for a variable
- Parenthesised expression -
(
expression)
where expression is a top-level expression - Double literal
- Function call -
- Precedence 1:
- Numeric negation -
-
expression-0
- Numeric negation -
- Precedence 2:
- Multiplication - expression-1
*
expression-2 - Division - expression-1
/
expression-2
- Multiplication - expression-1
- Precedence 3:
- Addition - expression-2
+
expression-3 - Subtraction - expression-2
-
expression-3
- Addition - expression-2
- Precedence 4:
- Modulo - expression-3
%
expression-4
- Modulo - expression-3
where expression-n is an expression with precedence level n or lower and all binary operators are right associative.
Note that the modulo operation (%
) results in a value with the same sign as the dividend (left-hand side).
There is a standard library of functions that are accessible from basilisk.
This function prints the argument into standard input followed by a new line.
This program is a valid basilisk program for illustration. For a full set of example programs, see contents of examples.
Source:
pi = 3.14;
get_pi() {
return pi;
}
write(x) {
println(x);
}
main() {
write(get_pi());
pi = 3.0;
write(pi);
write(1.0 + (3.0 * 4.0) % 5.0);
return 0.0;
}
Output:
3.14
3
3