49 lines
2.7 KiB
Markdown
49 lines
2.7 KiB
Markdown
# Metamethods
|
|
|
|
This language relies on a small set of "metamethods" which define special
|
|
behavior that is required for all types:
|
|
|
|
- `func as_text(obj:&T?, colorize=no, type:&TypeInfo_t -> 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
|
|
`none`, a string representation of the type will be returned instead.
|
|
|
|
- `func compare(x:&T, y:&T, type:&TypeInfo_t -> 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.
|
|
|
|
- `func equals(x:&T, y:&T, type:&TypeInfo_t -> 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.
|
|
|
|
- `func hash(x:&T, type:&TypeInfo_t -> Int32)`: Values are hashed when used as keys in a
|
|
table or set. Hashing is consistent with equality, so two values that are
|
|
equal _must_ hash to the same hash value, ideally in a way that makes it
|
|
unlikely that two different values will have the same hash value.
|
|
|
|
Metamethods are automatically defined for all user-defined structs, DSLs, and
|
|
enums. At this time, metamethods may not be overridden.
|
|
|
|
## 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, Tomo uses generic metamethods, which are general-purpose functions that
|
|
take an object pointer and a type info struct pointer that has metadata about
|
|
the object's type. That metadata is added automatically at compile time and
|
|
used to perform the appropriate operations. As an example, every array follows
|
|
the same logic when performing comparisons, except that each item is compared
|
|
using the item's comparison function. Therefore, we can compile a single array
|
|
comparison function and reuse it for each type of array if we pass in some
|
|
metadata about how to compare the array's items.
|
|
|
|
When possible, we avoid calling metamethods (for example, doing fixed-sized
|
|
integer comparisons does not require calling a function), but metamethods are
|
|
available as a fallback or for working with container types or pointers.
|