Files
zig/deps/aro/pragmas/once.zig
Veikka Tuominen 5792570197 add Aro sources as a dependency
ref: 5688dbccfb58216468267a0f46b96bed7013715a
2023-10-01 23:51:54 +03:00

57 lines
1.8 KiB
Zig
Vendored

const std = @import("std");
const mem = std.mem;
const Compilation = @import("../Compilation.zig");
const Pragma = @import("../Pragma.zig");
const Diagnostics = @import("../Diagnostics.zig");
const Preprocessor = @import("../Preprocessor.zig");
const Parser = @import("../Parser.zig");
const TokenIndex = @import("../Tree.zig").TokenIndex;
const Source = @import("../Source.zig");
const Once = @This();
pragma: Pragma = .{
.afterParse = afterParse,
.deinit = deinit,
.preprocessorHandler = preprocessorHandler,
},
pragma_once: std.AutoHashMap(Source.Id, void),
preprocess_count: u32 = 0,
pub fn init(allocator: mem.Allocator) !*Pragma {
var once = try allocator.create(Once);
once.* = .{
.pragma_once = std.AutoHashMap(Source.Id, void).init(allocator),
};
return &once.pragma;
}
fn afterParse(pragma: *Pragma, _: *Compilation) void {
var self = @fieldParentPtr(Once, "pragma", pragma);
self.pragma_once.clearRetainingCapacity();
}
fn deinit(pragma: *Pragma, comp: *Compilation) void {
var self = @fieldParentPtr(Once, "pragma", pragma);
self.pragma_once.deinit();
comp.gpa.destroy(self);
}
fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pragma.Error!void {
var self = @fieldParentPtr(Once, "pragma", pragma);
const name_tok = pp.tokens.get(start_idx);
const next = pp.tokens.get(start_idx + 1);
if (next.id != .nl) {
try pp.comp.diag.add(.{
.tag = .extra_tokens_directive_end,
.loc = name_tok.loc,
}, next.expansionSlice());
}
const seen = self.preprocess_count == pp.preprocess_count;
const prev = try self.pragma_once.fetchPut(name_tok.loc.id, {});
if (prev != null and !seen) {
return error.StopPreprocessing;
}
self.preprocess_count = pp.preprocess_count;
}