feature. See also
. The project being documented here (as the example) is the Zig library itself.
Translator.transMacros
fn transMacros(t: *Translator) !void
File
Code
fn transMacros(t: *Translator) !void {
var tok_list: std.ArrayList(CToken) = .empty;
defer tok_list.deinit(t.gpa);
var pattern_list = try PatternList.init(t.gpa);
defer pattern_list.deinit(t.gpa);
for (t.pp.defines.keys(), t.pp.defines.values()) |name, macro| {
if (macro.isBuiltin()) continue;
if (t.global_scope.containsNow(name)) {
continue;
}
tok_list.items.len = 0;
try tok_list.ensureUnusedCapacity(t.gpa, macro.tokens.len);
for (macro.tokens) |tok| {
switch (tok.id) {
.invalid => continue,
.whitespace => continue,
.comment => continue,
.macro_ws => continue,
else => {},
}
tok_list.appendAssumeCapacity(tok);
}
if (macro.is_func) {
const ms: PatternList.MacroSlicer = .{
.tokens = tok_list.items,
.source = t.comp.getSource(macro.loc.id).buf,
.params = @intCast(macro.params.len),
};
if (try pattern_list.match(ms)) |impl| {
const decl = try ZigTag.pub_var_simple.create(t.arena, .{
.name = name,
.init = try t.createHelperCallNode(impl, null),
});
try t.addTopLevelDecl(name, decl);
continue;
}
}
if (t.checkTranslatableMacro(tok_list.items, macro.params)) |err| {
switch (err) {
.undefined_identifier => |ident| try t.failDeclExtra(&t.global_scope.base, macro.loc, name, "unable to translate macro: undefined identifier `{s}`", .{ident}),
.invalid_arg_usage => |ident| try t.failDeclExtra(&t.global_scope.base, macro.loc, name, "unable to translate macro: untranslatable usage of arg `{s}`", .{ident}),
}
continue;
}
var macro_translator: MacroTranslator = .{
.t = t,
.tokens = tok_list.items,
.source = t.comp.getSource(macro.loc.id).buf,
.name = name,
.macro = macro,
};
const res = if (macro.is_func)
macro_translator.transFnMacro()
else
macro_translator.transMacro();
res catch |err| switch (err) {
error.ParseError => continue,
error.OutOfMemory => |e| return e,
};
}
}