tomo/docs/metamethods.md
2024-03-18 13:04:00 -04:00

2.6 KiB

Metamethods

This language relies on a small set of "metamethods" which define special behavior that is required for all types:

  • 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.

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, 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 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))).