Other Features - BBpezsgo/BBLang GitHub Wiki
Other Features
Some features that are exists in some languages.
Extension functions
You can define an extension function as follows:
i32 add(this i32 a, i32 b) {
return a + b;
}
If the first parameter defined with the this modifier, the function can be called like this:
i32 sum = 57.add(2);
You can also call an extension function in a normal way:
i32 sum = add(57, 2);
new statement
You can use the new keyword to initialize a value.
This is used for structs and arrays.
// Creates a new struct Point and initializes it to zeroes
Point point = new Point;
You can also use the new keyword to allocate memory on the heap:
// This will allocate a new struct Point on the heap
Point* point = new Point*;
// This will allocate an integer on the heap
i32* value = new i32*;
// This will allocate 5 bytes on the heap
u8[]* value = new u8[5]*;
delete statement
You can use the delete keyword to deallocate a value from the heap.
// Allocate an integer on the heap
i32* value = new i32*;
// Deallocate the integer from the heap
delete value;
If there is a constructor defined for the type, that will be called before deallocating the object.
Constructors
You can define a constructor for a struct like this:
struct Point
{
i32 x;
i32 y;
Point(i32 x, i32 y)
{
this.x = x;
this.y = y;
}
}
And use it like this:
Point point = new Point(37, 81);
Note that if you don't put the parentheses here, you just initialize a value without calling a constructor.
You can think of a constructor like this:
Point point = new Point; // Initializing with zeros
ctor(point, 37, 81); // Calling the corresponding constructor
You can also define multiple constructors for different kind of types:
struct Point
{
i32 x;
i32 y;
Point(i32 x, i32 y)
{
this.x = x;
this.y = y;
}
Point*(i32 x, i32 y)
{
this.x = x;
this.y = y;
}
}
And use them like this:
Point point1 = new Point(37, 81); // This is on the stack
Point* point2 = new Point*(37, 81); // This is on the heap
If there is one constructor defined, that will be used whatever type you want to allocate.
struct Point
{
i32 x;
i32 y;
Point(i32 x, i32 y)
{
this.x = x;
this.y = y;
}
}
// These two will call the same constructor
Point point1 = new Point(37, 81);
Point* point2 = new Point*(37, 81);
Destructors
You can also define a deconstructor for a struct like this:
struct List
{
i32[]* _ptr;
destructor()
{
delete this._ptr;
}
}
The destructor called before deallocating the object.
Index getters & setters
You can define a custom indexer for a struct like this:
struct List
{
i32[]* _ptr;
i32 indexer_get(i32 index)
{
return this._ptr[index];
}
void indexer_set(i32 index, i32 value)
{
this._ptr[index] = value;
}
}
And use it like this:
// This is on the stack
List list1 = new List;
list1[4] = 7;
int v = list1[4];
// This is on the heap
List* list2 = new List*;
list2[4] = 7;
int v = list2[4];