Reference: Base
This section documents definitions found in base.orb. To use these definitions, you need to import this file.
Due to how importing works, you may place import "base.orb"; at the start of your main Orb source file and not need to import it from any other file.
Declarations use the same syntax used in the reference for Orb special forms.
if cond<bool> then<block> [rest...]
Conditionally executes one of the provided blocks of instructions based on the conditions provided.
Conditions and bodies are consecutive pairs of arguments. Optionally, the last argument may be unpaired, in which case it represents the fallback block to execute if no condition is satisfied.
Will not process all condition nodes if a previous condition has been satisfied (short-circuiting).
if cond0 {
doThing0;
} cond1 {
doThing1;
} {
fallback;
};
switch val targets body<block> [rest...]
Conditionally executes one of the provided blocks of instructions based on which target val is equal to.
Targets and bodies are consecutive pairs of arguments. Optionally, the last argument may be unpaired, in which case it represents the fallback block to execute if no target equals val.
Target nodes are raw values containing values to compare against.
Will not process target nodes if a target equal to val has already been found (short-circuiting).
switch (x)
(0 1) {
doThing0;
} (2 3 4) {
doThing1;
} {
fallback;
};
for init cond<bool> step body<block>
First, executes init. Then, repeatedly checks if cond is true and, if it is, executes instructions in body, then executes step; if cond is false, the instruction is finished.
for (sym (i 0)) (< i n) (++ i) {
doThing i;
};
while cond<bool> body<block>
Repeatedly executes instructions in body as long as cond is true.
while cond {
doThing;
};
repeat body<block>
Repeatedly executes instructions in body.
repeat {
doThing;
if cond {
break;
};
};
repeat n<integer> body<block>
Executes instructions in body the number of times given by n.
If n is negative, will result in undefined behaviour.
repeat 5 {
doThing;
};
range i<id> up<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from zero to one less than up.
If up is not positive, will result in undefined behaviour.
# 0, 1, 2, ..., 9
range i 10 {
doThing i;
};
range i<id> lo<integer> hi<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from lo to hi.
If lo is greater than hi, will result in undefined behaviour.
# 5, 6, 7, 8, 9, 10
range i 5 10 {
doThing i;
};
range i<id> lo<integer> hi<integer> delta<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from lo to hi, but increasing by delta after each iteration.
If lo is greater than hi, will result in undefined behaviour.
# 5, 8
range i 5 10 3 {
doThing i;
};
rangeRev i<id> up<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from one less than up down to zero.
If up is not positive, will result in undefined behaviour.
# 9, 8, 7, ..., 0
rangeRev i 10 {
doThing i;
};
rangeRev i<id> hi<integer> lo<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from hi down to lo.
If lo is greater than hi, will result in undefined behaviour.
# 10, 9, 8, 7, 6, 5
rangeRev i 10 5 {
doThing i;
};
rangeRev i<id> hi<integer> lo<integer> delta<integer> body<block>
Declares a symbol with the name i. Repeatedly executes instructions in body while iterating values of i from hi down to lo, but decreasing by delta after each iteration.
If lo is greater than hi, will result in undefined behaviour.
# 10, 7
rangeRev i 10 5 3 {
doThing i;
};
break
Prematurely ends a for, while, repeat, range, or rangeRev loop.
continue
Prematurely ends the current iteration of a for, while, repeat, range, or rangeRev loop.
++ val<integer>
Increases the value of val by one and returns it.
++ i;
-- val<integer>
Decreases the value of val by one and returns it.
-- i;
+= val by
-= val by
*= val by
/= val by
%= val by
>>= val by
<<= val by
&= val by
|= val by
^= val by
Assigns a new value to val based on the calculation with val and by as operands and returns val.
+= x k;
<<= n 1;
&& val0<bool> val<bool>... -> bool
Calculates the logical conjunction on arguments (AND operator), with short-circuiting.
Iteratively going through the arguments, if any are false, finishes the instruction and returns false. Otherwise, returns true.
if (&& b0 b1 b2) {
doThing;
};
|| val0<bool> val<bool>... -> bool
Calculates the logical disjunction on arguments (OR operator), with short-circuiting.
Iteratively going through the arguments, if any are true, finishes the instruction and returns true. Otherwise, returns false.
if (|| b0 b1 b2) {
doThing;
};
-> val m...
Dereferences val and performs [] on the result with m as the index. Then, repeats this for the previous result and the next argument, until all arguments have been used.
sym x:(Person *);
# = x ...;
std.println (-> x name);
alias name<id> ty<type>
Makes name refer to ty.
alias myArray (i32 4);
String
Alias for the type of string literals.
arr ty<type> val...
Constructs an array of ty. The length of the array is equal to the number of arguments in val....
Each value in val... is implicitly cast to ty and copied to the array.
sym (array (arr i32 10 11 12 13 14 15));
tup val...
Constructs a tuple with the given values as elements.
sym (tuple (tup 100.0 true));
make ty<type> pair...
Constructs a value of data type ty and assigns its elements depending on the provided pairs.
ty must be a data type. Each pair must be a raw of two elements - an element name and value.
For each pair, the element in the data type under that name will be assigned with the given value.
make Person (name 'Alice') (age 32);
lam body -> function
lam retTy body -> function
lam args retTy body -> function
Defines and returns a function.
If args is given, it will be used to define the arguments of the function. Otherwise, the function will take no arguments.
If retTy is given, it will be used to define the return type of the function. Otherwise, the function will not be a returning function.
body will be used as the body of the function.
lam { std.println; };
lam i32 { ret (* 2 (std.scanI32)); };
lam (x:i32) i32 { ret (* x x); };
pat body -> macro
pat args body -> macro
Defines and returns a macro.
If args is given, it will be used to define the arguments of the macro. Otherwise, the macro will take no arguments.
body will be used as the body of the macro.
pat { ret \(block {}); };
pat (a) { ret \(sym ,a:i32); };
enum name<id> vals
enum name<id> ty<type> vals
Defines an explicit type (an enum type) and creates values of that type.
If ty is provided it will be used as the base type. Otherwise, the base type will be i32.
vals is a list of symbols of this type to define. Each entry must be either an id or a pair of id and a value. The created symbol will use that id for its name. If the value is provided, it will be cast to ty and used to initialize that symbol.
If the value is not provided, and this is the first entry, its value will be zero. Default values of entries past the first are one more than the value of the previous entry.
Each symbol will be declared constant.
enum CoinSide {
Head
Tails
};
fnc flipCoin () CoinSide {
if (< (myRandGen) 0.5) {
ret CoinSide.Head;
};
ret CoinSide.Tails;
};
enum HttpStatus u32 {
(Ok 200)
Created
Accepted
(BadRequest 400)
Unauthorized
PaymentRequired
Forbidden
NotFound
(InternalError 500)
};
base.getEnumSize ty<type> -> unsigned
Returns the number of enum entries (initially created symbols of the ty, created by enum).
base.getEnumSize CoinSide; # 2
genId -> id
Generates and returns an id. Returns a different value on each call.
eval (sym (s:id (genId)));
cond<bool> onTrue onFalse
Conditionally processes either the onTrue or onFalse node depending on the value of cond.
cond must be an evaluated value.
cond verbose
(std.println "index=" ind " value=" ([] array ind))
(std.println ([] array ind));
cond<bool> onTrue
Only processes the onTrue node if cond is true.
cond must be an evaluated value.
cond enableDebugAsserts
(if (< ind 0) { exit 1; });
passthrough node
Returns node (ie. the node is processed).
This has a very fringe use-case which may appear when writing a macro that returns a special form that escapes one of its
idarguments.
process node
Does an extra processesing of the result of the node node.
escape node
Escapes node.
This is useful when a macro needs to return a value and tell its invoker to escape it.
unref val
Returns val as a non-ref value.
base.isOfType val ty<type> -> bool
Returns whether val is of type ty or ty cn.
val must be a typed value.
base.isRaw val -> bool
Returns whether val is of type raw or raw cn.
val must be a typed value.
base.isEmptyRaw val -> bool
Returns whether val is an empty raw value (ie. ()).
val must be a typed value.
base.assertIsOfType val ty<type>
Raises an error if val is not of type ty or ty cn.
base.makeRawWith val... -> raw
Creates a raw with arguments as its elements.
This is different from building a
rawby escaping a node, since here the arguments will not be escaped.