|
Metalang99 1.13.3
Full-blown preprocessor metaprogramming
|
The core metalanguage. More...

Go to the source code of this file.
Macros | |
| #define | ML99_EVAL(...) ML99_PRIV_EVAL(__VA_ARGS__) |
| Evaluates a metaprogram. | |
| #define | ML99_call(op, ...) (ML99_PRIV_IF(ML99_PRIV_IS_UNTUPLE_FAST(op), 0args, 0op), op, __VA_ARGS__) |
| Invokes a metafunction with arguments. | |
| #define | ML99_callUneval(ident, ...) (0callUneval, ident, __VA_ARGS__) |
Invokes a metafunction ident with unevaluated arguments. | |
| #define | ML99_appl(f, ...) ML99_call(ML99_appl, f, __VA_ARGS__) |
Applies arguments to f. | |
| #define | ML99_appl2(f, a, b) ML99_call(ML99_appl2, f, a, b) |
Applies a and b to f. | |
| #define | ML99_appl3(f, a, b, c) ML99_call(ML99_appl3, f, a, b, c) |
Applies a, b, and c to f. | |
| #define | ML99_appl4(f, a, b, c, d) ML99_call(ML99_appl4, f, a, b, c, d) |
Applies a, b, c, and d to f. | |
| #define | ML99_compose(f, g) ML99_call(ML99_compose, f, g) |
Functional composition of f and g. | |
| #define | v(...) (0v, __VA_ARGS__) |
| A value that is pasted as-is; no evaluation occurs on provided arguments. | |
| #define | ML99_fatal(f, ...) (0fatal, f, #__VA_ARGS__) |
| Emits a fatal error. | |
| #define | ML99_abort(...) (0abort, __VA_ARGS__) |
| Immediately aborts the interpretation with evaluated arguments. | |
| #define | ML99_TERMS(...) __VA_ARGS__ |
| A convenience macro to emphasise that your metafunction expands to more than one term. | |
| #define | ML99_QUOTE(...) v(__VA_ARGS__) |
| Delays evaluation for provided terms. | |
The core metalanguage.
| #define ML99_abort | ( | ... | ) | (0abort, __VA_ARGS__) |
Immediately aborts the interpretation with evaluated arguments.
| #define ML99_appl | ( | f, | |
| ... | |||
| ) | ML99_call(ML99_appl, f, __VA_ARGS__) |
Applies arguments to f.
This function implements partial application: instead of invoking a metafunction with all arguments at once, you specify each argument separately. This concept allows better re-use of metafunctions by specifying some arguments immediately, and the other arguments later, even in different execution contexts (for example, see this SO answer).
f must be either a term reducing to a macro name or a term obtained via another call to ML99_appl. If f is a macro name, then a macro named <f>_ARITY (its arity specifier) must denote how many times f will be applied to its arguments. (In Metalang99, an arity is an intentionally more flexible concept than just a number of parameters, see below.) Each time ML99_appl is invoked, it accumulates provided variadic arguments and decrements the arity of f; when the arity of f is already 1, it eventually calls the initial f with all the accumulated arguments and provided variadic arguments.
Most often, an arity specifier denotes a count of all named parameters plus 1 if a macro is variadic (all the functions in the standard library follow this pattern). However, feel free to specify arities as you wish, with regard to the aforementioned semantics; for example, you can have a macro accepting x, y, z with an arity specifier 2, then you must invoke ML99_appl exactly 2 times (either x + y, z or x, y + z). One common pattern is to match a head and a tail of variadic arguments:
In this case, x, y, and z can be specified separately but other arguments all at once.
| #define ML99_appl2 | ( | f, | |
| a, | |||
| b | |||
| ) | ML99_call(ML99_appl2, f, a, b) |
Applies a and b to f.
| #define ML99_callUneval | ( | ident, | |
| ... | |||
| ) | (0callUneval, ident, __VA_ARGS__) |
Invokes a metafunction ident with unevaluated arguments.
It is semantically the same as ML99_call(ident, v(...)) but performs one less reduction steps.
| #define ML99_compose | ( | f, | |
| g | |||
| ) | ML99_call(ML99_compose, f, g) |
Functional composition of f and g.
| #define ML99_EVAL | ( | ... | ) | ML99_PRIV_EVAL(__VA_ARGS__) |
| #define ML99_fatal | ( | f, | |
| ... | |||
| ) | (0fatal, f, #__VA_ARGS__) |
Emits a fatal error.
f must be a macro name that has caused the error and the rest of arguments comprise the error message.
ML99_fatal interprets its variadic arguments without preprocessor expansion – i.e., they are pasted as-is. This is intended because otherwise identifiers located in an error message may stand for other macros that will be unintentionally expanded.
[playground.c]
[/bin/sh]
| #define ML99_QUOTE | ( | ... | ) | v(__VA_ARGS__) |
Delays evaluation for provided terms.
ML99_QUOTE(...) is functionally equivalent to v(...).
| #define ML99_TERMS | ( | ... | ) | __VA_ARGS__ |
A convenience macro to emphasise that your metafunction expands to more than one term.
This macro just expands to provided arguments.