feature. See also
. The project being documented here (as the example) is the Zig library itself.
MacroTranslator.transMacro
pub fn transMacro(mt: *MacroTranslator) ParseError!void
File
Code
pub fn transMacro(mt: *MacroTranslator) ParseError!void {
const scope = &mt.t.global_scope.base;
while (true) {
switch (mt.peek()) {
.identifier, .extended_identifier => {
if (mt.t.global_scope.blank_macros.contains(mt.tokSlice())) {
mt.i += 1;
continue;
}
},
.eof, .nl => {
try mt.t.global_scope.blank_macros.put(mt.t.gpa, mt.name, {});
const init_node = try ZigTag.string_literal.create(mt.t.arena, "\"\"");
const var_decl = try ZigTag.pub_var_simple.create(mt.t.arena, .{ .name = mt.name, .init = init_node });
try mt.t.addTopLevelDecl(mt.name, var_decl);
return;
},
else => {},
}
break;
}
const init_node = try mt.parseCExpr(scope);
const last = mt.peek();
if (last != .eof)
return mt.fail("unable to translate C expr: unexpected token '{s}'", .{last.symbol()});
const node = node: {
const var_decl = try ZigTag.pub_var_simple.create(mt.t.arena, .{ .name = mt.name, .init = init_node });
if (mt.t.getFnProto(var_decl)) |proto_node| {
// the macro is intended to represent a function that assumes the function pointer
// variable is non-null and calls it.
break :node try mt.createMacroFn(mt.name, var_decl, proto_node);
} else if (mt.refs_var_decl) {
const return_type = try ZigTag.typeof.create(mt.t.arena, init_node);
const return_expr = try ZigTag.@"return".create(mt.t.arena, init_node);
const block = try ZigTag.block_single.create(mt.t.arena, return_expr);
const loc_str = try mt.t.locStr(mt.macro.loc);
const value = try std.fmt.allocPrint(mt.t.arena, "\n// {s}: warning: macro '{s}' contains a runtime value, translated to function", .{ loc_str, mt.name });
try scope.appendNode(try ZigTag.warning.create(mt.t.arena, value));
break :node try ZigTag.pub_inline_fn.create(mt.t.arena, .{
.name = mt.name,
.params = &.{},
.return_type = return_type,
.body = block,
});
}
break :node var_decl;
};
try mt.t.addTopLevelDecl(mt.name, node);
}