Repository navigation
Variables
Boink is a type safe language aiming to prevent any type mismatch. This means every variable should be declared with a valid type. If not, an error will be thrown before runtime.
All usable types:
- int
- float
- double
- bool
- string
Example
# Correct.
int a
a = 1
# Throws an error.
int a
a = 1.5
# Correct.
fn half(int whole) -> float
give whole/2
;
float x = half(1) # gives 0.5
fn half(int whole) -> double
give whole/2
;
# Throws an error.
# int and double mismatch
int x = half(1)
Just like type checking, Boink also checks for previous definitions of variables and throws errors accordingly. A variable (including functions) must be defined before reference and only once.
Global variables in Boink are readable from inner scopes but can't be changed globally. Attempt to assign or declare a variable with the same name will override the definition of the global variable.
Example
double PI = 3.1415
fn getPerimeter(double radius) -> double
# Can perfectly read global variable PI.
give PI * radius * 2
;
double perimeter = getPerimeter(2.0) # gives 12.566
int foo = 1
fn bar() -> int
foo = 2 # Override the 'foo' definition
give foo + 1
;
int result = bar() # It's 3 but 'foo' is still 1 in this scope
You can also override a global variable with a different type.
int foo = 1
fn bar() -> double
double foo = 2.0 # Override the 'foo' definition with another type
give foo + 1
;
float result = bar() # It's 3 but 'foo' is still 1 in this scope.
Same logic for overriding applies to nested functions.
fn foo() -> int
int one = 0
fn bar() -> int
int one = 1 # Override 'one' from outer scope
give one
;
give bar()
;
int result = foo() # It's 1
Note that this overriding only works for different scopes. For example:
int b = 1
# Throws an error.
int b = 2
Every variable should be declared before being referenced. Even though they is theoretically declared during runtime, semantic analyzer forces variables to be declared literally before a reference (as in line number or position) since Boink uses a top-to-down approach when reading syntax nodes.
int a = 1
fn increment() -> int
# Works.
give a + 1
;
int b = increment() # Gives 2
fn increment() -> int
# Semantic analyzer throws an error
# because 'a' is not defined before this declaration
# even though this would work in Python
give a + 1
;
int a
int b = increment()
int represents an integer number.
Literals
You can use int literals as shown below.
int literal = 1
double represents a double precision floating number.
Literals
You can use double literals as shown below.
double literal = 1.0
float represents a floating number.
Literals
You can use float literals as shown below.
float literal = 1.0f
bool represents a boolean value which is a binary true or false.
Literals
You can use bool literals as shown below.
bool literal = true
bool literal = false
string represents a series of characters, a text.
Literals
You can use string literals as shown below.
string literal = "literal"