correctly resolve primitive types

This commit is contained in:
Techatrix 2023-01-20 19:20:42 +01:00
parent 34b2643b33
commit b4ac6142cf
3 changed files with 83 additions and 40 deletions

View File

@ -378,57 +378,59 @@ pub fn interpret(
.identifier => { .identifier => {
const value = offsets.nodeToSlice(tree, node_idx); const value = offsets.nodeToSlice(tree, node_idx);
if (std.mem.eql(u8, "bool", value)) { const simples = std.ComptimeStringMap(InternPool.Simple, .{
.{ "anyerror", .anyerror },
.{ "anyframe", .@"anyframe" },
.{ "anyopaque", .anyopaque },
.{ "bool", .bool },
.{ "c_int", .c_int },
.{ "c_long", .c_long },
.{ "c_longdouble", .c_longdouble },
.{ "c_longlong", .c_longlong },
.{ "c_short", .c_short },
.{ "c_uint", .c_uint },
.{ "c_ulong", .c_ulong },
.{ "c_ulonglong", .c_ulonglong },
.{ "c_ushort", .c_ushort },
.{ "comptime_float", .comptime_float },
.{ "comptime_int", .comptime_int },
.{ "f128", .f128 },
.{ "f16", .f16 },
.{ "f32", .f32 },
.{ "f64", .f64 },
.{ "f80", .f80 },
.{ "false", .bool_false },
.{ "isize", .isize },
.{ "noreturn", .noreturn },
.{ "null", .null_value },
.{ "true", .bool_true },
.{ "type", .type },
.{ "undefined", .undefined_value },
.{ "usize", .usize },
.{ "void", .void },
});
if (simples.get(value)) |simple| {
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }), .ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = simple.toType() }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }), .val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = simple }),
} }; } };
} else if (std.mem.eql(u8, "true", value)) { }
return InterpretResult{ .value = Value{
.interpreter = interpreter, if (value.len >= 2 and (value[0] == 'u' or value[0] == 'i')) blk: {
.node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true }),
} };
} else if (std.mem.eql(u8, "false", value)) {
return InterpretResult{ .value = Value{
.interpreter = interpreter,
.node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false }),
} };
} else if (std.mem.eql(u8, "usize", value) or std.mem.eql(u8, "isize", value)) {
return InterpretResult{ .value = Value{
.interpreter = interpreter,
.node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{
.simple = if (value[0] == 'u') .usize else .isize,
}),
} };
} else if (std.mem.eql(u8, "type", value)) {
return InterpretResult{ .value = Value{
.interpreter = interpreter,
.node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }),
} };
} else if (value.len >= 2 and (value[0] == 'u' or value[0] == 'i')) int: {
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }), .ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .int_type = .{ .val = try interpreter.ip.get(interpreter.allocator, IPKey{ .int_type = .{
.signedness = if (value[0] == 'u') .unsigned else .signed, .signedness = if (value[0] == 'u') .unsigned else .signed,
.bits = std.fmt.parseInt(u16, value[1..], 10) catch break :int, .bits = std.fmt.parseInt(u16, value[1..], 10) catch break :blk,
} }), } }),
} }; } };
} }
// TODO: Floats
// Logic to find identifiers in accessible scopes // Logic to find identifiers in accessible scopes
const decl = interpreter.huntItDown(namespace, value, options) catch |err| switch (err) { const decl = interpreter.huntItDown(namespace, value, options) catch |err| switch (err) {
error.IdentifierNotFound => |e| { error.IdentifierNotFound => |e| {

View File

@ -1052,6 +1052,48 @@ pub const Simple = enum(u32) {
null_value, null_value,
bool_true, bool_true,
bool_false, bool_false,
pub fn toType(self: Simple) Simple {
return switch (self) {
.f16,
.f32,
.f64,
.f80,
.f128,
.usize,
.isize,
.c_short,
.c_ushort,
.c_int,
.c_uint,
.c_long,
.c_ulong,
.c_longlong,
.c_ulonglong,
.c_longdouble,
.anyopaque,
.bool,
.void,
.type,
.anyerror,
.comptime_int,
.comptime_float,
.noreturn,
.@"anyframe",
.null_type,
.undefined_type,
.enum_literal_type,
=> .type,
// values
.undefined_value => .undefined_type,
.void_value => .void,
.unreachable_value => .noreturn,
.null_value => .null_type,
.bool_true => .bool,
.bool_false => .bool,
};
}
}; };
pub fn deinit(ip: *InternPool, gpa: Allocator) void { pub fn deinit(ip: *InternPool, gpa: Allocator) void {

View File

@ -18,11 +18,10 @@ test "ComptimeInterpreter - primitive types" {
// TODO try testExprCheck("-2", .{ .simple = .comptime_int }, .{ .int_i64_value = -2 }); // TODO try testExprCheck("-2", .{ .simple = .comptime_int }, .{ .int_i64_value = -2 });
try testExprCheck("3.0", .{ .simple = .comptime_float }, null); try testExprCheck("3.0", .{ .simple = .comptime_float }, null);
if (true) return error.SkipZigTest; // TODO
try testExprCheck("null", .{ .simple = .null_type }, .{ .simple = .null_value }); try testExprCheck("null", .{ .simple = .null_type }, .{ .simple = .null_value });
try testExprCheck("void", .{ .simple = .void }, .{ .simple = .void_value }); try testExprCheck("void", .{ .simple = .type }, .{ .simple = .void });
try testExprCheck("undefined", .{ .simple = .undefined_type }, .{ .simple = .undefined_value }); try testExprCheck("undefined", .{ .simple = .undefined_type }, .{ .simple = .undefined_value });
try testExprCheck("noreturn", .{ .simple = .noreturn }, .{ .simple = .unreachable_value }); try testExprCheck("noreturn", .{ .simple = .type }, .{ .simple = .noreturn });
} }
test "ComptimeInterpreter - expressions" { test "ComptimeInterpreter - expressions" {