Macros
Macros in Venus is a very different beast compared to that in C/C++, it's not a text based replacement mechanism, rather, it is a complete interactive mechanism with the compiler. You might want to call it a plugin system for the language.
Here is a simplest form:
macro loop {
return {
while (true) {
$body
}
}
}
You can use it as if loop
is a defined language feature:
import std.io, std.thread
main {
var n = 0
loop { // $body goes here
println("Hello $n")
thread.sleep_sec(2)
}
}
This will translate to
import std.io, std.thread
main {
var n = 0
while (true) {
println("Hello $n")
thread.sleep_sec(2)
}
}
compiler hooks
macro mymacro {
// hooks for lexer
pre_lex(string body) {
// do some pre lexing text based computations
}
on_lex(Token tok) {
// callback on each token lexed in this macro
}
post_lex(TokenRange tokens) {
// manipulate the tokens after lexing
}
TokenRange override_lexer(string body) {
// completely redefine the lexer for yourself
// you get the code body as input, and should return a range of Tokens
// TODO: you might want to extend new TokenTypes
}
// hooks for parser
pre_parse(ASTNode root) {
// prepare for the parser
}
on_parse(ASTNode node) {
// callback on each node parsed in this macro
}
post_parse(ASTNode root) {
// manipulate the ast tree after parsing
}
ASTNode override_parser(TokenRange tokens) {
// completely redefine the lexer for yourself
}
return {
// return a macro replaced code block
}
}