2.5 KiB
Metamethods
This language relies on a small set of "metamethods" which define special behavior that is required for all types:
-
as_str(obj:&(optional)T, colorize=no)->Str
: a method to convert the type to a string. Ifcolorize
isyes
, then the method should include ANSI escape codes for syntax highlighting. If theobj
pointer isNULL
, a string representation of the type will be returned instead. -
compare(x:&T, y:&T)->Int32
: Return an integer representing the result of comparingx
andy
, where negative numbers meanx
is less thany
, zero meansx
is equal toy
, and positive numbers meanx
is greater thany
. For the purpose of floating point numbers,NaN
is sorted as greater than any other number value andNaN
values are compared bitwise between each other. -
equals(x:&T, y:&T)->Bool
: This is the same as comparing two numbers to check for zero, except for some minor differences: floating pointNaN
values are not equal to each other (IEEE 754) and the implementation ofequals
may be faster to compute thancompare
for certain types, such as tables.
Metamethods are automatically defined for all user-defined structs, DSLs, and enums.
Generic Metamethods
Due to the presence of pointers, arrays, tables, and functions, there are
potentially a very large number of metamethods that would be required if
every type had its own set of metamethods. To reduce the amount of generated
code, we use generic metamethods, which are general-purpose functions that take
an automatically compiled format string and variable number of arguments that
describe how to run a metamethod for that type. As a simple example, if foo
is an array of type Foo
, which has a defined as_str()
method, then
rather than define a separate Foo_Array_as_str()
function that would be
99% identical to a Baz_Array_as_str()
function, we instead insert a call
to as_str(&foo, colorize, "[_]", Foo__as_str)
to convert a [Foo]
array to a string, and you call as_str(&baz, colorize, "[_]", Baz__as_str)
to convert a [Baz]
array to a string. The generic metamethod
handles all the reusable logic like "an array's string form starts with a '[',
then iterates over the items, getting the item's string form (whatever that is)
and putting commas between them".
Similarly, to compare two tables, we would use compare(&x, &y, "{_=>_}", KeyType__compare, ValueType__compare)
. Or to hash an array of arrays of type
Foo
, we would use hash(&foo, "[[_]]", Foo__hash)
.