Skip to content

Latest commit

 

History

History
115 lines (90 loc) · 4.21 KB

Language.md

File metadata and controls

115 lines (90 loc) · 4.21 KB

Basilisk Language Description

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().

Definition

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.

Variable Definition

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.

Function Definition

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.

Statement

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.

Variable Assignment

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.

Discard Statement

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 Statement

return expression ;

A return statement immediately ends the execution of a function, returning the provided value.

Expression

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
  • Precedence 1:
    • Numeric negation - - expression-0
  • Precedence 2:
    • Multiplication - expression-1 * expression-2
    • Division - expression-1 / expression-2
  • Precedence 3:
    • Addition - expression-2 + expression-3
    • Subtraction - expression-2 - expression-3
  • Precedence 4:
    • Modulo - expression-3 % expression-4

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).

Standard Library

There is a standard library of functions that are accessible from basilisk.

Print Line - println(x)

This function prints the argument into standard input followed by a new line.

Valid Example Program

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