From b6f91fd2fd20bd06549974a71b2494b03dd73337 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 17 Feb 2024 14:20:55 -0500 Subject: [PATCH] Docs --- docs/metamethods.md | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/metamethods.md diff --git a/docs/metamethods.md b/docs/metamethods.md new file mode 100644 index 0000000..9e43514 --- /dev/null +++ b/docs/metamethods.md @@ -0,0 +1,47 @@ +# Metamethods + +This language relies on a small set of "metamethods" which define special +behavior that is required for all types: + +- `as_string(obj:&(optional)T, colorize=no)->Str`: 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)->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)->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. + +## 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_string()` method, then +rather than define a separate `Foo_Array_as_string()` function that would be +99% identical to a `Baz_Array_as_string()` function, we instead insert a call +to `as_string(&foo, colorize, "[_]", Foo__as_string)` to convert a `[Foo]` +array to a string, and you call `as_string(&baz, colorize, "[_]", +Baz__as_string)` 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)`.