Libraries
This is a list of Nelua standard libraries.
To use a library, use require 'libraryname'
.
builtins
The following are builtin functions defined in the Nelua compiler.
Thus this is not really a library and shouldn’t be used with require
.
require
global function require(modname: string <comptime>)
Loads the given module modname
.
The function starts by looking into loaded modules to determine whether modname
is already loaded.
If it is then require does nothing, otherwise it tries to load the module.
If there is any error loading the module, then the compilation fails. If there is any error running the module, then the application terminates.
global function print(...: varargs): void
Receives any number of arguments and prints their values to the standard output,
converting each argument to a string following the same rules of tostring
.
The values are separated by tabs and a new line is always appended.
The function print
is not intended for formatted output,
but only as a quick way to show a value, for instance for debugging.
For complete control over the output, use io.write
or io.writef
.
panic
global function panic(message: string): void
Terminate the application abnormally with message message
.
This function never returns.
Use to raise unrecoverable errors.
error
global function error(msg: string): void
Raises an error with message message
.
This function never returns.
Currently this is an alias to panic
and terminates the application,
but in the future, in case the language get an exception system,
it may be changed to an exception being thrown.
Remarks: Error messages are dependent on the host environment the program is being compiled in,
it may include terminal color codes and path to host machine files to make debugging error locations easier.
You can disable this behavior by enabling the pragma noerrorloc
,
it will make the program error messages reproducible when building across different host machines.
assert
global function assert(v: auto, message: facultative(string))
Raises an error if the value v
is evaluated to false
, otherwise, returns v
.
In case of error, message
is the error message, when absent defaults to "assertion failed!"
.
Remarks: Error messages are dependent on the host environment the program is being compiled in,
it may include terminal color codes and path to host machine files to make debugging error locations easier.
You can disable this behavior by using the pragma noerrorloc
,
it will make the program error messages reproducible when building across different host machines.
check
global function check(cond: boolean, message: facultative(string)): void
If cond
is true it does nothing, otherwise raises an error with message
and terminates the application.
Similar to assert
however it’s completely omitted when compiling in release mode or with pragma nochecks
.
Use for assertive programming, to check if conditions are met without impacting performance of production code.
Remarks: Error messages are dependent on the host environment the program is being compiled in,
it may include terminal color codes and path to host machine files to make debugging error locations easier.
You can disable this behavior by using the pragma noerrorloc
,
it will make the program error messages reproducible when building across different host machines.
likely
global function likely(cond: boolean): boolean
Returns cond
. This is a branching prediction utility, expecting cond
to evaluate to true
.
unlikely
global function unlikely(cond: boolean): boolean
Returns cond
. This is a branching prediction utility, expecting cond
to evaluate to false
.
_VERSION
global _VERSION: string
A string containing the running Nelua version, such as "Nelua 0.2-dev"
.
arg
The arguments library provides the global sequence arg
,
which is filled with command line arguments on initialization.
arg
global arg: sequence(string, GeneralAllocator)
Sequence of command line arguments.
The value at index 0
is usually filled with the program executable name.
The values starting from index 1
up to #arg
contains each command line argument.
iterators
The iterators library provides iterators functions such as
ipairs
, pairs
and next
to assist iterating over elements of a container.
The functions provided here can be used with the for in
construction.
Most containers in the standard library already requires this library.
ipairs
global function ipairs(a: container_reference_concept): (auto, auto, integer)
Returns values so that the construction
for i,v in ipairs(a) do body end
will iterate over the index–value pairs of a
from its first element up to the last.
Where i
is an integer determining the index of the element, and v
its respective value.
The container a
must be contiguous, such as array
, span
, vector
or sequence
.
mipairs
global function mipairs(a: container_reference_concept): (auto, auto, integer)
Like ipairs
but yields reference to elements values so that you can modify them in-place.
next
global function next(a: container_reference_concept, k: auto): (auto, auto, auto)
Gets the next element after key k
for the container a
.
In case of success returns true
plus the next element key and the next element value.
Otherwise returns false
plus a zeroed key and value.
The container a
must either have the metamethod __next
or be a contiguous.
mnext
global function mnext(a: container_reference_concept, k: auto): (auto, auto, auto)
Like next
but returns reference to the next element value, so that you can modify it in-place.
pairs
global function pairs(a: container_reference_concept): (auto, auto, auto)
Returns values so that the construction
for k,v in pairs(a) do body end
will iterate over all the key–value pairs of a
.
Where k
is a key determining the location of the element, and v
its respective value.
The container a
must either have the metamethod __pairs
or be a contiguous.
Should work on any container, such as array
, span
, vector
, sequence
or hashmap
.
mpairs
global function mpairs(a: container_reference_concept): (auto, auto, auto)
Like pairs
but yields reference to elements values so that you can modify them in-place.
select
global function select(index: auto <comptime>, ...: varargs)
If index
is a number, returns all arguments after argument number index;
a negative number indexes from the end (-1
is the last argument).
Otherwise, index
must be the string ‘#’,
and select returns the total number of extra arguments it received.
io
The input and output library provides functions to manipulate files.
The library provides two different styles for file manipulation.
The first one uses implicit file handles,
that is, there are operations to set a default input file and a default output file,
and all input/output operations are done over these default files.
The second style uses explicit file handles.
When using implicit file handles, all operations are supplied by module io
.
When using explicit file handles,
the operation io.open
returns a file handle and
then all operations are supplied as methods of the file handle.
The io module also provides three predefined file handles with their usual meanings from C:
io.stdin
: default input file handleio.stdout
: default output file handleio.stderr
: default error output file handle
The I/O library never closes these files.
Unless otherwise stated, all I/O functions return a valid value on success, otherwise an error message as a second result and a system-dependent error code as a third result.
io
global io: type = @record{}
Namespace for I/O module.
io.stderr
global io.stderr: filestream
Default error output file handle.
io.stdout
global io.stdout: filestream
Default output file handle.
io.stdin
global io.stdin: filestream
Default input file handle.
io.open
function io.open(filename: string, mode: facultative(string)) : (filestream, string, integer)
Opens a file, in the mode specified in the string mode
.
In case of success, it returns an open file.
Equivalent to filestream:open(filename, mode)
.
io.popen
function io.popen(prog: string, mode: facultative(string)) : (filestream, string, integer)
Starts the program prog
in a separated process and
returns a file handle that you can use to read data from this program
(if mode
is “r”, the default) or to write data to this program (if mode
is “w”).
This function is system dependent and is not available on all platforms.
io.close
function io.close(file: facultative(filestream)): (boolean, string, integer)
Closes a file.
Without a file
, closes the default output file.
Equivalent to file:close()
.
io.flush
function io.flush(): (boolean, string, integer)
Save any written data to the default output file.
Equivalent to io.output():flush()
.
io.input
function io.input(file: overload(string,filestream,niltype)): filestream
When called with a file name, it opens the named file
(in text mode), and sets its handle as the default input file.
When called with a file handle, it simply sets this file handle as the default input file.
When called without arguments, it returns the current default input file.
In case of errors this function raises the error, instead of returning an error code.
io.output
function io.output(file: overload(string,filestream,niltype)): filestream
Similar to io.input
, but operates over the default output file.
io.tmpfile
function io.tmpfile(): (filestream, string, integer)
In case of success, returns an open handle for a temporary file. This file is opened in update mode and it is automatically removed when the program ends.
io.read
function io.read(fmt: overload(integer,string,niltype)): (string, string, integer)
Read from default input, according to the given format.
Equivalent to io.input():read(fmt)
.
io.write
function io.write(...: varargs): (boolean, string, integer)
Writes the value of each of its arguments to the standard output.
The arguments must be strings or numbers.
In case of success, this function returns true
.
Equivalent to io.output():write(...)
.
io.writef
function io.writef(fmt: string, ...: varargs): (boolean, string, integer)
Writes formatted values to the standard output, according to the given format.
In case of success, this function returns true
.
Equivalent to io.output():writef(fmt, ...)
.
io.printf
function io.printf(...: varargs): void
Like io.writef
but also flushes the standard output.
io.print
function io.print(...: varargs): void
Like print
, but writes to io.stdout
using io.write
.
io.type
function io.type(obj: auto): auto
Checks whether obj
is a valid file handle.
Returns the string "file"
if obj
is an open file handle,
"closed file"
if obj
is a closed file handle,
or nil
if obj
is not a file handle.
io.lines
function io.lines(filename: facultative(string), fmt: overload(integer,string,niltype))
Opens the given file name in read mode
and returns an iterator function that works like file:lines(...)
over the opened file.
The call io.lines()
(with no file name) is equivalent to io.input():lines("l")
,
that is, it iterates over the lines of the default input file.
It currently never closes the file when the iteration finishes. In case of errors opening the file, this function raises the error, instead of returning an error code.
filestream
The file stream library provides the filestream
record,
mostly used by the io
library to manage file handles,
but can also be used independently.
filestream
global filestream: type = @record{
fs: *FStream
}
File stream record, used to store file handles.
filestream._fromfp
function filestream._fromfp(fp: *FILE, closef: function(fp: *FILE): cint): filestream
Initialize a new filestream
from a given C FILE
pointer.
closef
is a callback to call when closing the file handle.
This function is used internally.
filestream:_getfp
function filestream:_getfp(): *FILE
Returns a C FILE
pointer for the filestream.
In case the file is closed, returns nilptr
.
This function is used internally.
filestream.open
function filestream.open(filename: string, mode: facultative(string)) : (filestream, string, integer)
Opens a file, in the mode specified in the string mode
.
In case of success, it returns an open file.
Otherwise, returns a closed file handle, plus an error message and a system-dependent error code.
The mode string can be any of the following:
"r"
: read mode (the default);"w"
: write mode;"a"
: append mode;"r+"
: update mode, all previous data is preserved;"w+"
: update mode, all previous data is erased;"a+"
: append update mode, previous data is preserved, writing is only allowed at the end of file.
The mode string can also have a ‘b’ at the end, which is needed in some systems to open the file in binary mode.
filestream:flush
function filestream:flush(): (boolean, string, integer)
Saves any written data to file.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
filestream:close
function filestream:close(): (boolean, string, integer)
Closes the file.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
filestream:destroy
function filestream:destroy(): void
Destroys a file stream freeing its memory. If the file still open, it’s silently closed.
This function is only needed to be called when not using the GC.
filestream:__close
function filestream:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
filestream:seek
function filestream:seek(whence: facultative(string), offset: facultative(integer)): (integer, string, integer)
Sets and gets the file position, measured from the beginning of the file,
to the position given by offset
plus a base specified by the string whence
, as follows:
"set"
: base is position 0 (beginning of the file)"cur"
: base is current position"end"
: base is end of file
In case of success, returns the final file position, measured in bytes from the beginning of the file.
If seek fails, it returns -1
, plus an error message and a system-dependent error code.
The default value for whence is "cur"
, and for offset is 0
.
Therefore, the call filestream:seek()
returns the current file position, without changing it.
The call filestream:seek("set")
sets the position to the beginning of the file (and returns 0
).
The call filestream:seek("end")
sets the position to the end of the file, and returns its size.
filestream:setvbuf
function filestream:setvbuf(mode: string, size: facultative(integer)): (boolean, string, integer)
Sets the buffering mode for a file. There are three available modes:
"no"
: no buffering."full"
: full buffering."line"
: line buffering.
For the last two cases, size is a hint for the size of the buffer, in bytes. The default is an appropriate size.
The specific behavior of each mode is non portable,
check the underlying ISO C function setvbuf
in your platform for more details.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
filestream:read
function filestream:read(fmt: overload(integer,string,niltype)): (string, string, integer)
Reads the file file, according to the given formats, which specify what to read.
The function returns a string with the characters read. Otherwise, if it cannot read data with the specified format, it returns an empty string plus an error message and a system-dependent error code.
The available formats are:
"a"
: reads the whole file, starting at the current position. On end of file, it returns the empty string, this format never fails."l"
: reads the next line skipping the end of line, returning fail on end of file."L"
: reads the next line keeping the end-of-line character (if present), returning fail on end of file.integer
: reads a string with up to this number of bytes, returning fail on end of file. If number is zero, it reads nothing and returns an empty string, or fail on end of file.
The formats "l"
and "L"
should be used only for text files.
When called without arguments, it uses the default format "l"
that reads the next line.
filestream:write
function filestream:write(...: varargs): (boolean, string, integer)
Writes values to the file. The arguments must be strings or convertible to string.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
filestream:writef
function filestream:writef(fmt: string, ...: varargs): (boolean, string, integer)
Writes formatted values to the file, according to the given format.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
filestream:printf
function filestream:printf(...: varargs): void
Like filestream:writef
but also flushes the standard output.
filestream:print
function filestream:print(...: varargs): void
Like print
, but writes to a filestream.
filestream:lines
function filestream:lines(fmt: overload(integer,string,niltype)): (auto, auto, string)
Returns an iterator function that, each time it is called, reads the file according to the given format.
When no format is given, uses "l"
as a default. As an example, the construction
for c in filestream:lines(1) do body end
will iterate over all characters of the file, starting at the current position.
filestream:isopen
function filestream:isopen(): boolean
Checks whether the file is open.
filestream:__tostring
function filestream:__tostring(): string
Convert the file handle to a string.
Returns "filed (closed)"
for invalid or closed files,
and "file (some address)"
for open files.
This metamethod is used by tostring
.
math
The math library provides basic mathematical functions.
math
global math: type = @record{}
Namespace for math module.
math.abs
function math.abs(x: an_scalar): auto
Returns the absolute value of x
, that is, the maximum value between x
and -x
.
The argument type is always preserved.
math.floor
function math.floor(x: an_scalar): auto
Returns the largest integral value less than or equal to x
.
math.ifloor
function math.ifloor(x: an_scalar): integer
Like math.floor
, but the result is always converted to an integer.
math.ceil
function math.ceil(x: an_scalar): auto
Returns the smallest integral value greater than or equal to x
.
math.iceil
function math.iceil(x: an_scalar): integer
Like math.ceil
, but the result is always converted to an integer.
math.round
function math.round(x: an_scalar): auto
Returns the rounded value of x
towards the nearest integer.
Halfway cases are rounded away from zero.
math.iround
function math.iround(x: an_scalar): integer
Like math.round
, but the result is always converted to an integer.
math.trunc
function math.trunc(x: an_scalar): auto
Returns the rounded value of x
towards zero.
math.itrunc
function math.itrunc(x: an_scalar): integer
Like math.trunc
, but the result is always converted to an integer.
math.sqrt
function math.sqrt(x: an_scalar): auto
Returns the square root of x
.
You can also use the expression x^0.5
to compute this value.
math.cbrt
function math.cbrt(x: an_scalar): auto
Returns the cubic root of x
.
You can also use the expression x^(1/3)
to compute this value.
math.exp
function math.exp(x: an_scalar): auto
Returns the value of e^x
(where e
is the base of natural logarithms).
math.exp2
function math.exp2(x: an_scalar): auto
Returns the value of 2^x
.
You can also use the expression 2^x
to compute this value.
math.pow
function math.pow(x: an_scalar, y: an_scalar): auto
Returns x^y
.
You can also use the expression x^y
to compute this value.
math.log
function math.log(x: an_scalar, base: an_optional_scalar): auto
Returns the logarithm of x
in the given base
.
The default for base
is e, so that the function returns the natural logarithm of x
.
math.cos
function math.cos(x: an_scalar): auto
Returns the cosine of x
(assumed to be in radians).
math.sin
function math.sin(x: an_scalar): auto
Returns the sine of x
(assumed to be in radians).
math.tan
function math.tan(x: an_scalar): auto
Returns the tangent of x
(assumed to be in radians).
math.acos
function math.acos(x: an_scalar): auto
Returns the arc cosine of x
(in radians).
math.asin
function math.asin(x: an_scalar): auto
Returns the arc sine of x
(in radians).
math.atan
function math.atan(y: an_scalar, x: an_optional_scalar): auto
Returns the arc tangent of y/x
(in radians),
but uses the signs of both arguments to find the quadrant of the result.
It also handles correctly the case of x
being zero.
The default value for x
is 1
, so that the call math.atan(y)
returns the arc tangent of y
.
math.atan2
function math.atan2(y: an_scalar, x: an_optional_scalar): auto
Returns the arc tangent of y/x
(in radians),
but uses the signs of both arguments to find the quadrant of the result.
It also handles correctly the case of x
being zero.
math.cosh
function math.cosh(x: an_scalar): auto
Returns the hyperbolic cosine of x
.
math.sinh
function math.sinh(x: an_scalar): auto
Returns the hyperbolic sine of x
.
math.tanh
function math.tanh(x: an_scalar): auto
Returns the hyperbolic tangent of x
.
math.log10
function math.log10(x: an_scalar): auto
Returns the base-10 logarithm of x
.
math.log2
function math.log2(x: an_scalar): auto
Returns the base-2 logarithm of x
.
math.acosh
function math.acosh(x: an_scalar): auto
Returns the inverse hyperbolic cosine of x
.
math.asinh
function math.asinh(x: an_scalar): auto
Returns the inverse hyperbolic sine of x
.
math.atanh
function math.atanh(x: an_scalar): auto
Returns the inverse hyperbolic tangent of x
.
math.deg
function math.deg(x: an_scalar): auto
Converts the angle x
from radians to degrees.
math.rad
function math.rad(x: an_scalar): auto
Converts the angle x
from degrees to radians.
math.sign
function math.sign(x: an_scalar): auto
Returns the sign of x
, that is:
-1
ifx < 0
0
ifx == 0
1
ifx > 0
math.fract
function math.fract(x: an_scalar): auto
Returns the fractional part of x
.
Computed as x - math.floor(x)
.
math.mod
function math.mod(x: an_scalar, y: an_scalar): auto
Returns the modulo operation of x
by y
, rounded towards minus infinity.
This is equivalent to x % y
, but faster and subject to rounding errors.
It’s computed as x - math.floor(x / y) * y
.
math.modf
function math.modf(x: an_scalar): (auto, auto)
Returns the integral part of x
and the fractional part of x
.
Its second result is always a float.
math.fmod
function math.fmod(x: an_scalar, y: an_scalar): auto
Returns the remainder of the division of x
by y
that rounds the quotient towards zero.
The result can either be an integer or a float depending on the arguments.
math.frexp
function math.frexp(x: an_scalar): (auto, int32)
Returns m
and e
such that x = m*(2^e)
,
e
is an integer and the absolute value of m
is in the range [0.5, 1) or zero (when x
is zero).
math.ldexp
function math.ldexp(m: an_scalar, e: int32): auto
Returns m*(2^e)
, that is, m
multiplied by an integral power of 2.
math.min
function math.min(...: varargs): auto
Returns the argument with the minimum value, according to the operator <
.
math.max
function math.max(...: varargs): auto
Returns the argument with the maximum value, according to the operator <
.
math.clamp
function math.clamp(x: an_scalar, min: an_scalar, max: an_scalar): auto
Returns the value of x
clamped between min
and max
.
math.ult
function math.ult(m: an_scalar, n: an_scalar): boolean
Returns a boolean, true
if and only if integer m
is below integer n
when they are compared as unsigned integers.
math.tointeger
function math.tointeger(x: an_scalar): auto
If the value x
is convertible to an integer, returns that integer. Otherwise, returns nil
.
math.type
function math.type(x: auto): auto
Returns "integer"
if x
is an integer, “float” if x
is a float, or fail if x
is not a number.
math.randomseed
function math.randomseed(x: an_optional_integral, y: an_optional_integral): (integer, integer)
When called with at least one argument,
the integer parameters x
and y
are joined into a 128-bit seed that is used
to reinitialize the pseudo-random generator.
Equal seeds produce equal sequences of numbers. The default for y
is zero.
When called with no arguments, generates a seed with a weak attempt for randomness.
This function returns the two seed components that were effectively used, so that setting them again repeats the sequence.
To ensure a required level of randomness to the initial state
(or contrarily, to have a deterministic sequence, for instance when debugging a program),
you should call math.randomseed
with explicit arguments.
math.random
function math.random(m: an_optional_scalar, n: an_optional_scalar): auto
When called without arguments, returns a pseudo-random float with uniform distribution in the range [0
,1
).
When called with two integers m
and n
, returns a pseudo-random integer with uniform distribution in the range [m
, n
].
The call math.random(n)
, for a positive n
, is equivalent to math.random(1,n)
.
The call math.random(0)
produces an integer with all bits (pseudo)random.
This function uses an algorithm based on xoshiro256 to produce pseudo-random 64-bit integers, which are the results of calls with argument 0. Other results (ranges and floats) are unbiased extracted from these integers.
Its pseudo-random generator is initialized with the equivalent of a call to math.randomseed
with no arguments,
so that math.random
should generate different sequences of results each time the program runs.
math.isnan
function math.isnan(x: an_scalar): boolean
Returns true if value x
is a NaN (not a number) floating point number.
math.isinf
function math.isinf(x: an_scalar): boolean
Returns true if value x
is an infinite floating point number.
math.isfinite
function math.isfinite(x: an_scalar): boolean
Returns true if value x
is a finite floating point number (neither NaN or Inf).
math.pi
global math.pi: number
Float value of PI.
math.huge
global math.huge: number
Float value greater than any other numeric value (infinite).
math.mininteger
global math.mininteger: integer
An integer with the minimum value for an integer.
math.maxinteger
global math.maxinteger: integer
An integer with the maximum value for an integer.
math.maxuinteger
global math.maxuinteger: uinteger
An integer with the maximum value for an unsigned integer.
memory
The memory library provides low level memory management utilities.
The user is responsible to use valid pointers and memory regions for the library functions,
otherwise the user may experience crashes or undefined behaviors at runtime.
To assist finding such mistakes some checks are performed where applicable, which can
be disabled with the pragma nochecks
.
memory
global memory: type = @record{}
Namespace for memory module.
memory.copy
function memory.copy(dest: pointer, src: pointer, n: usize): void
Copies n
bytes from memory pointed by src
into memory pointed by dest
.
If n
is zero, then nothing is done.
The memory region may not overlap, use memory.move
in that case.
memory.move
function memory.move(dest: pointer, src: pointer, n: usize): void
Copies n
bytes from memory pointed by src
into memory pointed by dest
.
The memory region may overlap.
If n
is zero, then nothing is done.
If the memory region is guaranteed to not overlap, then you could use memory.copy
.
memory.set
function memory.set(dest: pointer, x: byte, n: usize): void
Fills first n
bytes of the memory pointed by dest
with the byte x
.
If n
is zero, then nothing is done.
memory.zero
function memory.zero(dest: pointer, n: usize): void
Fills first n
bytes of the memory pointed by dest
with zeros.
If n
is zero, then nothing is done.
memory.compare
function memory.compare(a: pointer, b: pointer, n: usize): int32
Compares the first n
bytes of the memory areas pointed by a
and b
.
Returns an integer less than, equal to, or greater than zero if the first n
bytes
of a
is found, respectively, to be less than, to match, or be greater than the first n
bytes of b
.
The sign is determined by the sign of the difference between the first pair of bytes that differ in a
and b
.
If n
is zero, the return value is zero.
memory.equals
function memory.equals(a: pointer, b: pointer, n: usize): boolean
Check if the first n
bytes of the memory areas pointed by a
and b
are equal.
Returns true
if the first n
bytes of a
is equal to the first n
bytes of `b.
If n
is zero, the return value is true
.
memory.scan
function memory.scan(src: pointer, x: byte, n: usize): pointer
Scan first n
bytes from memory pointed by src
for the first instance of byte x
.
Returns a pointer to the matching byte when found, otherwise nilptr
.
If n
is zero, the return value is nilptr
.
memory.find
function memory.find(haystack: pointer, haystacksize: usize, needle: pointer, needlesize: usize): pointer
Scan first haystacksize
bytes from memory pointed by haystack
for the first instance of
the chunk of memory in the region determined by needle
and needlesize
.
Returns a pointer to the matching chunk when found, otherwise nilptr
.
memory.spancopy
function memory.spancopy(dest: an_span, src: an_span): void
Like memory.copy
but operate over spans.
memory.spanmove
function memory.spanmove(dest: an_span, src: an_span): void
Like memory.move
but operate over spans.
memory.spanset
function memory.spanset(dest: an_span, x: auto): void
Like memory.set
but operate over spans.
memory.spanzero
function memory.spanzero(dest: an_span): void
Like memory.zero
but operate over spans.
memory.spancompare
function memory.spancompare(a: an_span, b: an_span): int32
Like memory.compare
but operate over spans.
memory.spanequals
function memory.spanequals(a: an_span, b: an_span): boolean
Like memory.equals
but operate over spans.
memory.spanfind
function memory.spanfind(s: an_span, x: auto): isize
Scan span s
for value x
and returns its respective index.
In case x
is not found -1 is returned.
os
The os library provides some operating system facilities.
Some os
functions behavior may vary across different operating systems,
or may not be supported.
os
global os: type = @record{}
Namespace for OS module.
os.execute
function os.execute(command: facultative(string)): (boolean, string, integer)
Passes command to be executed by an operating system shell.
Its first result is true
if the command terminated successfully, or false
otherwise.
After this first result the function returns a string plus a number, as follows:
"exit"
: the command terminated normally; the following number is the exit status of the command."unsupported"
: executing command is not supported in the system.
When called without a command, os.execute
returns a boolean that is true
if a shell is available.
This function is equivalent to the ISO C function system
.
This function is system dependent and is not available on all platforms.
os.exit
function os.exit(code: overload(integer,boolean,niltype)): void
Calls the ISO C function exit
to terminate the host program.
If code
is true
, the returned status is EXIT_SUCCESS
.
If code
is false
, the returned status is EXIT_FAILURE
.
If code
is a number, the returned status is this number.
The default value for code is true
.
os.setenv
function os.setenv(varname: string, value: facultative(string)): (boolean, string, integer)
Sets the value of the process environment variable varname
to value
.
In case the variable already exists, then it is overwritten, otherwise it is added.
If value
is not present, then the variable is removed.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
os.getenv
function os.getenv(varname: string): string
Returns the value of the process environment variable varname
.
In case the variable is not defined, an empty string is returned.
os.remove
function os.remove(filename: string): (boolean, string, integer)
Deletes the file (or empty directory, on POSIX systems) with the given name.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
os.rename
function os.rename(oldname: string, newname: string): (boolean, string, integer)
Renames the file or directory named oldname
to newname
.
Returns true
on success, otherwise false
plus an error message and a system-dependent error code.
os.setlocale
function os.setlocale(locale: facultative(string), category: facultative(string)): string
Sets the current locale of the program.
locale
is a system-dependent string specifying a locale.
category
is an optional string describing which category to change:
"all"
, "collate"
, "ctype"
, "monetary"
, "numeric"
, or "time"
;
the default category is “all”.
If locale is the empty string, the current locale is set to an implementation-defined native locale.
If locale is the string "C"
, the current locale is set to the standard C locale.
The function returns the name of the new locale on success, or an empty string if the request cannot be honored.
os.tmpname
function os.tmpname(): string
Returns a string with a file name that can be used for a temporary file.
The file must be explicitly opened before its use and explicitly removed when no longer needed.
In POSIX systems, this function also creates a file with that name, to avoid security risks.
(Someone else might create the file with wrong permissions in the time between getting the name and creating the file.)
You still have to open the file to use it and to remove it (even if you do not use it).
When possible, you may prefer to use io.tmpfile
, which automatically removes the file when the program ends.
os.date
function os.date(format: facultative(string), formattime: facultative(integer)): string
Returns a string or a table containing date and time,
formatted according to the given string format
.
If the formattime
argument is present, this is the time to be formatted
(see the os.time
function for a description of this value).
Otherwise, date
formats the current time.
If format
starts with ‘!’, then the date is formatted in UTC (Coordinated Universal Time).
After this optional character, the date is
formatted according to the same rules as the ISO C function strftime
.
If format
is absent, it defaults to “%c”,
which gives a human-readable date and time representation using the current locale.
On non-POSIX systems, this function may be not thread safe
because of its reliance on C function gmtime
and C function localtime
.
os.clock
function os.clock(): number
Returns an approximation of the amount in seconds of CPU time used by the program,
as returned by the underlying ISO C function clock
.
os.difftime
function os.difftime(t2: integer, t1: integer): number
Returns the difference, in seconds, from time t1
to time t2
(where the times are values returned by os.time
).
In POSIX, Windows, and some other systems, this value is exactly t2 - t1
.
os.timedesc
global os.timedesc: type = @record{
year: integer, month: integer, day: integer,
hour: integer, min: integer, sec: integer,
isdst: boolean
}
Time description, used by function os.time
.
os.time
function os.time(desc: facultative(os.timedesc)): integer
Returns the current time when called without arguments, or a time representing the local date and time specified by the given time description.
When the function is called, the values in these fields do not need to be inside their valid ranges. For instance, if sec is -10, it means 10 seconds before the time specified by the other fields. If hour is 1000, it means 1000 hours after the time specified by the other fields.
The returned value is a number, whose meaning depends on your system.
In POSIX, Windows, and some other systems,
this number counts the number of seconds since some given start time (the “epoch”).
In other systems, the meaning is not specified,
and the number returned by time can be used only as an argument to os.date
and os.difftime
.
When called with a record os.timedesc
, os.time
also normalizes all the fields,
so that they represent the same time as before the call but with values inside their valid ranges.
os.realtime
function os.realtime(): (integer, integer)
Like os.time
, returns the current time but using a high resolution clock.
Returns two integers, the number of seconds since the “epoch” (same value as os.time
)
plus the remaining number of nanoseconds.
A system realtime clock is used.
A realtime clock can jump, because it is affected by changes in system time clock,
thus prefer using os.now
for timers.
The operation may not be supported by all systems, or may fail in some systems,
in that case -1
, 0
is returned.
os.now
function os.now(): number
Get time elapsed in seconds since its first call using a high resolution timer.
Returns a number greater than or equal to 0
on success, otherwise -1
.
In the first successful call 0
is returned,
in subsequent calls the relative time in seconds since the first call is returned.
This is typically used to compute time differences with high precision.
A system monotonic clock is used if supported by the OS. A monotonic clock can’t jump, because it isn’t affected by changes in system time clock. If a monotonic clock is not supported, then a realtime may be used as fallback.
The time resolution is unspecified and depends on the OS, but typically has nanosecond precision on POSIX systems.
The operation may not be supported by all systems, or may fail in some systems,
in that case -1
is returned.
os.sleep
function os.sleep(secs: number): boolean
Sleep the current OS thread for secs
seconds.
Returns true on success, otherwise false.
The operation typically has at least millisecond precision, the sleep time will be typically the requested one, but can be a little lower or higher depending on the system.
The operation may not be supported by all systems, or may fail in some systems, in that case false is returned.
span
The span library provides the span generic.
A span is used as a view to elements of a contiguous memory block. Contiguous containers like vector, sequence and array can be viewed as a span. Span elements start at index 0 and go up to length-1 (like fixed arrays).
Spans are especially useful for making functions with arguments that are agnostic to the input container type.
Spans are also known as “fat pointer” or “slice” in some other languages.
Remarks: A span initialized from a list of unnamed fields points to an array of the list elements.
spanT
local spanT: type = @record{
data: *[0]T,
size: usize
}
Span record defined when instantiating the generic span
with type T
.
spanT.empty
function spanT.empty(self: spanT): boolean
Returns true
if the span is empty, that is, its length is 0
.
spanT.valid
function spanT.valid(self: spanT): boolean
Returns true
if the span is not empty and has a valid data pointer.
spanT.sub
function spanT.sub(self: spanT, i: usize, j: usize): spanT
Returns the sub span that starts at i
(inclusive) and continues until j
(exclusive).
Both i
and j-1
must be in the span bounds and the expression i <= j
must be true.
Remarks: When using the GC the sub span will not hold reference to the original span data, thus if you don’t hold the original reference somewhere you will have a dangling reference.
spanT.__atindex
function spanT.__atindex(self: spanT, i: usize): *T
Returns the reference of element at index i
.
Argument i
must be less than span size.
Used when indexing elements with square brackets ([]
).
spanT.__len
function spanT.__len(self: spanT): isize
Returns the number of elements in the span.
spanT.sizebytes
function spanT.sizebytes(self: spanT): usize
Returns the size of the span in bytes.
spanT.__convert
function spanT.__convert(values: spanT_convertible_concept): spanT
Initializes a span from a pointer to contiguous containers.
spanT.as
function spanT.as(self: spanT, U: type): auto
Converts a span of T into a span of U.
span
global span: type
Generic used to instantiate a span type in the form of span(T)
.
Argument T
is the value type that the span will store.
string
The string library provides functions to manipulate strings.
String points to an immutable contiguous sequence of characters. Internally it just holds a pointer to a buffer and a size. It’s buffer is zero terminated by default to have more compatibility with C.
The string type is defined by the compiler, however it does not have its methods implemented, this module implements all string methods.
When the GC is disabled, you should call string.destroy
to free the string memory
of non views strings returned by this library, otherwise the memory will leak.
Note that string literals points to a buffer in the program static storage
and such strings should never be destroyed.
Note that all string methods are 1-indexed (like Lua).
string
global string = @record{
data: *[0]byte,
size: usize,
}
The string record defined in the compiler sources.
New strings always have the data
buffer null terminated by default
to have more comparability with C APIs.
The data
buffer is 0-indexed (unlike string APIs).
string.create
function string.create(size: usize): string
Allocate a new string to be filled with length size
.
The string is guaranteed to be zero terminated,
so it can safely be used as a cstring
.
The string data is not initialized.
string:destroy
function string:destroy(): void
Destroys a string freeing its memory.
This must never be called on string literals. This function is only needed to be called when not using the GC.
string.copy
function string.copy(s: string): string
Clone a string, allocating new space.
This is useful in case you want to own the string memory, so you can modify it or manually manage its memory when GC is disabled.
string.byte
function string.byte(s: string, i: facultative(isize)): byte
Returns the internal numeric codes of the character at position i
.
string.sub
function string.sub(s: string, i: isize, j: facultative(isize)): string
Returns the substring of s
that starts at i
and continues until j
(both inclusive).
Both i
and j
can be negative.
If j
is absent, then it is assumed to be equal to -1
(which is the same as the string length).
In particular, the call string.sub(s,1,j)
returns a prefix of s
with length j
,
and string.sub(s, -i)
(for a positive i
) returns a suffix of s
with length i
.
string.subview
function string.subview(s: string, i: isize, j: facultative(isize)): string
Return a view for a sub string in a string.
The main difference between this and string.sub
is that here we don’t allocate a new string,
instead it reuses its memory as an optimization.
Use this only if you know what you are doing, to be safe use string.sub
instead.
Remarks: When using the GC the view will not hold reference to the original string,
thus if you don’t hold the original string reference somewhere you will have a dangling reference.
The view string may not be zero terminated, thus you should never
cast it to a cstring
to use in C functions.
string.rep
function string.rep(s: string, n: isize, sep: facultative(string)): string
Returns a string that is the concatenation of n
copies of the string s
separated by the string sep
.
The default value for sep
is the empty string (that is, no separator).
Returns the empty string if n
is not positive.
string.reverse
function string.reverse(s: string): string
Returns a string that is the string s
reversed.
string.upper
function string.upper(s: string): string
Receives a string and returns a copy of this string with all lowercase letters changed to uppercase.
All other characters are left unchanged.
The definition of what a lowercase letter is depends on the current locale
only if pragma useclocale
is set.
string.lower
function string.lower(s: string): string
Receives a string and returns a copy of this string with all uppercase letters changed to lowercase.
All other characters are left unchanged.
The definition of what an uppercase letter is depends on the current locale
only if pragma useclocale
is set.
string.char
function string.char(...: varargs): string
Receives zero or more integers and returns a string with length equal to the number of arguments, in which each character has the internal numeric code equal to its corresponding argument. Numeric codes are not necessarily portable across platforms.
string.format
function string.format(fmt: string, ...: varargs): string
Returns a formatted version of its variable number of arguments following the description
given in its first argument, which must be a string.
The format string follows the same rules as the ISO C function sprintf
.
The only differences are that the conversion specifiers and modifiers *, h, L, l
are not supported.
string.len
function string.len(s: string): isize
Receives a string and returns its length. The empty string “” has length 0. Embedded zeros are counted.
string.fillcstring
function string.fillcstring(s: string, buf: *[0]cchar, buflen: usize): boolean
Fills a cstring
buffer.
This is mainly used to ensure the string is zero terminated.
Returns true
in case of success, otherwise false
when the buflen
is not enough.
string.span
function string.span(s: string): span(byte)
Converts a string to a span of bytes.
Remarks: Similar to subview
a reference of the current string data is returned.
string.concat
function string.concat(list: span(string), sep: facultative(string)): string
Concatenates a span of a strings into a single string.
string:__close
function string:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
string.__atindex
function string.__atindex(s: string, i: usize): *byte
Returns the reference of byte representing the character at index i
.
Argument i
must be an integer between 1 and the string size.
Used when indexing elements with square brackets ([]
).
string.__len
function string.__len(a: string): isize
Return length of a string. Used by the length operator (#
).
string.__concat
function string.__concat(a: auto, b: auto): string
Concatenate two strings. Used by the concatenation operator (..
).
string.__eq
function string.__eq(a: string, b: string): boolean
Compare two strings. Used by the equality operator (==
).
string.__lt
function string.__lt(a: string, b: string): boolean
Compare if string a
is less than string b
in lexicographical order.
Used by the less than operator (<
).
string.__le
function string.__le(a: string, b: string): boolean
Compare if string a
is less or equal than string b
in lexicographical order.
Used by the less or equal than operator (<=
).
string.__add
function string.__add(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of addition.
Use by the add operator (+
).
string.__sub
function string.__sub(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of subtraction.
Use by the subtract operator (-
).
string.__mul
function string.__mul(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of multiplication.
Use by the multiply operator (*
).
string.__div
function string.__div(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of division.
Use by the division operator (/
).
string.__idiv
function string.__idiv(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of floor division.
Use by the integer division operator (//
).
string.__tdiv
function string.__tdiv(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of truncate division.
Use by the truncate division operator (///
).
string.__mod
function string.__mod(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of floor division remainder.
Use by the modulo operator (%
).
string.__tmod
function string.__tmod(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of truncate division remainder.
Use by the truncate module operator (%%%
).
string.__pow
function string.__pow(a: scalar_coercion_concept, b: scalar_coercion_concept): number
Converts input strings to numbers and returns the result of exponentiation.
Use by the pow operator (^
).
string.__unm
function string.__unm(a: scalar_coercion_concept): number
Converts the input string to a number and returns its negation.
Use by the negation operator (-
).
string.__band
function string.__band(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise AND.
Use by the bitwise AND operator (&
).
string.__bor
function string.__bor(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise OR.
Use by the bitwise OR operator (|
).
string.__bxor
function string.__bxor(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise XOR.
Use by the bitwise XOR operator (~
).
string.__shl
function string.__shl(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise logical left shift.
Use by the bitwise logical left shift operator (<<
).
string.__shr
function string.__shr(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise logical right shift.
Use by the bitwise logical right shift operator (>>
).
string.__asr
function string.__asr(a: scalar_coercion_concept, b: scalar_coercion_concept): integer
Converts input strings to integers and returns the result of bitwise arithmetic right shift.
Use by the bitwise arithmetic right shift operator (>>>
).
string.__bnot
function string.__bnot(a: scalar_coercion_concept): integer
Converts the input string to an integer and returns its bitwise NOT.
Use by the bitwise NOT operator (~
).
string.find
function string.find(s: string, pattern: string, init: facultative(isize), plain: facultative(boolean)): (isize, isize)
Look for the first match of pattern in the string.
Returns the indices of where this occurrence starts and ends.
The indices will be positive if a match is found, zero otherwise. A third, optional argument specifies where to start the search, its default value is 1 and can be negative. A value of true as a fourth, optional argument plain turns off the pattern matching facilities.
string.gmatch
function string.gmatch(s: string, pattern: string, init: facultative(isize)): (auto, auto, string)
Returns an iterator function that, each time it is called, returns the whole match plus a span of captures. A third, optional argument specifies where to start the search, its default value is 1 and can be negative.
string.gmatchview
function string.gmatchview(s: string, pattern: string, init: facultative(isize)): (auto, auto, string)
Like string.gmatch
but uses sub string views (see also string.subview
).
string.gsub
function string.gsub(s: string, pattern: string, repl: auto, maxn: facultative(isize)): (string, isize)
Returns a copy of s
in which all (or the first n
, if given) occurrences of the pattern
have been replaced by a replacement string specified by repl
,
which can be a string, a string hashmap, or a function.
gsub
also returns, as its second value, the total number of matches that occurred.
The name gsub
comes from Global SUBstitution.
- If
repl
is a string, then its value is used for replacement. The character ‘% works as an escape character: any sequence inrepl
of the form ‘%d’, with d between 1 and 9, stands for the value of the d-th captured substring; the sequence ‘%0’ stands for the whole match; the sequence ‘%%’ stands for a single %.
If repl
is a hashmap of strings, then it is queried for every match,
using the first capture as the key and its hashmap value as the replacement string,
if the.
If repl
is a function, then this function is called every time a match occurs
with all captured substrings passed as arguments, in order.
In any case, if the pattern specifies no captures,
then it behaves as if the whole pattern was inside a capture.
If the value returned by the table query or by the function call is a string or a number, then it is used as the replacement string; otherwise, if it is false or nil, then there is no replacement (that is, the original match is kept in the string).
string.match
function string.match(s: string, pattern: string, init: facultative(isize)): (boolean, sequence(string))
Look for the first match of pattern in the string. If it finds one, then returns true plus a sequence with the captured values, otherwise it returns false plus an empty sequence. If pattern specifies no captures, then the whole match is captured. A third, optional argument specifies where to start the search, its default value is 1 and can be negative.
string.matchview
function string.matchview(s: string, pattern: string, init: facultative(isize)): (boolean, sequence(string))
Like string.match
but uses sub string views (see also string.subview
).
string.pack
function string.pack(fmt: string, ...: varargs): string
Returns a binary string containing the values in ...
,
serialized in binary form (packed) according to the format string fmt
.
For description of the format options, see Lua’s format strings for pack.
string.unpack
function string.unpack(fmt: string <comptime>, s: string, init: facultative(isize))
Returns the values packed in string s
(see string.pack
) according to the format string fmt
.
An optional init
marks where to start reading in s
(default is 1
).
After the read values, this function also returns the index of the first unread byte in s
.
For description of the format options, see Lua’s format strings for pack.
Remarks: fmt
must be a compile-time string.
string.packsize
function string.packsize(fmt: string): isize
Returns the size of a string resulting from string.pack with the given format. The format string cannot have the variable-length options ‘s’ or ‘z’.
For description of the format options, see Lua’s format strings for pack.
tostring
global function tostring(x: auto): string
Convert a value to a string.
A new string will be always allocated.
The __tostring
metamethod may be called,
in this case, it must always return a new allocated string.
tostringview
global function tostringview(x: auto): string
Convert a value to a string without performing new allocations.
The __tostringview
metamethod may be called,
in this case, it must always return a non owned string reference
that the caller won’t attempt to destroy.
tonumber
global function tonumber(x: auto, base: facultative(integer)): auto
Convert a value to a number.
tointeger
global function tointeger(x: auto, base: facultative(integer)): integer
Convert a value to an integer.
stringbuilder
The string builder library allows high-performance composition of string-like data.
Unlike strings, which are immutable, string builders are mutable sequences of bytes. The convenient string builder API simplifies common string composing tasks that would otherwise require creating many intermediate strings.
String builders improve performance by eliminating redundant memory copies, object creation, and garbage collection overhead.
stringbuilderT
local stringbuilderT: type = @record{
data: span(byte),
size: usize,
allocator: Allocator
}
String builder record defined when instantiating the generic stringbuilder
.
stringbuilderT.make
function stringbuilderT.make(allocator: Allocator): stringbuilderT
Creates a string builder using a custom allocator instance. Useful only when using instanced allocators.
stringbuilderT:destroy
function stringbuilderT:destroy(): void
Free string builder resources and resets it to a zeroed state. Useful only when not using the garbage collector.
stringbuilderT:__close
function stringbuilderT:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
stringbuilderT:clear
function stringbuilderT:clear(): void
Clears the internal written buffer of the string builder, leaving it empty. The internal buffer is not freed, and it may be reused.
stringbuilderT:prepare
function stringbuilderT:prepare(n: usize): span(byte)
Prepares to append at least n
bytes into the internal writing buffer.
Returns a span that can be used to write bytes to.
Typically the returned span length will have at least n
bytes,
but may have more to facilitate efficient buffer growth.
If there is not enough space to allocate then the span length will be 0.
After calling prepare
and writing bytes to its returned span,
the commit
function must be called subsequently to advance the internal writing buffer.
stringbuilderT:commit
function stringbuilderT:commit(n: usize): void
Commits n
previously written bytes effectively advancing the internal writing buffer.
A call to prepare
must be preceded before calling this function, and its
returned span length must have at least n
bytes.
stringbuilderT:rollback
function stringbuilderT:rollback(n: usize): void
Removes n
previously written bytes effectively rewinding the internal writing buffer.
The internal buffer must have at least n
bytes.
stringbuilderT:resize
function stringbuilderT:resize(n: usize): boolean
Resizes the internal writing buffer to n
bytes, and sets the writing position to its end.
When growing new elements will be zeroed.
Returns true
in case of success, otherwise false
when out of buffer memory space.
stringbuilderT:writebyte
function stringbuilderT:writebyte(c: byte, n: facultative(usize)): boolean
Appends byte c
to the internal writing buffer.
In case n
is present, then that amount of bytes is added, otherwise one byte is added.
Returns true
in case of success, otherwise false
when out of buffer memory space.
stringbuilderT:write
function stringbuilderT:write(...: varargs): (boolean, usize)
Appends values to the internal writing buffer.
The arguments must be a string, convertible to string, or a span o bytes.
Returns true
in case of success plus the number of bytes written,
otherwise false
when out of buffer memory space.
stringbuilderT:writef
function stringbuilderT:writef(fmt: string, ...: varargs): (boolean, usize)
Appends a formatted string to the internal writing buffer.
Returns true
in case of success plus the number of bytes written,
otherwise false
when out of buffer memory space.
The fmt
string is expected to be a valid format, it should follow string.format
rules.
stringbuilderT:view
function stringbuilderT:view(): string
Returns a string view of the current written bytes so far. No allocation is done.
stringbuilderT:__tostringview
function stringbuilderT:__tostringview(): string
Alias to view
method, for supporting tostringview
.
stringbuilderT:promote
function stringbuilderT:promote(): string
Promote a stringbuilder
to a string
.
The allocated internal buffer memory is forwarded to the string,
and then the string builder is destroyed.
This is typically used as an optimization to skip an extra allocating when finishing building a string. This method is only available for the default string builder.
stringbuilderT:__len
function stringbuilderT:__len(): isize
Returns the number of bytes in the internal writing buffer.
Used by the length operator (#
).
stringbuilderT:__tostring
function stringbuilderT:__tostring(): string
Converts the string builder to a new string
.
The operation allocates new space for the returned string.
stringbuilder
global stringbuilder: type
The default string builder using DefaultAllocator
.
This type can also be used as a generic in the form of stringbuilder(Allocator)
,
where Allocator
is an allocator type for the string builder buffer.
traits
The traits library provides utilities to gather type information.
traits
global traits: type = @record{}
Namespace for traits module.
traits.typeid
global traits.typeid: type = @uint32
Type of the identifier for types.
traits.typeinfo
global traits.typeinfo: type = @record{
id: traits.typeid,
name: string,
nickname: string,
codename: string
}
Record for type information.
traits.typeidof
function traits.typeidof(v: auto): traits.typeid
Returns the typeid
of v
.
The given v
can be either a runtime value or a compile-time type.
traits.typeinfoof
function traits.typeinfoof(v: auto): traits.typeinfo
Returns type information of v
.
The given v
can be either a runtime value or a compile-time type.
type
global function type(v: auto): string
Returns the type of v
, coded as a string, as follows:
"nil"
forniltype
"pointer"
for pointers andnilptr
"number"
for scalar types (including enums)"string"
for types that can represent a string"record"
for records"union"
for unions"type"
for compile-time types"function"
for functions"polyfunction"
for polymorphic functions
This function behaves as describe to be compatible with Lua APIs.
utf8
The UTF-8 library provides basic support for UTF-8 encoding.
The library does not provide any support for Unicode other than the handling of the encoding. Any operation that needs the meaning of a character, such as character classification, is outside its scope.
Unless stated otherwise, all functions that expect a byte position as a parameter assume that the given position is either the start of a byte sequence or one plus the length of the subject string. As in the string library, negative indices count from the end of the string.
Functions that create byte sequences accept all values up to 0x7FFFFFFF
,
as defined in the original UTF-8 specification,
that implies byte sequences of up to six bytes.
Functions that interpret byte sequences only accept valid sequences (well formed and not overlong)
By default, they only accept byte sequences that result in valid Unicode code points,
rejecting values greater than 0x10FFFF
and surrogates.
A boolean argument relax
, when available, lifts these checks,
so that all values up to 0x7FFFFFFF
are accepted.
(Not well formed and overlong sequences are still rejected.)
utf8
global utf8: type = @record{}
Namespace for UTF-8 module.
utf8.charpattern
global utf8.charpattern: string
Pattern to match exactly one UTF-8 byte sequence, assuming that the subject is a valid UTF-8 string.
utf8.char
function utf8.char(...: varargs): string
Receives zero or more integers, converts each one to its corresponding UTF-8 byte sequence, and returns a string with the concatenation of all these sequences.
Containers of integers (e.g vector, sequence or span) are also accepted as arguments, returning a string with the concatenation of all their elements.
utf8.codes
function utf8.codes(s: string, relax: facultative(boolean))
: (function(string, isize): (boolean, isize, uint32), string, isize)
UTF-8 iterator, use to iterate over UTF-8 codes. It returns values so that the construction
for p, c in utf8.codes(s) do end
will iterate over all UTF-8 characters in string s
,
with p
being the position (in bytes) and c
the code point of each character.
It raises an error if it meets any invalid byte sequence.
utf8.codepoint
function utf8.codepoint(s: string, i: facultative(isize), relax: facultative(boolean)): uint32
Returns the code point (as integer) from the characters in s
at position i
.
The default for i
is 1
.
It raises an error if it meets any invalid byte sequence.
utf8.offset
function utf8.offset(s: string, n: isize, i: facultative(isize)): isize
Returns the position (in bytes) where the encoding of the n-th character of s
starts (counting from position i
).
A negative n
gets characters before position i
.
The default for i
is 1
when n
is non-negative and #s + 1
otherwise,
so that utf8.offset(s, -n)
gets the offset of the n-th character from the end of the string.
If the specified character is neither in the subject nor right after its end,
the function returns -1
.
utf8.len
function utf8.len(s: string, i: facultative(isize), j: facultative(isize), relax: facultative(boolean)): (isize, isize)
Returns the number of UTF-8 characters in string s
that start between positions i
and j
(both inclusive).
The default for i
is 1
and for j
is -1
.
If it finds any invalid byte sequence, returns -1
plus the position of the first invalid byte.
coroutine
The coroutine library provides functions to manipulate coroutines.
A coroutine represents an independent “green” thread of execution. Unlike threads in multithread systems, however, a coroutine only suspends its execution by explicitly calling a yield function.
You create a coroutine by calling coroutine.create
.
Its sole argument is a function that is the body function of the coroutine.
The create
function only creates a new coroutine and returns a handle to it, it does not start the coroutine.
You execute a coroutine by calling coroutine.resume
.
When calling a resume function the coroutine starts its execution by calling its body function.
After the coroutine starts running, it runs until it terminates or yields.
A coroutine yields by calling coroutine.yield
.
When a coroutine yields, the corresponding resume returns immediately,
even if the yield happens inside nested function calls (that is, not in the main function).
In the case of a yield, resume also returns true.
The next time you resume the same coroutine, it continues its execution from the point where it yielded.
At the moment Nelua does not support variable arguments in yield
and resume
(unlikely Lua).
To pass values between resume and yield, you must use coroutine.push
and coroutine.pop
with the input and output types known at compile-time.
coroutine
global coroutine: type = @*minicoro.Coro
The coroutine handle.
coroutine.destroy
function coroutine.destroy(co: coroutine): (boolean, string)
Destroy the coroutine co
, freeing its stack memory and resources.
Note that this is only needed to be called when the GC is disabled.
Remarks: Destroying a coroutine before "dead"
state will not execute its defer statements.
coroutine:__close
function coroutine:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
coroutine.create
function coroutine.create(f: function_concept): (coroutine, string)
Returns a new coroutine with body function f
.
The function allocates stack memory and resources for the coroutine.
It only creates a new coroutine and returns a handle to it, it does not start the coroutine.
coroutine.push
function coroutine.push(co: coroutine, ...: varargs): (boolean, string)
Pushes multiple values into the coroutine co
storage, returning true
on success.
- The values can be received in the next
coroutine.pop
or in the body function arguments (when coroutine starts). - In case of an error returns
false
plus the error message. - The user is responsible to always use the right types and push/pop order and count.
coroutine.pop
function coroutine.pop(co: coroutine, ...: varargs): (boolean, string)
Pops multiple values from the coroutine co
storage, returning true
on success.
- Only pointers to values are expected in extra arguments,
and they should follow the same order of the last
coroutine.push
. - The retrieved values was either set by the last
coroutine.pop
or returned by its body function (when coroutine finishes). - In case of an error, return
false
plus the error message, and the values may not be set. - The user is responsible to always use the right types and push/pop order and count.
coroutine.isyieldable
function coroutine.isyieldable(co: coroutine): boolean
Checks whether the coroutine co
can yield.
A coroutine is yieldable if it isn’t the main thread.
coroutine.resume
function coroutine.resume(co: coroutine, ...: varargs): (boolean, string)
Starts or continues the execution of the coroutine co
.
- The first time you resume a coroutine, it starts running its body function.
- Extra arguments
...
are pushed before resuming. - If the coroutine has yielded, resume continues it.
- If the coroutine runs without any errors, resume returns
true
plus an empty error message. - If there is any error, resume returns
false
plus the error message. - Values passed to the last yield should be retrieved with
coroutine.pop
.
coroutine.spawn
function coroutine.spawn(f: function_concept, ...: varargs): (coroutine, string)
Creates and immediately starts a new coroutine with body function f
.
Extra arguments are passed to the function f
arguments.
This is effectively the same as calling coroutine.create
and then coroutine.resume
.
coroutine.yield
function coroutine.yield(...: varargs): (boolean, string)
Suspends the execution of the running coroutine.
- On failure raises an error.
- Extra arguments
...
are pushed before yielding. - Values passed to last resume should be retrieved with
coroutine.pop
.
coroutine.running
function coroutine.running(): (coroutine, boolean)
Returns the running coroutine plus a boolean that is true when the running coroutine is the main one.
coroutine.status
function coroutine.status(co: coroutine): string
Returns the status of the coroutine co
.
The status string can be any of the following:
"running"
, if the coroutine is running (that is, it is the one that called status)."suspended"
, if the coroutine is suspended in a call to yield, or if it has not started running yet."normal"
if the coroutine is active but not running (that is, it has resumed another coroutine)."dead"
if the coroutine has finished its body function, or if it has been destroyed.
hash
The hash library provides utilities to generate hash for values.
The included hash functions in this library are intended to be used containers such as hashmap
and table
,
thus the hash functions are designed to be fast, and are not necessarily equal across platforms
and may skip bytes.
Use a better hash algorithm in case you need deterministic hash across platforms
and with better quality.
hash
global hash: type = @record{}
Namespace for hash module.
hash.short
function hash.short(data: span(byte)): usize
Hashes a span of bytes, iterating over all bytes. This function can be slow for long spans.
hash.long
function hash.long(data: span(byte)): usize
Hashes a span of bytes, iterating at most 32 bytes evenly spaced. This function can be fast to hash long spans, at cost of hash quality.
hash.combine
function hash.combine(seed: usize, value: usize): usize
Returns the combination of the hashes seed
and value
.
hash.hash
function hash.hash(v: auto): usize
Hashes value v
, used to hash anything.
To customize a hash for a specific record you can define __hash
metamethod,
and it will be used when calling this function.
vector
The vector library provides an efficient dynamic sized array of values.
A vector has the following semantics:
- Its elements starts at index 0 and go up to its length minus 1.
- It should never be passed by value while being modified,
otherwise the behavior is undefined, in case this is needed then try the
sequence
library. - Any failure when growing a vector raises an error.
Remarks: A vector initialized from a list of unnamed fields is filled with the list elements.
vectorT
local vectorT: type = @record{
data: span(T),
size: usize,
allocator: Allocator
}
Vector record defined when instantiating the generic vector
with type T
.
vectorT.make
function vectorT.make(allocator: Allocator): vectorT
Creates a vector using a custom allocator instance. Useful only when using instanced allocators.
vectorT:clear
function vectorT:clear(): void
Removes all elements from the vector. The internal storage buffer is not freed, and it may be reused.
vectorT:destroy
function vectorT:destroy(): void
Free vector resources and resets it to a zeroed state. Useful only when not using the garbage collector.
vectorT:__close
function vectorT:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
vectorT:reserve
function vectorT:reserve(n: usize): void
Reserve at least n
elements in the vector storage.
vectorT:resize
function vectorT:resize(n: usize): void
Resizes the vector so that it contains n
elements.
When expanding new elements are initialized to zeros.
vectorT:copy
function vectorT:copy(): vectorT
Returns a shallow copy of the vector, allocating a new vector.
vectorT:push
function vectorT:push(v: T): void
Inserts a element v
at the end of the vector.
vectorT:pop
function vectorT:pop(): T
Removes the last element in the vector and returns its value. The vector must not be empty.
vectorT:insert
function vectorT:insert(pos: usize, v: T): void
Inserts element v
at position pos
in the vector.
Elements with position greater or equal than pos
are shifted up.
The position pos
must be valid (within vector bounds).
vectorT:remove
function vectorT:remove(pos: usize): T
Removes element at position pos
in the vector and returns its value.
Elements with position greater than pos
are shifted down.
The position pos
must be valid (within vector bounds).
vectorT:removevalue
function vectorT:removevalue(v: T): boolean
Removes the first item from the vector whose value is v
.
The remaining elements are shifted.
Returns true
if an element was removed, otherwise false
.
vectorT:removeif
function vectorT:removeif(pred: function(v: T): boolean): void
Removes all elements from the vector where pred
function returns true
.
The remaining elements are shifted.
vectorT:capacity
function vectorT:capacity(): isize
Returns the number of elements the vector can store before triggering a reallocation.
vectorT:__atindex
function vectorT:__atindex(pos: usize): *T
Returns reference to element at position pos
.
Position pos
must be valid (within vector bounds).
The reference will remain valid until the vector grows.
Used when indexing elements with square brackets ([]
).
vectorT:__len
function vectorT:__len(): isize
Returns the number of elements in the vector.
Used by the length operator (#
).
vectorT.__convert
function vectorT.__convert(values: an_arrayT): vectorT
Initializes vector elements from a fixed array.
Used to initialize vector elements with curly braces ({}
).
vector
global vector: type
Generic used to instantiate a vector type in the form of vector(T, Allocator)
.
Argument T
is the value type that the vector will store.
Argument Allocator
is an allocator type for the container storage,
in case absent then DefaultAllocator
is used.
sequence
The sequence library provides a dynamic sized array of values, like vector, but with the following semantics:
- Its elements starts at position 1 and go up to its length (like lua tables).
- Internally it just contains a pointer, thus the list itself is passed by reference by default (like lua tables again).
- Indexing the next elements after the end makes the sequence grow automatically.
- Any failure when growing a sequence raises an error.
A sequence is typically used as a more efficient table that can hold only sequences of a fixed value type.
Remarks: A sequence initialized from a list of unnamed fields is filled with the list elements.
sequenceT
local sequenceT: type = @record{
impl: *sequenceimplT,
allocator: Allocator
}
Sequence record defined when instantiating the generic sequence
with type T
.
sequenceT:_init
function sequenceT:_init(): void
Initializes sequence internal implementation if not initialized yet. This is already implicitly called by other sequence functions when needed.
sequenceT.make
function sequenceT.make(allocator: Allocator): sequenceT
Create a sequence using a custom allocator instance. Useful only when using instanced allocators.
sequenceT:clear
function sequenceT:clear(): void
Removes all elements from the sequence. The internal storage buffer is not freed, and it may be reused.
sequenceT:destroy
function sequenceT:destroy(): void
Free sequence resources and resets it to a zeroed state. Useful only when not using the garbage collector.
sequenceT:__close
function sequenceT:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
sequenceT:reserve
function sequenceT:reserve(n: usize): void
Reserve at least n
elements in the sequence storage.
sequenceT:resize
function sequenceT:resize(n: usize): void
Resizes the sequence so that it contains n
elements.
When expanding new elements are zero initialized.
sequenceT:copy
function sequenceT:copy(): sequenceT
Returns a shallow copy of the sequence, allocating a new sequence.
sequenceT:push
function sequenceT:push(v: T): void
Inserts elements v
at the end of the sequence.
sequenceT:pop
function sequenceT:pop(): T
Removes the last element in the sequence and returns its value. The sequence must not be empty.
sequenceT:insert
function sequenceT:insert(pos: usize, v: T): void
Inserts element v
at position pos
in the sequence.
Elements with position greater or equal than pos
are shifted up.
The pos
must be valid (within sequence bounds).
sequenceT:remove
function sequenceT:remove(pos: usize): T
Removes element at position pos
in the sequence and returns its value.
Elements with position greater than pos
are shifted down.
The pos
must be valid (within sequence bounds).
sequenceT:removevalue
function sequenceT:removevalue(v: T): boolean
Removes the first item from the sequence whose value is v
.
The remaining elements are shifted.
Returns true
if the item was removed, otherwise false
.
sequenceT:removeif
function sequenceT:removeif(pred: function(v: T): boolean): void
Removes all elements from the sequence where pred
function returns true
.
The remaining elements are shifted.
sequenceT:capacity
function sequenceT:capacity(): isize
Returns the number of elements the sequence can store before triggering a reallocation.
sequenceT:__atindex
function sequenceT:__atindex(pos: usize): *T
Returns reference to element at position pos
.
If pos
is the sequence size plus 1, then a zeroed element is added and return its reference.
Argument pos
must be at most the sequence size plus 1.
The reference will remain valid until the sequence grows.
Used when indexing elements with square brackets ([]
).
sequenceT:__len
function sequenceT:__len(): isize
Returns the number of elements in the sequence.
It never counts the element at position 0
.
Used by the length operator (#
).
sequenceT.__convert
function sequenceT.__convert(values: an_arrayT): sequenceT
Initializes sequence elements from a fixed array.
Used to initialize sequence elements with curly braces ({}
).
sequenceT:unpack
function sequenceT:unpack(i: isize <comptime>, j: isize <comptime>)
Returns the sequence elements from i
to j
.
Both i
and j
must be known at compile-time.
This function is equivalent to
return seq[i], seq[i+1], ..., seq[j]
sequence
global sequence: type
Generic used to instantiate a sequence type in the form of sequence(T, Allocator)
.
Argument T
is the value type that the sequence will store.
Argument Allocator
is an allocator type for the container storage,
in case absent then DefaultAllocator
is used.
list
The list library provides a double linked list container.
A double linked list is a dynamic sized container that supports constant time insertion and removal from anywhere in the container. Doubled linked lists don’t support fast random access, use a vector or sequence in that case.
listnodeT
local listnodeT: type = @record{
prev: *listnodeT,
next: *listnodeT,
value: T
}
List node record defined when instantiating the generic list
.
listT
local listT: type = @record{
front: *listnodeT, -- list begin
back: *listnodeT, -- list end
allocator: Allocator
}
List record defined when instantiating the generic list
.
listT.make
function listT.make(allocator: Allocator): listT
Creates a list using a custom allocator instance. This is only to be used when not using the default allocator.
listT:clear
function listT:clear(): void
Remove all elements from the list.
Complexity: O(n).
listT:destroy
function listT:destroy(): void
Resets the list to zeroed state, freeing all used resources.
This is more useful to free resources when not using the garbage collector.
listT:__close
function listT:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
listT:pushfront
function listT:pushfront(value: T): void
Inserts an element at beginning of the list.
Complexity: O(1).
listT:pushback
function listT:pushback(value: T): void
Inserts an element at the end of the list.
Complexity: O(1).
listT:insert
function listT:insert(pos: *listnodeT, value: T): *listnodeT
Inserts an element before element node pos
.
Returns the inserted element node reference.
If pos
is nilptr
, then the element is added at the end of the list.
Complexity: O(1).
listT:popfront
function listT:popfront(): T
Removes the first element and returns it. If the list is empty, then throws a runtime error on debug builds.
Complexity: O(1).
listT:popback
function listT:popback(): T
Removes the first element and returns it. If the list is empty, then throws a runtime error on debug builds.
Complexity: O(1).
listT:find
function listT:find(value: T): *listnodeT
Find an element in the list, returning it’s node reference when found.
Complexity: O(1).
listT:erase
function listT:erase(node: *listnodeT): *listnodeT
Erases a node from the list. Returns the node reference of the next element. If the node not in the list, then throws a runtime error on debug builds.
Complexity: O(1).
listT:empty
function listT:empty(): boolean
Returns whether the list is empty.
listT:__len
function listT:__len(): isize
Returns the number of elements in the list.
Complexity: O(n).
listT:__next
function listT:__next(node: *listnodeT): (boolean, *listnodeT, T)
Returns the next node of the list and its element.
Used with pairs()
iterator.
listT:__mnext
function listT:__mnext(node: *listnodeT): (boolean, *listnodeT, *T)
Returns the next node of the list and its element by reference.
Used with mpairs()
iterator.
listT:__pairs
function listT:__pairs(): (auto, *listT, *listnodeT)
Allow using pairs()
to iterate the container.
listT:__mpairs
function listT:__mpairs(): (auto, *listT, *listnodeT)
Allow using mpairs()
to iterate the container.
listT.__convert
function listT.__convert(values: an_arrayT): listT
Initializes list elements from a fixed array.
Used to initialize list elements with curly braces ({}
).
list
global list: type
Generic used to instantiate a list type in the form of list(T, Allocator)
.
Argument T
is the value type that the list will store.
Argument Allocator
is an allocator type for the container storage,
in case absent then then DefaultAllocator
is used.
hashmap
The hashmap library provides a hash table with fixed types.
A hash map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.
The hash map share similarities with Lua tables but should not be used like them, the main differences are:
- There is no array part.
- The length operator returns number of elements in the map.
- Indexing automatically inserts a key-value pair, to avoid this use
peek()
method. - Values cannot be
nil
or set tonil
. - Can only use
pairs()
to iterate.
Any failure when growing a hash map raises an error.
hashnodeT
local hashnodeT: type = @record{
key: K,
value: V,
filled: boolean,
next: usize,
}
Hash map node record defined when instantiating the generic hashmap
.
hashmapT
local hashmapT: type = @record{
buckets: span(usize),
nodes: span(hashnodeT),
size: usize,
free_index: usize,
allocator: Allocator
}
Hash map record defined when instantiating the generic hashmap
.
hashmapT.make
function hashmapT.make(allocator: Allocator): hashmapT
Creates a hash map using a custom allocator instance. Useful only when using instanced allocators.
hashmapT:destroy
function hashmapT:destroy(): void
Resets the container to a zeroed state, freeing all used resources.
Complexity: O(1).
hashmapT:__close
function hashmapT:__close(): void
Effectively the same as destroy
, called when a to-be-closed variable goes out of scope.
hashmapT:clear
function hashmapT:clear(): void
Remove all elements from the container. The internal storage buffers are not freed, and they may be reused.
Complexity: O(n).
hashmapT:_find
function hashmapT:_find(key: K): (usize, usize, usize)
Used internally to find a value at a key returning it’s node index.
hashmapT:rehash
function hashmapT:rehash(bucket_count: usize): void
Sets the number of buckets to at least bucket_count
and rehashes the container when needed.
The number of new buckets will always be at least
the smallest appropriate value to not exceed the maximum load factor,
thus rehashing with 0 bucket_count
can be used to shrink the hash map.
Rehash invalidates all references to element values previously returned.
Complexity: Average case O(n).
hashmapT:reserve
function hashmapT:reserve(count: usize): void
Sets the number of buckets to the number needed to accommodate at least count
elements
without exceeding maximum load factor and rehashes the container when needed.
Complexity: Average case O(n).
hashmapT:_at
function hashmapT:_at(key: K): usize
Used internally to find or make a value at a key returning it’s node index.
hashmapT:__atindex
function hashmapT:__atindex(key: K): *V
Returns a reference to the value that is mapped to a key.
If such key does not exist, then it’s inserted and a rehash may happen.
The reference will remain valid until next rehash (when growing).
This allows indexing the hash map with square brackets []
.
Complexity: Average case O(1).
hashmapT:peek
function hashmapT:peek(key: K): *V
Returns a reference to the value that is mapped to a key.
If no such element exists, returns nilptr
.
The reference will remain valid until next rehash (when growing).
Complexity: Average case O(1).
hashmapT:has
function hashmapT:has(key: K): boolean
Returns true if a key exists in the container.
Complexity: Average case O(1).
hashmapT:has_and_get
function hashmapT:has_and_get(key: K): (boolean, V)
Returns true plus the value for the element with key key
in in the container in case it exists.
Otherwise, returns false plus a zero initialized element.
Complexity: Average case O(1).
hashmapT:remove
function hashmapT:remove(key: K): V
Removes an element with a key from the container (if it exists). Returns the removed value that was was actually removed. If the key does not exist, then returns a zeroed value.
It’s safe to remove an element while iterating. References to element values previously returned will remain valid.
Complexity: Average case O(1).
hashmapT:erase
function hashmapT:erase(key: K): boolean
Removes an element with a key from the container (if it exists). Returns the true if it was actually removed.
It’s safe to remove an element while iterating. References to element values previously returned will remain valid.
Complexity: Average case O(1).
hashmapT:loadfactor
function hashmapT:loadfactor(): number
Returns the average number of elements per bucket.
hashmapT:bucketcount
function hashmapT:bucketcount(): usize
Returns the number of buckets in the container.
hashmapT:capacity
function hashmapT:capacity(): usize
Returns the number of elements the container can store before triggering a rehash.
hashmapT:__len
function hashmapT:__len(): isize
Returns the number of elements in the container.
hashmapT:__pairs
function hashmapT:__pairs(): (auto, hashmap_iteratorT, K)
Allow using pairs()
to iterate the container.
hashmapT:__mpairs
function hashmapT:__mpairs(): (auto, hashmap_iteratorT, K)
Allow using mpairs()
to iterate the container.
hashmapT:_next_node
function hashmapT:_next_node(key: facultative(K)): *hashnodeT
Used internally by __next
and __mnext
.
hashmapT:__next
function hashmapT:__next(key: facultative(K)): (boolean, K, V)
Allow using next()
to iterate the container.
hashmapT:__mnext
function hashmapT:__mnext(key: facultative(K)): (boolean, K, *V)
Allow using mnext()
to iterate the container.
hashmap
global hashmap: type
Generic used to instantiate a hash map type in the form of hashmap(K, V, HashFunc, KeyEqualFunc, Allocator)
.
Argument K
is the key type for the hash map.
Argument V
is the value type for the hash map.
Argument HashFunc
is a function to hash a key,
in case absent then hash.hash
is used.
Argument KeyEqualFunc
is a function to compare two keys,
in case absent then ==
is used.
Argument Allocator
is an allocator type for the container storage,
in case absent then then DefaultAllocator
is used.
allocators.default
The default allocator library provides the default allocator used by the standard libraries.
The default allocator is GCAllocator
when GC is enabled,
otherwise GeneralAllocator
(when using the pragma nogc
).
When disabling the GC the user is responsible for manually deallocating unused memory from the default allocator.
new
global function new(what: auto, size: facultative(usize), flags: facultative(usize)): auto
Shorthand for default_allocator:new
.
For details see also Allocator:new
.
delete
global function delete(v: auto): void
Shorthand for default_allocator:delete
.
For details see also Allocator:delete
.
allocators.allocator
Allocator interface library provides common functions implemented on every allocator.
This library is not an allocator by itself, but it’s used by other allocators.
- A method with ‘0’ suffix initializes the memory with zeros.
- A method with ‘x’ prefix raises an error in case of an allocation failure.
- A method with ‘span’ prefix returns a span, instead of a pointer.
Allocation failures usually happen when running out of memory.
AllocatorFlags
global AllocatorFlags: type = @enum(usize){
GCRoot = 1 << 17, -- Allocation always scanned and never collected.
GCLeaf = 1 << 18, -- Allocation never scanned (contains no pointers).
GCBranch = 1 << 19, -- Allocation should be scanned despite being detected as leaf (contains pointers).
GCExtern = 1 << 20, -- External allocation, finalizers should be called, however deallocation is disabled.
}
Flags for new allocations.
Allocator
local Allocator: type
The allocator type which the allocator interface will implements the methods.
Allocator:alloc
function Allocator:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer of the allocated memory block.
- The allocated memory is not initialized.
- If
size
is zero or the operation fails, then returnsnilptr
. - If
flags
is present, then it is passed as flags to the underlying allocator.
Allocator:xalloc
function Allocator:xalloc(size: usize, flags: facultative(usize)): pointer
Like alloc
, but raises an error in case the allocation fails.
Allocator:alloc0
function Allocator:alloc0(size: usize, flags: facultative(usize)): pointer
Like alloc
, but the allocated memory is initialized with zeros.
Allocator:xalloc0
function Allocator:xalloc0(size: usize, flags: facultative(usize)): pointer
Like alloc0
, but raises an error in case the allocation fails.
Allocator:dealloc
function Allocator:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
.
- If
p
isnilptr
, then no operation is performed. - The
dealloc(p)
has been already been called before, then undefined behavior occurs. - Unless
p
isnilptr
, it must have been returned by an earlier allocation call from this allocator.
Allocator:realloc
function Allocator:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by p
from size oldsize
bytes to newsize
bytes.
- The allocated memory contents will be unchanged from the start of the region
up to the minimum of the
oldsize
andnewsize
. - If
newsize
is larger than theoldsize
, the added memory is not initialized. - If
p
isnilptr
, the call is equivalent toalloc(newsize)
. - If
newsize
is equal tooldsize
, then no operation is performed. - If
newsize
is zero, the call is equivalent todealloc(p)
. - If the operation fails, then the original
p
is left untouched, it’s not deallocated or moved, andnilptr
is returned. - The returned pointer may be the same as
p
if the allocation was not moved, or different fromp
if the allocation was moved to a new address. - Unless
p
isnilptr
, it must have been returned by an earlier allocation call from this allocator.
Allocator:xrealloc
function Allocator:xrealloc(p: pointer, newsize: usize, oldsize: usize): pointer
Like realloc
, but raises an error in case the allocation fails.
Allocator:realloc0
function Allocator:realloc0(p: pointer, newsize: usize, oldsize: usize): pointer
Like realloc
, but initializes added memory with zeros.
Allocator:xrealloc0
function Allocator:xrealloc0(p: pointer, newsize: usize, oldsize: usize): pointer
Like realloc0
, but raises an error in case the allocation fails.
Allocator:spanalloc
function Allocator:spanalloc(T: type, size: usize, flags: facultative(usize)): auto
Like alloc
, but returns a span of T
with size
elements.
- The allocated memory region will have
size * #T
bytes. - If the operation fails, then an empty span is returned.
Allocator:xspanalloc
function Allocator:xspanalloc(T: type, size: usize, flags: facultative(usize)): auto
Like spanalloc
, but raises an error in case the allocation fails.
Allocator:spanalloc0
function Allocator:spanalloc0(T: type, size: usize, flags: facultative(usize)): auto
Like spanalloc
, but initializes added memory with zeros.
Allocator:xspanalloc0
function Allocator:xspanalloc0(T: type, size: usize, flags: facultative(usize)): auto
Like spanalloc0
, but raises an error in case the allocation fails.
Allocator:spandealloc
function Allocator:spandealloc(s: span_concept): void
Like dealloc
, but operates over a span.
Allocator:spanrealloc
function Allocator:spanrealloc(s: span_concept, size: usize): auto
Like realloc
, but operate over a span.
If the operation fails and size > 0
,
then the memory region is left untouched and span s
is returned,
thus to check for an allocation failure you have to compare
if the returned span size is different than size
.
Allocator:xspanrealloc
function Allocator:xspanrealloc(s: span_concept, size: usize): auto
Like spanrealloc
, but raises an error in case the allocation fails.
Allocator:spanrealloc0
function Allocator:spanrealloc0(s: span_concept, size: usize): auto
Like spanrealloc
, but initializes added memory with zeros.
Allocator:xspanrealloc0
function Allocator:xspanrealloc0(s: span_concept, size: usize): auto
Like spanrealloc0
, but raises an error in case the allocation fails.
Allocator:new
function Allocator:new(what: auto, size: facultative(usize), flags: facultative(usize)): auto
Allocates a new value.
- Argument
what
must be either a compile-time type or a runtime initialized value. - If
what
is a runtime value, the return value will have the same type, and it’s contents are copied into the new allocated value. - If
what
is a compile-time type, the returned value will be ofwhat
type, and its contents are zero initialized. - If the operation fails, then an error is raised.
- If
size
is present, then returns a span withsize
elements ofwhat
, instead of a pointer. - In case the value has the
__new
metamethod, it will be called immediately after the allocation. - In case the value has a finalizer, and the allocator supports finalizers,
such as
GCAllocator
, the value is marked to be finalized when deallocated. - In case the value record size is 0, a valid pointer (different from nullptr) is guaranteed to be returned.
Allocator:delete
function Allocator:delete(v: deleteable_concept): void
Deletes value v
, which must be either a pointer or a span.
It’s similar to dealloc
or spandealloc
,
but delete
should only be used when new
is used for the same allocation.
If the deleted values has __delete
metamethod, then it’s called before deletion.
allocators.general
The general allocator uses the system’s general purpose allocator to allocate dynamic memory, usually this an efficient allocator for the general use case. It uses the allocation functions provided by the system.
The general allocator can also be overridden by an allocator instance in case
the global embedded_general_allocator
is declared before this library is required.
GeneralAllocator
global GeneralAllocator: type = @record{}
General allocator record.
general_allocator
global general_allocator: GeneralAllocator
General allocator instance, that must be used to perform allocations.
GeneralAllocator:alloc
function GeneralAllocator:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer of the allocated memory block.
The allocated memory is not initialized.
For more details see Allocator:alloc
.
This function calls system’s malloc()
.
GeneralAllocator:alloc0
function GeneralAllocator:alloc0(size: usize, flags: facultative(usize)): pointer
Like alloc
, but the allocated memory is initialized with zeros.
This function calls system’s calloc()
.
GeneralAllocator:dealloc
function GeneralAllocator:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
.
For more details see Allocator:dealloc
.
This function calls system’s free()
.
GeneralAllocator:realloc
function GeneralAllocator:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by p
from size oldsize
bytes to newsize
bytes.
For more details see Allocator:realloc
.
This function calls system’s realloc()
.
allocators.gc
The garbage collector allocator provides automatic memory management.
With this allocator you don’t have to worry about deallocating objects that are no longer needed. It manages memory automatically by running a garbage collector from time to time to collect all dead pointers (that is, pointers that are no longer accessible in the heap or stack).
Only memory allocated by this allocator is subject to automatic management.
The collector implements a simple mark-and-sweep garbage collector. It’s a stop-the-world garbage collector, that is, it may halt execution of the program to run a collection cycle. It is a conservative garbage collector, that is, it scans the heap and stack memory assuming any bit pattern could be a pointer.
The collector has one number to control its garbage-collection cycle, the garbage collector pause, it controls how long the collector waits before starting a new cycle. Larger values make the collector less aggressive. The default value of 200 means that the collector waits for the total memory in use to double before starting a new cycle. Values smaller than 100 mean the collector will not wait to start a new cycle.
GCFlags
global GCFlags: type = @enum(usize) {
MARK = 1 << 16, -- Marked for collection (used only internally).
FINALIZE = 1 << 17, -- Finalizer should be called before deallocating.
ROOT = AllocatorFlags.GCRoot, -- Allocation always scanned and never collected.
LEAF = AllocatorFlags.GCLeaf, -- Allocation never scanned (contains no pointers).
BRANCH = AllocatorFlags.GCBranch, -- Allocation should be scanned despite being detected as leaf (contains pointers).
EXTERN = AllocatorFlags.GCExtern, -- External allocation, finalizers should be called, however deallocation is disabled.
}
Possible flags to set when registering a new pointer in the allocator.
GC
global GC: type = @record{
running: boolean, -- Whether the collector is running.
collecting: boolean, -- Whether a collecting cycle is actively running.
pause: usize, -- The collector pause (default 200).
membytes: usize, -- Total allocated memory currently being tracked by the GC (in bytes).
lastmembytes: usize, -- Total allocated memory tracked just after the last collection cycle.
addrormask: usize, -- OR bit mask for pointer address being tracked by the GC.
addrandmask: usize, -- AND bit mask for pointer address being tracked by the GC.
stacktop: usize, -- Stack top address.
stackbottom: usize, -- Stack bottom address.
finalizeitems: vector(pointer, GeneralAllocator), -- List of pointers to be finalized.
scanranges: vector(GCScanRange, GeneralAllocator), -- List of ranges to be scanned.
items: hashmap(pointer, GCItem, nil, nil, GeneralAllocator), -- Map of all tracked allocations.
rootitems: hashmap(pointer, usize, nil, nil, GeneralAllocator), -- Map of all tracked root allocations.
}
The garbage collector record.
gc
global gc: GC
The global GC instance.
GC:unregister
function GC:unregister(ptr: pointer, finalize: facultative(boolean)): void
Unregister pointer ptr
from the GC.
If finalize
is true
and the pointer has a finalizer, then it’s called.
GC:collect
function GC:collect(): void
Performs a full garbage collection cycle. This halts the application until a the collection is finished. All collected items are finalized and deallocated. The finalization or deallocation order is random
GC:step
function GC:step(): boolean
Trigger a collection cycle when the memory has grown above pause threshold.
GC:register
function GC:register(ptr: pointer, size: usize, flags: usize,
finalizer: function(pointer, pointer): void, userdata: pointer): void
Register pointer ptr
with size
bytes into the GC.
If finalizer
is present, then it will be called when the pointer is collected.
GC:reregister
function GC:reregister(oldptr: pointer, newptr: pointer, newsize: usize): void
Register pointer that moved from oldptr
to newptr
with new size newsize
.
Called when reallocating a pointers.
GC:setstacktop
function GC:setstacktop(stacktop: facultative(usize)): usize
Set new stack top for the GC scanner and returns the previous stack top.
This may be used to support scanning from coroutines.
If stacktop
is omitted then it will calculate it.
GC:count
function GC:count(): number
Returns the total memory size tracked by the collector (in Kbytes). The value has a fractional part, so that it multiplied by 1024 gives the exact number of bytes.
GC:stop
function GC:stop(): void
Stops automatic execution of the garbage collector. The collector will run only when explicitly invoked, until a call to restart it.
GC:restart
function GC:restart(): void
Restarts the garbage collector.
GC:setpause
function GC:setpause(pause: integer): integer
Set pause
as the new pause for the collector.
Returns previous pause value.
GC:isrunning
function GC:isrunning(): boolean
Returns a boolean that tells whether the collector is running (i.e., not stopped).
GC:init
function GC:init(stack: pointer): void
Initializes the garbage collector. This is called automatically when the starting the application.
GC:destroy
function GC:destroy(): void
Destroys the garbage collector. All allocations are finalized and deallocated. This is called automatically when the application finishes with success. The GC is not expected to be used after calling this.
collectgarbage
global function collectgarbage(opt: overload(string,number,niltype) <comptime>,
arg: facultative(integer))
This function is a generic interface to the garbage collector.
It performs different functions according to its first argument, opt
:
"collect"
: Performs a full garbage-collection cycle. This is the default option."stop"
: Stops automatic execution of the garbage collector. The collector will run only when explicitly invoked, until a call to restart it."restart"
: Restarts automatic execution of the garbage collector."count"
: Returns the total memory being tracked by the collector in Kbytes. The value has a fractional part, so that it multiplied by 1024 gives the exact number of bytes."step"
: Performs a garbage-collection step. The collector will perform a full collection cycle only if the memory has grown above pause threshold. Returnstrue
if a collection cycle was run. Calling this is only useful when the GC is stopped."setpause"
: Setsarg
as the new value for the pause of the collector. Returns the previous value for pause."isrunning"
: Returns a boolean that tells whether the collector is running (i.e., not stopped).
GCAllocator
global GCAllocator: type = @record{}
GC allocator record.
gc_allocator
global gc_allocator: GCAllocator
GC allocator instance, that must be used to perform allocations.
GCAllocator:alloc
function GCAllocator:alloc(size: usize,
flags: facultative(usize),
finalizer: facultative(function(pointer, pointer): void),
userdata: facultative(pointer)): pointer
Allocates size
bytes and returns a pointer of the allocated memory block.
The allocated memory is not initialized.
If flags
is present, then it’s passed to GC:register
, see GCFlags
for possible values.
If finalizer
is present, then it will be called before the allocation is deallocated.
If userdata
is present, then it’s passed as a parameters to the finalizer.
For more details see Allocator:alloc
.
GCAllocator:alloc0
function GCAllocator:alloc0(size: usize,
flags: facultative(usize),
finalizer: facultative(function(pointer, pointer): void),
userdata: facultative(pointer)): pointer
Like alloc
, but the allocated memory is initialized with zeros.
GCAllocator:dealloc
function GCAllocator:dealloc(ptr: pointer): void
Deallocates the allocated memory block pointed by ptr
.
If ptr
has a finalizer, then it’s called before deallocating.
For more details see Allocator:dealloc
.
This function calls system’s free()
.
GCAllocator:realloc
function GCAllocator:realloc(ptr: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by ptr
from size oldsize
bytes to newsize
bytes.
Flags and finalizer of ptr
are preserved.
For more details see Allocator:realloc
.
GCAllocator:spanalloc
function GCAllocator:spanalloc(T: type, size: usize,
flags: facultative(usize),
finalizer: facultative(function(pointer, pointer): void),
userdata: facultative(pointer)): auto
Like alloc
, but returns a span of T
with size
elements.
This function automatically sets GCFlags.LEAF
in case T
has no pointers,
by doing so, it can skip unnecessary memory scans, thus the GC can collect faster.
For more details see Allocator:spanalloc
.
GCAllocator:spanalloc0
function GCAllocator:spanalloc0(T: type, size: usize,
flags: facultative(usize),
finalizer: facultative(function(pointer, pointer): void),
userdata: facultative(pointer)): auto
Like spanalloc0
, but initializes added memory with zeros.
GCAllocator:new
function GCAllocator:new(what: auto, size: facultative(usize), flags: facultative(usize)): auto
Allocates a new value.
- Argument
what
must be either a compile-time type or a runtime initialized value. - If
what
is a runtime value, the return value will have the same type, and it’s contents are copied into the new allocated value. - If
what
is a compile-time type, the returned value will be ofwhat
type, and its contents are zero initialized. - If the operation fails, then an error is raised.
- If
size
is present, then returns a span withsize
elements ofwhat
, instead of a pointer. - In case the value has the
__new
metamethod, it will be called immediately after the allocation. - In case the value has the
__gc
metamethod, it will be called once the value is collected. - In case the value record size is 0, a valid pointer (different from nullptr) is guaranteed to be returned.
allocators.arena
The arena allocator, sometimes also known as linear, monotonic or region allocator, allocates everything from a fixed size contiguous buffer by incrementing an offset every new allocation.
The purpose of this allocator is to have very fast allocations with almost no runtime cost when the maximum used space is known ahead and to quickly deallocate many allocated objects at once with almost no runtime cost too.
Reallocations and deallocations do not free space unless once for the last recent allocation.
To free space deallocall
should be called when all operations on its allocations are finished.
The allocator buffer will reside on the stack when declared inside a function, or on the static memory storage when declared in a top scope, or on the heap if allocated by the general allocator.
When declaring on the stack there is no need to perform deallocations at the end of the scope, just leave the scope ends to have a quick cleanup. Also take care to not use a large buffer on the stack, or the program may crash with not enough stack space, on some system for example the stack is limited to 1MB.
By default allocations are aligned to 8 bytes unless explicitly told otherwise. Remember to use the proper alignment for the allocated objects to have fast memory access.
The implementation is based on this article.
ArenaAllocatorT
local ArenaAllocatorT: type = @record{
prev_offset: usize,
curr_offset: usize,
buffer: [SIZE]byte
}
Arena allocator record defined when instantiating the generic ArenaAllocator
.
ArenaAllocatorT:alloc
function ArenaAllocatorT:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer to the allocated memory block,
advancing the internal arena offset.
The allocated memory is not initialized.
If size
is zero or the operation fails, then returns nilptr
.
ArenaAllocatorT:dealloc
function ArenaAllocatorT:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
.
If p
is the very last allocation,
then the internal arena offset is rewind by one allocation.
ArenaAllocatorT:deallocall
function ArenaAllocatorT:deallocall(): void
Deallocate all allocations. rewinding the entire internal arena offset.
This operation is fast.
ArenaAllocatorT:realloc
function ArenaAllocatorT:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by p
from size oldsize
bytes to newsize
bytes.
If p
is not the very last allocation,
then its contents are copied to a new memory block.
For more realloc
details see also Allocator:realloc
.
ArenaAllocator
global ArenaAllocator: type
Generic used to instantiate a arena allocator type in the form of ArenaAllocator(SIZE, ALIGN)
.
Argument SIZE
is the arena fixed buffer size in bytes, must be multiple of ALIGN
.
Argument ALIGN
is the default alignment for new allocations,
must be at least 4 and in power of two, in case absent then 8
is used.
allocators.stack
The stack allocator, allocates everything from a fixed size contiguous buffer by incrementing an offset every new allocation and decrementing on every deallocation that follows the LIFO (last-in, first-out) principle. This allocator is an evolution of the Arena allocator, thus understand the arena allocator first before using this.
The purpose of this allocator is to have very fast allocations with almost no runtime cost when the maximum used space is known ahead.
Deallocations out of order will cause a runtime error only on checked builds. By default alignment should be at least 4 because this allocator stores a header for allocation metadata with this requirement. By default allocations are aligned to 8 bytes unless explicitly told otherwise.
The implementation is based on this article.
StackAllocatorT
local StackAllocatorT: type = @record{
prev_offset: usize,
curr_offset: usize,
buffer: [SIZE]byte
}
Stack allocator record defined when instantiating the generic StackAllocator
.
StackAllocatorT:alloc
function StackAllocatorT:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer to the allocated memory block,
advancing the internal stack offset.
The allocated memory is not initialized.
If size
is zero or the operation fails, then returns nilptr
.
StackAllocatorT:dealloc
function StackAllocatorT:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
,
rewinding the internal stack offset by one allocation.
Unless p
is nilptr
, it must be the very last allocation.
StackAllocatorT:deallocall
function StackAllocatorT:deallocall(): void
Deallocate all allocations, rewinding the entire internal stack offset.
This operation is fast.
StackAllocatorT:realloc
function StackAllocatorT:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by p
from size oldsize
bytes to newsize
bytes,
rewinding or advancing the internal stack offset as necessary.
Unless p
is nilptr
, it must be the very last allocation.
For more realloc
details see also Allocator:realloc
.
StackAllocator
global StackAllocator: type
Generic used to instantiate a stack allocator type in the form of StackAllocator(SIZE, ALIGN)
.
Argument SIZE
is the fixed stack buffer size in bytes, must be multiple of ALIGN
.
Argument ALIGN
is the default alignment for new allocations,
must be at least 4 and in power of two, in case absent then 8
is used.
allocators.pool
The pool allocator allocates chunks from a fixed contiguous buffer of many chunks, allocations pop a free chunk from the pool and deallocations push a chunk back. It works by using a single linked list of free chunks.
The purpose of this allocator is to have very fast allocations of objects with almost no runtime cost when the maximum used space is known ahead.
Reallocations and deallocations free space (unlikely the Arena allocator). Allocations greater than the chunk size will always fail.
The implementation is based on this article.
PoolAllocatorT
local PoolAllocatorT: type = @record{
initialized: boolean,
head: *PoolFreeNode,
buffer: [SIZE]PoolChunkT
}
Pool allocator record defined when instantiating the generic PoolAllocator
.
PoolAllocatorT:alloc
function PoolAllocatorT:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer to the allocated memory block,
using a free chunk from the pool.
The allocated memory is not initialized.
If size
is greater than the size of T, then the operation fails.
If size
is zero, then the operation fails.
If the operation fails, then returns nilptr
.
PoolAllocatorT:dealloc
function PoolAllocatorT:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
,
leaving the pool chunk of p
free to be reused in a subsequent allocation.
PoolAllocatorT:deallocall
function PoolAllocatorT:deallocall(): void
Deallocate all allocations, leaving all pool chunks free to be reused in new allocations.
PoolAllocatorT:realloc
function PoolAllocatorT:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
This function is provided just for compatibility.
Any attempt to grow the memory block will fail, returning nilptr
.
Any attempt to shrink the memory block will be ignored, returning the same p
.
New allocations and deallocation through this function will work normally.
PoolAllocator
global PoolAllocator: type
Generic used to instantiate a arena allocator type in the form of PoolAllocator(T, SIZE)
.
Argument T
is the object type in the pool.
Argument SIZE
is the maximum number of elements in the pool.
The pool will effectively have an internal buffer with #T * SIZE
bytes.
allocators.heap
This is a minimal general purpose heap allocator, that could serve as replacement to the system’s general allocator. It requires a pre allocated memory region in advance. It’s purpose is to have predictable allocation and deallocation time when you can allocate the maximum memory usage in advance.
It uses linked lists to search for the best free node. It tries to have a fast alloc/dealloc. However it may fragment more than other allocators.
In some cases it can be faster than the general purpose allocator. However usually you are better off with the system’s general purpose allocator. This may be more useful to have reliable alloc/dealloc time on real time applications, or if you want to avoid the system’s default allocator for some reason, or if the system does not have an allocator.
Its memory cannot grow automatically, use the system’s general purpose allocator for that. The allocator is not thread safe, it was designed to be used in single thread applications. Allocations are always aligned to the platform max alignment, typically 16 bytes.
NOTE: This is experimental, a bunch of tests were done but is not really battle tested.
The implementation is based on this project, however it has heavy customized to have more performance, constant time allocations and alignment.
HeapAllocatorT
local HeapAllocatorT: type = @record{
initialized: boolean,
heap: Heap,
buffer: [SIZE]byte
}
Heap allocator record defined when instantiating the generic HeapAllocator
.
HeapAllocatorT:init
function HeapAllocatorT:init(): void
Initializes the heap allocator, called automatically on first alloc
/realloc
.
HeapAllocatorT:alloc
function HeapAllocatorT:alloc(size: usize, flags: facultative(usize)): pointer
Allocates size
bytes and returns a pointer to the allocated memory block.
The allocated memory is not initialized.
If size
is zero or the operation fails, then returns nilptr
.
HeapAllocatorT:dealloc
function HeapAllocatorT:dealloc(p: pointer): void
Deallocates the allocated memory block pointed by p
.
If p
is nilptr
, then no operation is performed.
The dealloc(p)
has been already been called before, then undefined behavior occurs.
Unless p
is nilptr
,
it must have been returned by an earlier allocation call from this allocator.
HeapAllocatorT:deallocall
function HeapAllocatorT:deallocall(): void
Deallocate all allocations from the heap.
HeapAllocatorT:realloc
function HeapAllocatorT:realloc(p: pointer, newsize: usize, oldsize: usize): pointer
Changes the size of the memory block pointer by p
from size oldsize
bytes to newsize
bytes.
For more details see Allocator:realloc
.
HeapAllocator
global HeapAllocator: type
Generic used to instantiate a heap allocator type in the form of HeapAllocator(SIZE)
.
Argument SIZE
is the size of the heap in bytes.