feature. See also
. The project being documented here (as the example) is the Zig library itself.
PatternList.tokenizeMacro
fn tokenizeMacro(allocator: mem.Allocator, source: []const u8, tok_list: *std.ArrayList(CToken)) Error!MacroSlicer
File
Code
fn tokenizeMacro(allocator: mem.Allocator, source: []const u8, tok_list: *std.ArrayList(CToken)) Error!MacroSlicer {
var param_count: u32 = 0;
var param_buf: [8][]const u8 = undefined;
var tokenizer: aro.Tokenizer = .{
.buf = source,
.source = .unused,
.langopts = .{},
.splice_locs = &.{},
};
{
const name_tok = tokenizer.nextNoWS();
assert(name_tok.id == .identifier);
const l_paren = tokenizer.nextNoWS();
assert(l_paren.id == .l_paren);
}
while (true) {
const param = tokenizer.nextNoWS();
if (param.id == .r_paren) break;
assert(param.id == .identifier);
const slice = source[param.start..param.end];
param_buf[param_count] = slice;
param_count += 1;
const comma = tokenizer.nextNoWS();
if (comma.id == .r_paren) break;
assert(comma.id == .comma);
}
outer: while (true) {
const tok = tokenizer.next();
switch (tok.id) {
.whitespace, .comment => continue,
.identifier => {
const slice = source[tok.start..tok.end];
for (param_buf[0..param_count], 0..) |param, i| {
if (std.mem.eql(u8, param, slice)) {
try tok_list.append(allocator, .{
.id = .macro_param,
.source = .unused,
.end = @intCast(i),
});
continue :outer;
}
}
},
.hash_hash => {
if (tok_list.items[tok_list.items.len - 1].id == .macro_param) {
tok_list.items[tok_list.items.len - 1].id = .macro_param_no_expand;
}
},
.nl, .eof => break,
else => {},
}
try tok_list.append(allocator, tok);
}
return .{
.source = source,
.tokens = try tok_list.toOwnedSlice(allocator),
.params = param_count,
};
}