[fpc-pascal] Proper preprocessor?
denisgolovan
denisgolovan at yandex.ru
Fri Jun 22 12:09:57 CEST 2018
See below the function to convert dynamic value into string value inside interpreter project I am working at, something similar to *ToStr family in FPC.
It's generated by the macro which expands to corresponding branches for each value type. "$" prefixes are for passing macro arguments. "ident!" is "calling" other macros, but it's quite obvious I guess.
Last syntax expression is "application" of this macro resulting in actual function creating and immediate compilation by Rust compiler.
macro_rules! to_string {
($($scalar:tt),*) => {
pub fn to_string(ast: &AST, interpreter: &Interpreter) -> AST {
match base_tp(ast.tp()) {
$(
$scalar => {
let aco=aco!($scalar, ast, Some(interpreter.alloc()));
let s=ato_str!(aco, aget!(aco, ast), interpreter);
new_string(&s, interpreter.alloc())
},
)*
$(
to_vec!($scalar) => {
let aco=aco!($scalar, ast, Some(interpreter.alloc()));
let v=ast.array::<atype!($scalar)>();
v.iter().map(|x| {
let s=ato_str!(aco, *x, interpreter);
new_string(&s, interpreter.alloc())
}).enlist(v.len(), interpreter.alloc())
}
)*
$(
to_deq!($scalar) => {
let aco=aco!($scalar, ast, Some(interpreter.alloc()));
let v=ast.vecdeq().head::<atype!($scalar)>();
v.iter().map(|x| {
let s=ato_str!(aco, *x, interpreter);
new_string(&s, interpreter.alloc())
}).enlist(v.len(), interpreter.alloc())
}
)*
x if is_nested(x) => atomic(ast, to_string, "to_string", interpreter),
VEC_CHAR => (*ast).clone(),
_ => except!(eval_err!("cast: nyi.")),
}
}
}
}
to_string!(
SC_BOOL,
SC_BYTE,
SC_SHORT,
SC_INT,
SC_MONTH,
SC_DATE,
SC_MINUTE,
SC_SECOND,
SC_TIME,
SC_LONG,
SC_TIMESTAMP,
SC_DATETIME,
SC_TIMESPAN,
SC_SINGLE,
SC_DOUBLE,
SC_ENUM,
SC_SYMBOL,
SC_GUID
);
All in all my rough estimate for macro efficiency ratio is something like 12x currently. That's about 12 times less code to type and support. YMMV, of course.
See https://danielkeep.github.io/tlborm/book/mbe-min-captures-and-expansion-redux.html for boring details on Rust macros.
BR,
Denis
More information about the fpc-pascal
mailing list