code / tomo

Lines41.3K C23.7K Markdown9.7K YAML5.0K Tomo2.3K
7 others 763
Python231 Shell230 make212 INI47 Text21 SVG16 Lua6
(48 lines)

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, lists, 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 list 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 list comparison function and reuse it for each type of list if we pass in some metadata about how to compare the list'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.

1 # Metamethods
3 This language relies on a small set of "metamethods" which define special
4 behavior that is required for all types:
6 - `func as_text(obj:&T?, colorize=no, type:&TypeInfo_t -> Text)`: a method to
7 convert the type to a string. If `colorize` is `yes`, then the method should
8 include ANSI escape codes for syntax highlighting. If the `obj` pointer is
9 `none`, a string representation of the type will be returned instead.
11 - `func compare(x:&T, y:&T, type:&TypeInfo_t -> Int32)`: Return an integer representing
12 the result of comparing `x` and `y`, where negative numbers mean `x` is less
13 than `y`, zero means `x` is equal to `y`, and positive numbers mean `x` is
14 greater than `y`. For the purpose of floating point numbers, `NaN` is sorted
15 as greater than any other number value and `NaN` values are compared bitwise
16 between each other.
18 - `func equals(x:&T, y:&T, type:&TypeInfo_t -> Bool)`: This is the same as comparing two
19 numbers to check for zero, except for some minor differences: floating point
20 `NaN` values are _not_ equal to each other (IEEE 754) and the implementation
21 of `equals` may be faster to compute than `compare` for certain types, such
22 as tables.
24 - `func hash(x:&T, type:&TypeInfo_t -> Int32)`: Values are hashed when used as keys in a
25 table or set. Hashing is consistent with equality, so two values that are
26 equal _must_ hash to the same hash value, ideally in a way that makes it
27 unlikely that two different values will have the same hash value.
29 Metamethods are automatically defined for all user-defined structs, DSLs, and
30 enums. At this time, metamethods may not be overridden.
32 ## Generic Metamethods
34 Due to the presence of pointers, lists, tables, and functions, there are
35 potentially a very large number of metamethods that would be required if
36 _every_ type had its own set of metamethods. To reduce the amount of generated
37 code, Tomo uses generic metamethods, which are general-purpose functions that
38 take an object pointer and a type info struct pointer that has metadata about
39 the object's type. That metadata is added automatically at compile time and
40 used to perform the appropriate operations. As an example, every list follows
41 the same logic when performing comparisons, except that each item is compared
42 using the item's comparison function. Therefore, we can compile a single list
43 comparison function and reuse it for each type of list if we pass in some
44 metadata about how to compare the list's items.
46 When possible, we avoid calling metamethods (for example, doing fixed-sized
47 integer comparisons does not require calling a function), but metamethods are
48 available as a fallback or for working with container types or pointers.