103 lines
2.9 KiB
Zig
103 lines
2.9 KiB
Zig
const std = @import("std");
|
|
const Allocator = mem.Allocator;
|
|
const mem = std.mem;
|
|
const ast = std.zig.ast;
|
|
const Visib = @import("visib.zig").Visib;
|
|
const event = std.event;
|
|
const Value = @import("value.zig").Value;
|
|
const Token = std.zig.Token;
|
|
const errmsg = @import("errmsg.zig");
|
|
const Scope = @import("scope.zig").Scope;
|
|
const Compilation = @import("compilation.zig").Compilation;
|
|
|
|
pub const Decl = struct {
|
|
id: Id,
|
|
name: []const u8,
|
|
visib: Visib,
|
|
resolution: event.Future(Compilation.BuildError!void),
|
|
parent_scope: *Scope,
|
|
|
|
// TODO when we destroy the decl, deref the tree scope
|
|
tree_scope: *Scope.AstTree,
|
|
|
|
pub const Table = std.StringHashMap(*Decl);
|
|
|
|
pub fn cast(base: *Decl, comptime T: type) ?*T {
|
|
if (base.id != @field(Id, @typeName(T))) return null;
|
|
return @fieldParentPtr(T, "base", base);
|
|
}
|
|
|
|
pub fn isExported(base: *const Decl, tree: *ast.Tree) bool {
|
|
switch (base.id) {
|
|
.Fn => {
|
|
const fn_decl = @fieldParentPtr(Fn, "base", base);
|
|
return fn_decl.isExported(tree);
|
|
},
|
|
else => return false,
|
|
}
|
|
}
|
|
|
|
pub fn getSpan(base: *const Decl) errmsg.Span {
|
|
switch (base.id) {
|
|
.Fn => {
|
|
const fn_decl = @fieldParentPtr(Fn, "base", base);
|
|
const fn_proto = fn_decl.fn_proto;
|
|
const start = fn_proto.fn_token;
|
|
const end = fn_proto.name_token orelse start;
|
|
return errmsg.Span{
|
|
.first = start,
|
|
.last = end + 1,
|
|
};
|
|
},
|
|
else => @panic("TODO"),
|
|
}
|
|
}
|
|
|
|
pub fn findRootScope(base: *const Decl) *Scope.Root {
|
|
return base.parent_scope.findRoot();
|
|
}
|
|
|
|
pub const Id = enum {
|
|
Var,
|
|
Fn,
|
|
CompTime,
|
|
};
|
|
|
|
pub const Var = struct {
|
|
base: Decl,
|
|
};
|
|
|
|
pub const Fn = struct {
|
|
base: Decl,
|
|
value: union(enum) {
|
|
Unresolved,
|
|
Fn: *Value.Fn,
|
|
FnProto: *Value.FnProto,
|
|
},
|
|
fn_proto: *ast.Node.FnProto,
|
|
|
|
pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 {
|
|
return if (self.fn_proto.extern_export_inline_token) |tok_index| x: {
|
|
const token = tree.tokens.at(tok_index);
|
|
break :x switch (token.id) {
|
|
.Extern => tree.tokenSlicePtr(token),
|
|
else => null,
|
|
};
|
|
} else null;
|
|
}
|
|
|
|
pub fn isExported(self: Fn, tree: *ast.Tree) bool {
|
|
if (self.fn_proto.extern_export_inline_token) |tok_index| {
|
|
const token = tree.tokens.at(tok_index);
|
|
return token.id == .Keyword_export;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
pub const CompTime = struct {
|
|
base: Decl,
|
|
};
|
|
};
|