2024-02-17 11:20:55 -08:00
|
|
|
# Metamethods
|
|
|
|
|
|
|
|
This language relies on a small set of "metamethods" which define special
|
|
|
|
behavior that is required for all types:
|
|
|
|
|
2024-03-18 10:04:00 -07:00
|
|
|
- `as_text(obj:&(optional)T, colorize=no, type:&TypeInfo)->Text`: a method to
|
|
|
|
convert the type to a string. If `colorize` is `yes`, then the method should
|
|
|
|
include ANSI escape codes for syntax highlighting. If the `obj` pointer is
|
|
|
|
`NULL`, a string representation of the type will be returned instead.
|
|
|
|
|
|
|
|
- `compare(x:&T, y:&T, type:&TypeInfo)->Int32`: Return an integer representing
|
|
|
|
the result of comparing `x` and `y`, where negative numbers mean `x` is less
|
|
|
|
than `y`, zero means `x` is equal to `y`, and positive numbers mean `x` is
|
|
|
|
greater than `y`. For the purpose of floating point numbers, `NaN` is sorted
|
|
|
|
as greater than any other number value and `NaN` values are compared bitwise
|
|
|
|
between each other.
|
|
|
|
|
|
|
|
- `equals(x:&T, y:&T, type:&TypeInfo)->Bool`: This is the same as comparing two
|
|
|
|
numbers to check for zero, except for some minor differences: floating point
|
|
|
|
`NaN` values are _not_ equal to each other (IEEE 754) and the implementation
|
|
|
|
of `equals` may be faster to compute than `compare` for certain types, such
|
|
|
|
as tables.
|
2024-02-17 11:20:55 -08:00
|
|
|
|
|
|
|
Metamethods are automatically defined for all user-defined structs, DSLs, and
|
2024-03-18 10:04:00 -07:00
|
|
|
enums. At this time, metamethods may not be overridden.
|
2024-02-17 11:20:55 -08:00
|
|
|
|
|
|
|
## 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`
|
2024-03-18 10:04:00 -07:00
|
|
|
is an array of `Foo` structs, which has a defined `as_text()` method, then
|
|
|
|
rather than define a separate `Foo_Array_as_text()` function which would be 99%
|
|
|
|
identical to a `Baz_Array_as_text()` function, we instead insert a call to
|
|
|
|
`as_text(&foo, colorize, $ArrayInfo(&Foo))` to convert a `[Foo]` array to a
|
|
|
|
string, and you call `as_text(&baz, colorize, $ArrayInfo(&Baz))` 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,
|
|
|
|
$TableInfo(&KeyType, &ValueType))`. Or to hash an array of arrays of type
|
|
|
|
`Foo`, we would use `hash(&foo, $ArrayInfo($ArrayInfo(&Foo)))`.
|