do not intern Structs, Enums and Unions
This commit is contained in:
parent
9131285db1
commit
55364f2e2b
@ -23,7 +23,6 @@ allocator: std.mem.Allocator,
|
||||
ip: InternPool = .{},
|
||||
document_store: *DocumentStore,
|
||||
uri: DocumentStore.Uri,
|
||||
decls: std.ArrayListUnmanaged(Decl) = .{},
|
||||
namespaces: std.MultiArrayList(Namespace) = .{},
|
||||
|
||||
/// Interpreter diagnostic errors
|
||||
@ -69,7 +68,6 @@ pub fn deinit(interpreter: *ComptimeInterpreter) void {
|
||||
interpreter.namespaces.items(.usingnamespaces)[i].deinit(interpreter.allocator);
|
||||
}
|
||||
interpreter.namespaces.deinit(interpreter.allocator);
|
||||
interpreter.decls.deinit(interpreter.allocator);
|
||||
}
|
||||
|
||||
pub const Type = struct {
|
||||
@ -86,29 +84,18 @@ pub const Value = struct {
|
||||
ty: Index,
|
||||
val: Index,
|
||||
};
|
||||
|
||||
pub const Decl = struct {
|
||||
name: []const u8,
|
||||
ty: Index,
|
||||
val: Index,
|
||||
alignment: u16,
|
||||
address_space: std.builtin.AddressSpace,
|
||||
is_pub: bool,
|
||||
is_exported: bool,
|
||||
};
|
||||
|
||||
// pub const Comptimeness = enum { @"comptime", runtime };
|
||||
|
||||
pub const NamespaceIndex = InternPool.NamespaceIndex;
|
||||
|
||||
pub const Namespace = struct {
|
||||
/// always points to Namespace or Index.none
|
||||
parent: NamespaceIndex,
|
||||
parent: Namespace.Index,
|
||||
node_idx: Ast.Node.Index,
|
||||
/// Will be a struct, enum, union, opaque or .none
|
||||
ty: Index,
|
||||
decls: std.StringArrayHashMapUnmanaged(Decl) = .{},
|
||||
usingnamespaces: std.ArrayListUnmanaged(NamespaceIndex) = .{},
|
||||
ty: InternPool.Index,
|
||||
decls: std.StringArrayHashMapUnmanaged(InternPool.DeclIndex) = .{},
|
||||
usingnamespaces: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{},
|
||||
|
||||
pub const Index = InternPool.NamespaceIndex;
|
||||
|
||||
// TODO: Actually use this value
|
||||
// comptimeness: Comptimeness,
|
||||
@ -161,15 +148,15 @@ pub const InterpretResult = union(enum) {
|
||||
|
||||
pub fn huntItDown(
|
||||
interpreter: *ComptimeInterpreter,
|
||||
namespace: NamespaceIndex,
|
||||
namespace: Namespace.Index,
|
||||
decl_name: []const u8,
|
||||
options: InterpretOptions,
|
||||
) ?Decl {
|
||||
) ?InternPool.DeclIndex {
|
||||
_ = options;
|
||||
|
||||
var current_namespace = namespace;
|
||||
while (current_namespace != .none) {
|
||||
const decls: std.StringArrayHashMapUnmanaged(Decl) = interpreter.namespaces.items(.decls)[@enumToInt(current_namespace)];
|
||||
const decls = interpreter.namespaces.items(.decls)[@enumToInt(current_namespace)];
|
||||
defer current_namespace = interpreter.namespaces.items(.parent)[@enumToInt(current_namespace)];
|
||||
|
||||
if (decls.get(decl_name)) |decl| {
|
||||
@ -199,7 +186,7 @@ pub const InterpretError = std.mem.Allocator.Error || std.fmt.ParseIntError || s
|
||||
pub fn interpret(
|
||||
interpreter: *ComptimeInterpreter,
|
||||
node_idx: Ast.Node.Index,
|
||||
namespace: NamespaceIndex,
|
||||
namespace: Namespace.Index,
|
||||
options: InterpretOptions,
|
||||
) InterpretError!InterpretResult {
|
||||
const tree = interpreter.getHandle().tree;
|
||||
@ -229,10 +216,16 @@ pub fn interpret(
|
||||
.node_idx = node_idx,
|
||||
.ty = undefined,
|
||||
});
|
||||
const container_namespace = @intToEnum(NamespaceIndex, interpreter.namespaces.len - 1);
|
||||
const container_namespace = @intToEnum(Namespace.Index, interpreter.namespaces.len - 1);
|
||||
|
||||
var fields = std.ArrayListUnmanaged(InternPool.Struct.Field){};
|
||||
defer fields.deinit(interpreter.allocator);
|
||||
const struct_index = try interpreter.ip.createStruct(interpreter.allocator, .{
|
||||
.fields = .{},
|
||||
.namespace = container_namespace,
|
||||
.layout = .Auto, // TODO
|
||||
.backing_int_ty = .none, // TODO
|
||||
.status = .none, // TODO
|
||||
});
|
||||
var struct_info = interpreter.ip.getStruct(struct_index);
|
||||
|
||||
var buffer: [2]Ast.Node.Index = undefined;
|
||||
|
||||
@ -259,28 +252,18 @@ pub fn interpret(
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const field_name = try interpreter.ip.get(interpreter.allocator, .{
|
||||
.bytes = tree.tokenSlice(container_field.ast.main_token),
|
||||
});
|
||||
const field: InternPool.Struct.Field = .{
|
||||
.name = field_name,
|
||||
|
||||
const field_name = tree.tokenSlice(container_field.ast.main_token);
|
||||
|
||||
try struct_info.fields.put(interpreter.allocator, field_name, .{
|
||||
.ty = init_type_value.val,
|
||||
.default_value = default_value,
|
||||
.alignment = 0, // TODO,
|
||||
.is_comptime = false, // TODO
|
||||
};
|
||||
|
||||
try fields.append(interpreter.allocator, field);
|
||||
});
|
||||
}
|
||||
|
||||
const struct_type = try interpreter.ip.get(interpreter.allocator, Key{
|
||||
.struct_type = .{
|
||||
.fields = fields.items,
|
||||
.namespace = namespace,
|
||||
.layout = .Auto, // TODO
|
||||
.backing_int_ty = .none, // TODO
|
||||
},
|
||||
});
|
||||
const struct_type = try interpreter.ip.get(interpreter.allocator, Key{ .struct_type = struct_index }); // TODO potential double free on struct_info.field
|
||||
interpreter.namespaces.items(.ty)[@enumToInt(container_namespace)] = struct_type;
|
||||
|
||||
return InterpretResult{ .value = Value{
|
||||
@ -317,7 +300,7 @@ pub fn interpret(
|
||||
if (v.ty != type_type) return InterpretResult{ .nothing = {} };
|
||||
}
|
||||
|
||||
try decls.putNoClobber(interpreter.allocator, name, .{
|
||||
const decl_index = try interpreter.ip.createDecl(interpreter.allocator, .{
|
||||
.name = name,
|
||||
.ty = if (type_value) |v| v.val else init_value.?.ty,
|
||||
.val = if (init_value) |init| init.val else .none,
|
||||
@ -326,6 +309,7 @@ pub fn interpret(
|
||||
.is_pub = true, // TODO
|
||||
.is_exported = false, // TODO
|
||||
});
|
||||
try decls.putNoClobber(interpreter.allocator, name, decl_index);
|
||||
|
||||
// TODO: Am I a dumbo shrimp? (e.g. is this tree shaking correct? works on my machine so like...)
|
||||
|
||||
@ -345,7 +329,7 @@ pub fn interpret(
|
||||
.node_idx = node_idx,
|
||||
.ty = .none,
|
||||
});
|
||||
const block_namespace = @intToEnum(NamespaceIndex, interpreter.namespaces.len - 1);
|
||||
const block_namespace = @intToEnum(Namespace.Index, interpreter.namespaces.len - 1);
|
||||
|
||||
var buffer: [2]Ast.Node.Index = undefined;
|
||||
const statements = ast.blockStatements(tree, node_idx, &buffer).?;
|
||||
@ -442,7 +426,8 @@ pub fn interpret(
|
||||
}
|
||||
|
||||
// Logic to find identifiers in accessible scopes
|
||||
if (interpreter.huntItDown(namespace, identifier, options)) |decl| {
|
||||
if (interpreter.huntItDown(namespace, identifier, options)) |decl_index| {
|
||||
const decl = interpreter.ip.getDecl(decl_index);
|
||||
return InterpretResult{ .value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
@ -478,7 +463,8 @@ pub fn interpret(
|
||||
if (irv.val == .none) break :blk true;
|
||||
|
||||
const ty_key = interpreter.ip.indexToKey(irv.val);
|
||||
if (interpreter.huntItDown(ty_key.getNamespace(), field_name, options)) |decl| {
|
||||
if (interpreter.huntItDown(ty_key.getNamespace(interpreter.ip), field_name, options)) |decl_index| {
|
||||
const decl = interpreter.ip.getDecl(decl_index);
|
||||
return InterpretResult{ .value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
@ -492,19 +478,18 @@ pub fn interpret(
|
||||
_ = error_set_info;
|
||||
},
|
||||
.union_type => {}, // TODO
|
||||
.enum_type => |enum_info| { // TODO
|
||||
if (interpreter.ip.contains(Key{ .bytes = field_name })) |field_name_index| {
|
||||
for (enum_info.fields) |field| {
|
||||
if (field.name != field_name_index) continue;
|
||||
return InterpretResult{
|
||||
.value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = data[node_idx].rhs,
|
||||
.ty = irv.val,
|
||||
.val = .none, // TODO resolve enum value
|
||||
},
|
||||
};
|
||||
}
|
||||
.enum_type => |enum_index| { // TODO
|
||||
const enum_info = interpreter.ip.getEnum(enum_index);
|
||||
if (enum_info.fields.get(field_name)) |field| {
|
||||
_ = field;
|
||||
return InterpretResult{
|
||||
.value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = data[node_idx].rhs,
|
||||
.ty = irv.val,
|
||||
.val = .none, // TODO resolve enum value
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
else => break :blk false,
|
||||
@ -583,17 +568,15 @@ pub fn interpret(
|
||||
} };
|
||||
}
|
||||
},
|
||||
.struct_type => |struct_info| blk: {
|
||||
// if the intern pool does not contain the field name, it is impossible that there is a field with the given name
|
||||
const field_name_index = interpreter.ip.contains(Key{ .bytes = field_name }) orelse break :blk true;
|
||||
|
||||
for (struct_info.fields) |field, i| {
|
||||
if (field.name != field_name_index) continue;
|
||||
.struct_type => |struct_index| blk: {
|
||||
const struct_info = interpreter.ip.getStruct(struct_index);
|
||||
if (struct_info.fields.getIndex(field_name)) |field_index| {
|
||||
const field = struct_info.fields.values()[field_index];
|
||||
const val = found_val: {
|
||||
if (irv.val == .none) break :found_val .none;
|
||||
const val_key = interpreter.ip.indexToKey(irv.val);
|
||||
if (val_key != .aggregate) break :found_val .none;
|
||||
break :found_val val_key.aggregate[i];
|
||||
break :found_val val_key.aggregate[field_index];
|
||||
};
|
||||
|
||||
return InterpretResult{ .value = Value{
|
||||
@ -813,15 +796,17 @@ pub fn interpret(
|
||||
|
||||
// TODO: Implement root support
|
||||
if (std.mem.eql(u8, import_str[1 .. import_str.len - 1], "root")) {
|
||||
const struct_index = try interpreter.ip.createStruct(interpreter.allocator, .{
|
||||
.fields = .{},
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = .none,
|
||||
.status = .none,
|
||||
});
|
||||
return InterpretResult{ .value = Value{
|
||||
.interpreter = interpreter,
|
||||
.node_idx = node_idx,
|
||||
.ty = try interpreter.ip.get(interpreter.allocator, Key{ .struct_type = .{
|
||||
.fields = &.{},
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = .none,
|
||||
} }),
|
||||
.ty = try interpreter.ip.get(interpreter.allocator, Key{ .struct_type = struct_index }),
|
||||
.val = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .undefined_value }),
|
||||
} };
|
||||
}
|
||||
@ -865,7 +850,7 @@ pub fn interpret(
|
||||
if (value.ty != type_type) return error.InvalidBuiltin;
|
||||
if (interpreter.ip.indexToKey(field_name.ty) != .pointer_type) return error.InvalidBuiltin; // Check if it's a []const u8
|
||||
|
||||
const value_namespace = interpreter.ip.indexToKey(value.val).getNamespace();
|
||||
const value_namespace = interpreter.ip.indexToKey(value.val).getNamespace(interpreter.ip);
|
||||
if (value_namespace == .none) return error.InvalidBuiltin;
|
||||
|
||||
const name = interpreter.ip.indexToKey(field_name.val).bytes; // TODO add checks
|
||||
@ -986,7 +971,8 @@ pub fn interpret(
|
||||
|
||||
if (namespace != .none) {
|
||||
const decls = &interpreter.namespaces.items(.decls)[@enumToInt(namespace)];
|
||||
try decls.put(interpreter.allocator, name, .{
|
||||
|
||||
const decl_index = try interpreter.ip.createDecl(interpreter.allocator, .{
|
||||
.name = name,
|
||||
.ty = type_type,
|
||||
.val = function_type,
|
||||
@ -995,6 +981,7 @@ pub fn interpret(
|
||||
.is_pub = false, // TODO
|
||||
.is_exported = false, // TODO
|
||||
});
|
||||
try decls.putNoClobber(interpreter.allocator, name, decl_index);
|
||||
}
|
||||
|
||||
return InterpretResult{ .nothing = {} };
|
||||
@ -1107,7 +1094,7 @@ pub fn interpret(
|
||||
}
|
||||
|
||||
pub const CallResult = struct {
|
||||
namespace: NamespaceIndex,
|
||||
namespace: Namespace.Index,
|
||||
result: union(enum) {
|
||||
value: Value,
|
||||
nothing,
|
||||
@ -1116,7 +1103,7 @@ pub const CallResult = struct {
|
||||
|
||||
pub fn call(
|
||||
interpreter: *ComptimeInterpreter,
|
||||
namespace: NamespaceIndex,
|
||||
namespace: Namespace.Index,
|
||||
func_node_idx: Ast.Node.Index,
|
||||
arguments: []const Value,
|
||||
options: InterpretOptions,
|
||||
@ -1136,7 +1123,7 @@ pub fn call(
|
||||
.node_idx = func_node_idx,
|
||||
.ty = .none,
|
||||
});
|
||||
const fn_namespace = @intToEnum(NamespaceIndex, interpreter.namespaces.len - 1);
|
||||
const fn_namespace = @intToEnum(Namespace.Index, interpreter.namespaces.len - 1);
|
||||
|
||||
const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
|
||||
|
||||
@ -1157,7 +1144,8 @@ pub fn call(
|
||||
if (param.name_token) |name_token| {
|
||||
const name = offsets.tokenToSlice(tree, name_token);
|
||||
|
||||
try interpreter.namespaces.items(.decls)[@enumToInt(fn_namespace)].put(interpreter.allocator, name, .{
|
||||
const decls = &interpreter.namespaces.items(.decls)[@enumToInt(fn_namespace)];
|
||||
const decl_index = try interpreter.ip.createDecl(interpreter.allocator, .{
|
||||
.name = name,
|
||||
.ty = tex.val,
|
||||
.val = arguments[arg_index].val,
|
||||
@ -1166,6 +1154,7 @@ pub fn call(
|
||||
.is_pub = true, // TODO
|
||||
.is_exported = false, // TODO
|
||||
});
|
||||
try decls.putNoClobber(interpreter.allocator, name, decl_index);
|
||||
arg_index += 1;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
|
||||
items: std.MultiArrayList(Item) = .{},
|
||||
extra: std.ArrayListUnmanaged(u8) = .{},
|
||||
|
||||
decls: std.ArrayListUnmanaged(InternPool.Decl) = .{},
|
||||
structs: std.ArrayListUnmanaged(InternPool.Struct) = .{},
|
||||
enums: std.ArrayListUnmanaged(InternPool.Enum) = .{},
|
||||
unions: std.ArrayListUnmanaged(InternPool.Union) = .{},
|
||||
|
||||
const InternPool = @This();
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
@ -36,15 +41,26 @@ pub const Array = packed struct {
|
||||
sentinel: Index = .none,
|
||||
};
|
||||
|
||||
pub const FieldStatus = enum {
|
||||
none,
|
||||
field_types_wip,
|
||||
have_field_types,
|
||||
layout_wip,
|
||||
have_layout,
|
||||
fully_resolved_wip,
|
||||
fully_resolved,
|
||||
};
|
||||
|
||||
pub const StructIndex = enum(u32) { _ };
|
||||
|
||||
pub const Struct = struct {
|
||||
fields: []const Field,
|
||||
fields: std.StringArrayHashMapUnmanaged(Field),
|
||||
namespace: NamespaceIndex,
|
||||
layout: std.builtin.Type.ContainerLayout = .Auto,
|
||||
backing_int_ty: Index,
|
||||
status: FieldStatus,
|
||||
|
||||
pub const Field = packed struct {
|
||||
/// guaranteed to be .bytes
|
||||
name: Index,
|
||||
ty: Index,
|
||||
default_value: Index = .none,
|
||||
alignment: u16 = 0,
|
||||
@ -66,17 +82,14 @@ pub const ErrorSet = struct {
|
||||
names: []const Index,
|
||||
};
|
||||
|
||||
pub const EnumIndex = enum(u32) { _ };
|
||||
|
||||
pub const Enum = struct {
|
||||
tag_type: Index,
|
||||
fields: []const Field,
|
||||
fields: std.StringArrayHashMapUnmanaged(void),
|
||||
values: std.AutoArrayHashMapUnmanaged(Index, void),
|
||||
namespace: NamespaceIndex,
|
||||
tag_type_infered: bool,
|
||||
|
||||
pub const Field = packed struct {
|
||||
/// guaranteed to be .bytes
|
||||
name: Index,
|
||||
val: Index,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Function = struct {
|
||||
@ -94,15 +107,16 @@ pub const Function = struct {
|
||||
is_var_args: bool = false,
|
||||
};
|
||||
|
||||
pub const UnionIndex = enum(u32) { _ };
|
||||
|
||||
pub const Union = struct {
|
||||
tag_type: Index,
|
||||
fields: []const Field,
|
||||
fields: std.StringArrayHashMapUnmanaged(Field),
|
||||
namespace: NamespaceIndex,
|
||||
layout: std.builtin.Type.ContainerLayout = .Auto,
|
||||
status: FieldStatus,
|
||||
|
||||
pub const Field = packed struct {
|
||||
/// guaranteed to be .bytes
|
||||
name: Index,
|
||||
ty: Index,
|
||||
alignment: u16,
|
||||
};
|
||||
@ -134,19 +148,34 @@ pub const UnionValue = packed struct {
|
||||
val: Index,
|
||||
};
|
||||
|
||||
pub const DeclIndex = enum(u32) { _ };
|
||||
|
||||
pub const Decl = struct {
|
||||
name: []const u8,
|
||||
ty: Index,
|
||||
val: Index,
|
||||
alignment: u16,
|
||||
address_space: std.builtin.AddressSpace,
|
||||
is_pub: bool,
|
||||
is_exported: bool,
|
||||
};
|
||||
|
||||
pub const Key = union(enum) {
|
||||
simple: Simple,
|
||||
|
||||
int_type: Int,
|
||||
pointer_type: Pointer,
|
||||
array_type: Array,
|
||||
struct_type: Struct,
|
||||
/// TODO consider *Struct instead of StructIndex
|
||||
struct_type: StructIndex,
|
||||
optional_type: Optional,
|
||||
error_union_type: ErrorUnion,
|
||||
error_set_type: ErrorSet,
|
||||
enum_type: Enum,
|
||||
/// TODO consider *Enum instead of EnumIndex
|
||||
enum_type: EnumIndex,
|
||||
function_type: Function,
|
||||
union_type: Union,
|
||||
/// TODO consider *Union instead of UnionIndex
|
||||
union_type: UnionIndex,
|
||||
tuple_type: Tuple,
|
||||
vector_type: Vector,
|
||||
anyframe_type: AnyFrame,
|
||||
@ -396,7 +425,8 @@ pub const Key = union(enum) {
|
||||
},
|
||||
.int_type => |int_info| return int_info,
|
||||
.enum_type => return panicOrElse("TODO", .{ .signedness = .unsigned, .bits = 0 }),
|
||||
.struct_type => |struct_info| {
|
||||
.struct_type => |struct_index| {
|
||||
const struct_info = ip.getStruct(struct_index);
|
||||
assert(struct_info.layout == .Packed);
|
||||
key = ip.indexToKey(struct_info.backing_int_ty);
|
||||
},
|
||||
@ -485,11 +515,11 @@ pub const Key = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getNamespace(ty: Key) NamespaceIndex {
|
||||
pub fn getNamespace(ty: Key, ip: InternPool) NamespaceIndex {
|
||||
return switch (ty) {
|
||||
.struct_type => |struct_info| struct_info.namespace,
|
||||
.enum_type => |enum_info| enum_info.namespace,
|
||||
.union_type => |union_info| union_info.namespace,
|
||||
.struct_type => |struct_index| ip.getStruct(struct_index).namespace,
|
||||
.enum_type => |enum_index| ip.getEnum(enum_index).namespace,
|
||||
.union_type => |union_index| ip.getUnion(union_index).namespace,
|
||||
else => .none,
|
||||
};
|
||||
}
|
||||
@ -555,10 +585,12 @@ pub const Key = union(enum) {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
.struct_type => |struct_info| {
|
||||
for (struct_info.fields) |field| {
|
||||
if (field.is_comptime) continue;
|
||||
if (ip.indexToKey(field.ty).onePossibleValue(ip) != null) continue;
|
||||
.struct_type => |struct_index| {
|
||||
const struct_info = ip.getStruct(struct_index);
|
||||
var field_it = struct_info.fields.iterator();
|
||||
while (field_it.next()) |entry| {
|
||||
if (entry.value_ptr.is_comptime) continue;
|
||||
if (ip.indexToKey(entry.value_ptr.ty).onePossibleValue(ip) != null) continue;
|
||||
return null;
|
||||
}
|
||||
return panicOrElse("TODO return empty struct value", null);
|
||||
@ -572,10 +604,11 @@ pub const Key = union(enum) {
|
||||
},
|
||||
.error_union_type => return null,
|
||||
.error_set_type => return null,
|
||||
.enum_type => |enum_info| {
|
||||
switch (enum_info.fields.len) {
|
||||
.enum_type => |enum_index| {
|
||||
const enum_info = ip.getEnum(enum_index);
|
||||
switch (enum_info.fields.count()) {
|
||||
0 => return Key{ .simple = .unreachable_value },
|
||||
1 => return ip.indexToKey(enum_info.fields[0].val),
|
||||
1 => return ip.indexToKey(enum_info.values.keys()[0]),
|
||||
else => return null,
|
||||
}
|
||||
},
|
||||
@ -623,11 +656,7 @@ pub const Key = union(enum) {
|
||||
ip: InternPool,
|
||||
};
|
||||
|
||||
// TODO implement options
|
||||
pub const FormatOptions = struct {
|
||||
include_fields: bool = true,
|
||||
include_declarations: bool = true,
|
||||
};
|
||||
pub const FormatOptions = struct {};
|
||||
|
||||
fn formatType(
|
||||
ctx: TypeFormatContext,
|
||||
@ -925,27 +954,27 @@ pub const Key = union(enum) {
|
||||
|
||||
.bytes => |bytes| try writer.print("\"{}\"", .{std.zig.fmtEscapes(bytes)}),
|
||||
.aggregate => |aggregate| {
|
||||
const struct_info = ip.indexToKey(ty).struct_type;
|
||||
assert(aggregate.len == struct_info.fields.len);
|
||||
const struct_info = ip.getStruct(ip.indexToKey(ty).struct_type);
|
||||
assert(aggregate.len == struct_info.fields.count());
|
||||
|
||||
try writer.writeAll(".{");
|
||||
var i: u32 = 0;
|
||||
while (i < aggregate.len) : (i += 1) {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
|
||||
const field_name = ip.indexToKey(struct_info.fields[i].name).bytes;
|
||||
const field_name = struct_info.fields.keys()[i];
|
||||
try writer.print(".{s} = ", .{field_name});
|
||||
try printValue(ip.indexToKey(aggregate[i]), struct_info.fields[i].ty, ip, writer);
|
||||
try printValue(ip.indexToKey(aggregate[i]), struct_info.fields.values()[i].ty, ip, writer);
|
||||
}
|
||||
try writer.writeByte('}');
|
||||
},
|
||||
.union_value => |union_value| {
|
||||
const union_info = ip.indexToKey(ty).union_type;
|
||||
const union_info = ip.getUnion(ip.indexToKey(ty).union_type);
|
||||
|
||||
const name = ip.indexToKey(union_info.fields[union_value.field_index].name).bytes;
|
||||
const name = union_info.fields.keys()[union_value.field_index];
|
||||
try writer.print(".{{ .{} = {} }}", .{
|
||||
std.zig.fmtId(name),
|
||||
union_value.val.fmtValue(union_info.fields[union_value.field_index].ty, ip),
|
||||
union_value.val.fmtValue(union_info.fields.values()[union_value.field_index].ty, ip),
|
||||
});
|
||||
},
|
||||
}
|
||||
@ -978,6 +1007,7 @@ pub const Item = struct {
|
||||
/// Two values which have the same type can be equality compared simply
|
||||
/// by checking if their indexes are equal, provided they are both in
|
||||
/// the same `InternPool`.
|
||||
/// TODO split this into an Optional and non-Optional Index
|
||||
pub const Index = enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
_,
|
||||
@ -1181,6 +1211,21 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
|
||||
ip.map.deinit(gpa);
|
||||
ip.items.deinit(gpa);
|
||||
ip.extra.deinit(gpa);
|
||||
|
||||
for (ip.structs.items) |*item| {
|
||||
item.fields.deinit(gpa);
|
||||
}
|
||||
for (ip.enums.items) |*item| {
|
||||
item.fields.deinit(gpa);
|
||||
item.values.deinit(gpa);
|
||||
}
|
||||
for (ip.unions.items) |*item| {
|
||||
item.fields.deinit(gpa);
|
||||
}
|
||||
ip.decls.deinit(gpa);
|
||||
ip.structs.deinit(gpa);
|
||||
ip.enums.deinit(gpa);
|
||||
ip.unions.deinit(gpa);
|
||||
}
|
||||
|
||||
pub fn indexToKey(ip: InternPool, index: Index) Key {
|
||||
@ -1199,17 +1244,18 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
|
||||
} },
|
||||
.type_pointer => .{ .pointer_type = ip.extraData(Pointer, data) },
|
||||
.type_array => .{ .array_type = ip.extraData(Array, data) },
|
||||
.type_struct => .{ .struct_type = ip.extraData(Struct, data) },
|
||||
.type_optional => .{ .optional_type = .{ .payload_type = @intToEnum(Index, data) } },
|
||||
.type_anyframe => .{ .anyframe_type = .{ .child = @intToEnum(Index, data) } },
|
||||
.type_error_union => .{ .error_union_type = ip.extraData(ErrorUnion, data) },
|
||||
.type_error_set => .{ .error_set_type = ip.extraData(ErrorSet, data) },
|
||||
.type_enum => .{ .enum_type = ip.extraData(Enum, data) },
|
||||
.type_function => .{ .function_type = ip.extraData(Function, data) },
|
||||
.type_union => .{ .union_type = ip.extraData(Union, data) },
|
||||
.type_tuple => .{ .tuple_type = ip.extraData(Tuple, data) },
|
||||
.type_vector => .{ .vector_type = ip.extraData(Vector, data) },
|
||||
|
||||
.type_struct => .{ .struct_type = @intToEnum(StructIndex, data) },
|
||||
.type_enum => .{ .enum_type = @intToEnum(EnumIndex, data) },
|
||||
.type_union => .{ .union_type = @intToEnum(UnionIndex, data) },
|
||||
|
||||
.int_u32 => .{ .int_u64_value = @intCast(u32, data) },
|
||||
.int_i32 => .{ .int_i64_value = @bitCast(i32, data) },
|
||||
.int_u64 => .{ .int_u64_value = ip.extraData(u64, data) },
|
||||
@ -1248,6 +1294,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
||||
.optional_type => |optional_ty| @enumToInt(optional_ty.payload_type),
|
||||
.anyframe_type => |anyframe_ty| @enumToInt(anyframe_ty.child),
|
||||
|
||||
.struct_type => |struct_index| @enumToInt(struct_index),
|
||||
.enum_type => |enum_index| @enumToInt(enum_index),
|
||||
.union_type => |union_index| @enumToInt(union_index),
|
||||
|
||||
.int_u64_value => |int_val| if (tag == .int_u32) @intCast(u32, int_val) else try ip.addExtra(gpa, int_val),
|
||||
.int_i64_value => |int_val| if (tag == .int_i32) @bitCast(u32, @intCast(u32, int_val)) else try ip.addExtra(gpa, int_val),
|
||||
.int_big_value => |big_int_val| try ip.addExtra(gpa, big_int_val.limbs),
|
||||
@ -1270,6 +1320,36 @@ pub fn contains(ip: InternPool, key: Key) ?Index {
|
||||
return @intToEnum(Index, index);
|
||||
}
|
||||
|
||||
pub fn getDecl(ip: *InternPool, index: InternPool.DeclIndex) *InternPool.Decl {
|
||||
return &ip.decls.items[@enumToInt(index)];
|
||||
}
|
||||
pub fn getStruct(ip: InternPool, index: InternPool.StructIndex) *InternPool.Struct {
|
||||
return &ip.structs.items[@enumToInt(index)];
|
||||
}
|
||||
pub fn getEnum(ip: InternPool, index: InternPool.EnumIndex) *InternPool.Enum {
|
||||
return &ip.enums.items[@enumToInt(index)];
|
||||
}
|
||||
pub fn getUnion(ip: InternPool, index: InternPool.UnionIndex) *InternPool.Union {
|
||||
return &ip.unions.items[@enumToInt(index)];
|
||||
}
|
||||
|
||||
pub fn createDecl(ip: *InternPool, gpa: Allocator, decl: InternPool.Decl) error{OutOfMemory}!InternPool.DeclIndex {
|
||||
try ip.decls.append(gpa, decl);
|
||||
return @intToEnum(InternPool.DeclIndex, ip.decls.items.len - 1);
|
||||
}
|
||||
pub fn createStruct(ip: *InternPool, gpa: Allocator, struct_info: InternPool.Struct) error{OutOfMemory}!InternPool.StructIndex {
|
||||
try ip.structs.append(gpa, struct_info);
|
||||
return @intToEnum(InternPool.StructIndex, ip.structs.items.len - 1);
|
||||
}
|
||||
pub fn createEnum(ip: *InternPool, gpa: Allocator, enum_info: InternPool.Enum) error{OutOfMemory}!InternPool.EnumIndex {
|
||||
try ip.enums.append(gpa, enum_info);
|
||||
return @intToEnum(InternPool.EnumIndex, ip.enums.items.len - 1);
|
||||
}
|
||||
pub fn createUnion(ip: *InternPool, gpa: Allocator, union_info: InternPool.Union) error{OutOfMemory}!InternPool.UnionIndex {
|
||||
try ip.unions.append(gpa, union_info);
|
||||
return @intToEnum(InternPool.UnionIndex, ip.unions.items.len - 1);
|
||||
}
|
||||
|
||||
fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
|
||||
const T = @TypeOf(extra);
|
||||
comptime if (@sizeOf(T) <= 4) {
|
||||
@ -2997,41 +3077,6 @@ test "array type" {
|
||||
try testExpectFmtType(ip, u32_0_0_array_type, "[3:0]u32");
|
||||
}
|
||||
|
||||
test "struct type" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
var ip: InternPool = .{};
|
||||
defer ip.deinit(gpa);
|
||||
|
||||
const i32_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .signed, .bits = 32 } });
|
||||
const u64_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .unsigned, .bits = 64 } });
|
||||
const bool_type = try ip.get(gpa, .{ .simple = .bool });
|
||||
|
||||
const foo_name = try ip.get(gpa, .{ .bytes = "foo" });
|
||||
const bar_name = try ip.get(gpa, .{ .bytes = "bar" });
|
||||
const baz_name = try ip.get(gpa, .{ .bytes = "baz" });
|
||||
|
||||
const field1 = Struct.Field{ .name = foo_name, .ty = u64_type };
|
||||
const field2 = Struct.Field{ .name = bar_name, .ty = i32_type };
|
||||
const field3 = Struct.Field{ .name = baz_name, .ty = bool_type };
|
||||
|
||||
const struct_type_0 = try ip.get(gpa, .{ .struct_type = .{
|
||||
.fields = &.{ field1, field2, field3 },
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = .none,
|
||||
} });
|
||||
|
||||
const struct_type_1 = try ip.get(gpa, .{ .struct_type = .{
|
||||
.fields = &.{ field1, field2, field3 },
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = .none,
|
||||
} });
|
||||
|
||||
try std.testing.expect(struct_type_0 == struct_type_1);
|
||||
}
|
||||
|
||||
test "struct value" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
@ -3041,18 +3086,17 @@ test "struct value" {
|
||||
const i32_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .signed, .bits = 32 } });
|
||||
const bool_type = try ip.get(gpa, .{ .simple = .bool });
|
||||
|
||||
const foo_name = try ip.get(gpa, .{ .bytes = "foo" });
|
||||
const bar_name = try ip.get(gpa, .{ .bytes = "bar" });
|
||||
|
||||
const field1 = Struct.Field{ .name = foo_name, .ty = i32_type };
|
||||
const field2 = Struct.Field{ .name = bar_name, .ty = bool_type };
|
||||
|
||||
const struct_type = try ip.get(gpa, .{ .struct_type = .{
|
||||
.fields = &.{ field1, field2 },
|
||||
const struct_index = try ip.createStruct(gpa, .{
|
||||
.fields = .{},
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.backing_int_ty = .none,
|
||||
} });
|
||||
.status = .none,
|
||||
});
|
||||
const struct_type = try ip.get(gpa, .{ .struct_type = struct_index });
|
||||
const struct_info = ip.getStruct(struct_index);
|
||||
try struct_info.fields.put(gpa, "foo", .{ .ty = i32_type });
|
||||
try struct_info.fields.put(gpa, "bar", .{ .ty = bool_type });
|
||||
|
||||
const one_value = try ip.get(gpa, .{ .int_i64_value = 1 });
|
||||
const true_value = try ip.get(gpa, .{ .simple = .bool_true });
|
||||
@ -3062,50 +3106,6 @@ test "struct value" {
|
||||
try ip.testExpectFmtValue(aggregate_value, struct_type, ".{.foo = 1, .bar = true}");
|
||||
}
|
||||
|
||||
test "enum type" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
var ip: InternPool = .{};
|
||||
defer ip.deinit(gpa);
|
||||
|
||||
const zig_name = try ip.get(gpa, .{ .bytes = "zig" });
|
||||
const cpp_name = try ip.get(gpa, .{ .bytes = "cpp" });
|
||||
|
||||
const empty_enum1 = try ip.get(gpa, .{ .enum_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{},
|
||||
.namespace = .none,
|
||||
.tag_type_infered = true,
|
||||
} });
|
||||
|
||||
const empty_enum2 = try ip.get(gpa, .{ .enum_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{},
|
||||
.namespace = .none,
|
||||
.tag_type_infered = true,
|
||||
} });
|
||||
|
||||
const field1 = Enum.Field{ .name = zig_name, .val = .none };
|
||||
const field2 = Enum.Field{ .name = cpp_name, .val = .none };
|
||||
|
||||
const enum1 = try ip.get(gpa, .{ .enum_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{ field1, field2 },
|
||||
.namespace = .none,
|
||||
.tag_type_infered = true,
|
||||
} });
|
||||
const enum2 = try ip.get(gpa, .{ .enum_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{ field2, field1 },
|
||||
.namespace = .none,
|
||||
.tag_type_infered = true,
|
||||
} });
|
||||
|
||||
try std.testing.expect(empty_enum1 == empty_enum2);
|
||||
try std.testing.expect(empty_enum2 != enum1);
|
||||
try std.testing.expect(enum1 != enum2);
|
||||
}
|
||||
|
||||
test "function type" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
@ -3152,40 +3152,6 @@ test "function type" {
|
||||
try testExpectFmtType(ip, @"fn() align(4) callconv(.C) type", "fn() align(4) callconv(.C) type");
|
||||
}
|
||||
|
||||
test "union type" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
var ip: InternPool = .{};
|
||||
defer ip.deinit(gpa);
|
||||
|
||||
const u32_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .unsigned, .bits = 32 } });
|
||||
const void_type = try ip.get(gpa, .{ .simple = .void });
|
||||
|
||||
const ok_name = try ip.get(gpa, .{ .bytes = "Ok" });
|
||||
const err_name = try ip.get(gpa, .{ .bytes = "Err" });
|
||||
|
||||
var field1 = Union.Field{ .name = ok_name, .ty = u32_type, .alignment = 0 };
|
||||
var field2 = Union.Field{ .name = err_name, .ty = void_type, .alignment = 0 };
|
||||
|
||||
const union_type1 = try ip.get(gpa, .{
|
||||
.union_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{ field1, field2 },
|
||||
.namespace = .none,
|
||||
},
|
||||
});
|
||||
|
||||
const union_type2 = try ip.get(gpa, .{
|
||||
.union_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{ field2, field1 },
|
||||
.namespace = .none,
|
||||
},
|
||||
});
|
||||
|
||||
try std.testing.expect(union_type1 != union_type2);
|
||||
}
|
||||
|
||||
test "union value" {
|
||||
const gpa = std.testing.allocator;
|
||||
|
||||
@ -3198,19 +3164,17 @@ test "union value" {
|
||||
const int_value = try ip.get(gpa, .{ .int_u64_value = 1 });
|
||||
const f16_value = try ip.get(gpa, .{ .float_16_value = 0.25 });
|
||||
|
||||
const int_name = try ip.get(gpa, .{ .bytes = "int" });
|
||||
const float_name = try ip.get(gpa, .{ .bytes = "float" });
|
||||
|
||||
var field1 = Union.Field{ .name = int_name, .ty = u32_type, .alignment = 0 };
|
||||
var field2 = Union.Field{ .name = float_name, .ty = f16_type, .alignment = 0 };
|
||||
|
||||
const union_type = try ip.get(gpa, .{
|
||||
.union_type = .{
|
||||
.tag_type = .none,
|
||||
.fields = &.{ field1, field2 },
|
||||
.namespace = .none,
|
||||
},
|
||||
const union_index = try ip.createUnion(gpa, .{
|
||||
.tag_type = .none,
|
||||
.fields = .{},
|
||||
.namespace = .none,
|
||||
.layout = .Auto,
|
||||
.status = .none,
|
||||
});
|
||||
const union_type = try ip.get(gpa, .{ .union_type = union_index });
|
||||
const union_info = ip.getUnion(union_index);
|
||||
try union_info.fields.put(gpa, "int", .{ .ty = u32_type, .alignment = 0 });
|
||||
try union_info.fields.put(gpa, "float", .{ .ty = f16_type, .alignment = 0 });
|
||||
|
||||
const union_value1 = try ip.get(gpa, .{ .union_value = .{
|
||||
.field_index = 0,
|
||||
|
@ -24,7 +24,7 @@ pub fn dotCompletions(
|
||||
.simple => |simple| switch (simple) {
|
||||
.type => {
|
||||
const ty_key = ip.indexToKey(val);
|
||||
const namespace = ty_key.getNamespace();
|
||||
const namespace = ty_key.getNamespace(ip.*);
|
||||
if (namespace != .none) {
|
||||
// TODO lookup in namespace
|
||||
}
|
||||
@ -40,11 +40,12 @@ pub fn dotCompletions(
|
||||
}
|
||||
},
|
||||
.union_type => {}, // TODO
|
||||
.enum_type => |enum_info| {
|
||||
for (enum_info.fields) |field| {
|
||||
const field_name = ip.indexToKey(field.name).bytes;
|
||||
.enum_type => |enum_index| {
|
||||
const enum_info = ip.getEnum(enum_index);
|
||||
var field_it = enum_info.fields.iterator();
|
||||
while (field_it.next()) |entry| {
|
||||
try completions.append(arena, .{
|
||||
.label = field_name,
|
||||
.label = entry.key_ptr.*,
|
||||
.kind = .Constant,
|
||||
// include field.val?
|
||||
});
|
||||
@ -85,14 +86,15 @@ pub fn dotCompletions(
|
||||
.detail = try std.fmt.allocPrint(arena, "usize ({d})", .{array_info.len}), // TODO how should this be displayed
|
||||
});
|
||||
},
|
||||
.struct_type => |struct_info| {
|
||||
for (struct_info.fields) |field| {
|
||||
const field_name = ip.indexToKey(field.name).bytes;
|
||||
.struct_type => |struct_index| {
|
||||
const struct_info = ip.getStruct(struct_index);
|
||||
var field_it = struct_info.fields.iterator();
|
||||
while (field_it.next()) |entry| {
|
||||
try completions.append(arena, types.CompletionItem{
|
||||
.label = field_name,
|
||||
.label = entry.key_ptr.*,
|
||||
.kind = .Field,
|
||||
// TODO include alignment and comptime
|
||||
.detail = try std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip.*)}),
|
||||
.detail = try std.fmt.allocPrint(arena, "{}", .{entry.value_ptr.ty.fmtType(ip.*)}),
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -103,26 +105,28 @@ pub fn dotCompletions(
|
||||
.detail = try std.fmt.allocPrint(arena, "{}", .{optional_info.payload_type.fmtType(ip.*)}),
|
||||
});
|
||||
},
|
||||
.enum_type => |enum_info| {
|
||||
for (enum_info.fields) |field| {
|
||||
const field_name = ip.indexToKey(field.name).bytes;
|
||||
.enum_type => |enum_index| {
|
||||
const enum_info = ip.getEnum(enum_index);
|
||||
for (enum_info.fields.keys()) |field_name, i| {
|
||||
const field_val = enum_info.values.keys()[i];
|
||||
try completions.append(arena, .{
|
||||
.label = field_name,
|
||||
.kind = .Field,
|
||||
.detail = try std.fmt.allocPrint(arena, "{}", .{field.val.fmtValue(enum_info.tag_type, ip.*)}),
|
||||
.detail = try std.fmt.allocPrint(arena, "{}", .{field_val.fmtValue(enum_info.tag_type, ip.*)}),
|
||||
});
|
||||
}
|
||||
},
|
||||
.union_type => |union_info| {
|
||||
for (union_info.fields) |field| {
|
||||
const field_name = ip.indexToKey(field.name).bytes;
|
||||
.union_type => |union_index| {
|
||||
const union_info = ip.getUnion(union_index);
|
||||
var field_it = union_info.fields.iterator();
|
||||
while (field_it.next()) |entry| {
|
||||
try completions.append(arena, .{
|
||||
.label = field_name,
|
||||
.label = entry.key_ptr.*,
|
||||
.kind = .Field,
|
||||
.detail = if (field.alignment != 0)
|
||||
try std.fmt.allocPrint(arena, "align({d}) {}", .{ field.alignment, field.ty.fmtType(ip.*) })
|
||||
.detail = if (entry.value_ptr.alignment != 0)
|
||||
try std.fmt.allocPrint(arena, "align({d}) {}", .{ entry.value_ptr.alignment, entry.value_ptr.ty.fmtType(ip.*) })
|
||||
else
|
||||
try std.fmt.allocPrint(arena, "{}", .{field.ty.fmtType(ip.*)}),
|
||||
try std.fmt.allocPrint(arena, "{}", .{entry.value_ptr.ty.fmtType(ip.*)}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -772,7 +772,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
|
||||
};
|
||||
var interpreter: *ComptimeInterpreter = handle.interpreter.?;
|
||||
|
||||
const root_namespace = @intToEnum(ComptimeInterpreter.NamespaceIndex, 0);
|
||||
const root_namespace = @intToEnum(ComptimeInterpreter.Namespace.Index, 0);
|
||||
|
||||
// TODO: Start from current/nearest-current scope
|
||||
const result = interpreter.interpret(node, root_namespace, .{}) catch |err| {
|
||||
|
@ -169,16 +169,15 @@ test "ComptimeInterpreter - call return struct" {
|
||||
|
||||
try std.testing.expect(result.ty == .simple);
|
||||
try std.testing.expect(result.ty.simple == .type);
|
||||
const struct_info = result.val.?.struct_type;
|
||||
const struct_info = context.interpreter.ip.getStruct(result.val.?.struct_type);
|
||||
try std.testing.expectEqual(Index.none, struct_info.backing_int_ty);
|
||||
try std.testing.expectEqual(std.builtin.Type.ContainerLayout.Auto, struct_info.layout);
|
||||
|
||||
const field_name = context.interpreter.ip.indexToKey(struct_info.fields[0].name).bytes;
|
||||
const bool_type = try context.interpreter.ip.get(allocator, .{ .simple = .bool });
|
||||
|
||||
try std.testing.expectEqual(@as(usize, 1), struct_info.fields.len);
|
||||
try std.testing.expectEqualStrings("slay", field_name);
|
||||
try std.testing.expect(struct_info.fields[0].ty == bool_type);
|
||||
try std.testing.expectEqual(@as(usize, 1), struct_info.fields.count());
|
||||
try std.testing.expectEqualStrings("slay", struct_info.fields.keys()[0]);
|
||||
try std.testing.expect(struct_info.fields.values()[0].ty == bool_type);
|
||||
}
|
||||
|
||||
test "ComptimeInterpreter - call comptime argument" {
|
||||
@ -284,7 +283,7 @@ const Context = struct {
|
||||
};
|
||||
}
|
||||
|
||||
const namespace = @intToEnum(ComptimeInterpreter.NamespaceIndex, 0); // root namespace
|
||||
const namespace = @intToEnum(ComptimeInterpreter.Namespace.Index, 0); // root namespace
|
||||
const result = (try self.interpreter.call(namespace, func_node, args, .{})).result;
|
||||
|
||||
try std.testing.expect(result == .value);
|
||||
@ -297,7 +296,7 @@ const Context = struct {
|
||||
}
|
||||
|
||||
pub fn interpret(self: *Context, node: Ast.Node.Index) !KV {
|
||||
const namespace = @intToEnum(ComptimeInterpreter.NamespaceIndex, 0); // root namespace
|
||||
const namespace = @intToEnum(ComptimeInterpreter.Namespace.Index, 0); // root namespace
|
||||
const result = try (try self.interpreter.interpret(node, namespace, .{})).getValue();
|
||||
|
||||
try std.testing.expect(result.ty != .none);
|
||||
|
Loading…
Reference in New Issue
Block a user