Commit e0b01bd4a9
Changed files (5)
src-self-hosted
src-self-hosted/astgen.zig
@@ -130,6 +130,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
.ArrayType => return rlWrap(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
.ArrayTypeSentinel => return rlWrap(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
+ .EnumLiteral => return rlWrap(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)),
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
.Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
@@ -158,7 +159,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.ErrorType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorType", .{}),
.FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),
.AnyFrameType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyFrameType", .{}),
- .EnumLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .EnumLiteral", .{}),
.MultilineStringLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .MultilineStringLiteral", .{}),
.CharLiteral => return mod.failNode(scope, node, "TODO implement astgen.expr for .CharLiteral", .{}),
.ErrorSetDecl => return mod.failNode(scope, node, "TODO implement astgen.expr for .ErrorSetDecl", .{}),
@@ -527,6 +527,14 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti
}, .{});
}
+fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.name].start;
+ const name = try identifierTokenString(mod, scope, node.name);
+
+ return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{});
+}
+
fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.rtoken].start;
src-self-hosted/type.zig
@@ -75,6 +75,7 @@ pub const Type = extern union {
.optional_single_const_pointer,
.optional_single_mut_pointer,
=> return .Optional,
+ .enum_literal => return .EnumLiteral,
}
}
@@ -127,6 +128,7 @@ pub const Type = extern union {
if (zig_tag_a != zig_tag_b)
return false;
switch (zig_tag_a) {
+ .EnumLiteral => return true,
.Type => return true,
.Void => return true,
.Bool => return true,
@@ -211,7 +213,6 @@ pub const Type = extern union {
.Frame,
.AnyFrame,
.Vector,
- .EnumLiteral,
=> std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }),
}
}
@@ -327,6 +328,7 @@ pub const Type = extern union {
.fn_ccc_void_no_args,
.single_const_pointer_to_comptime_int,
.const_slice_u8,
+ .enum_literal,
=> unreachable,
.array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),
@@ -437,6 +439,7 @@ pub const Type = extern union {
.noreturn,
=> return out_stream.writeAll(@tagName(t)),
+ .enum_literal => return out_stream.writeAll("@TypeOf(.EnumLiteral)"),
.@"null" => return out_stream.writeAll("@TypeOf(null)"),
.@"undefined" => return out_stream.writeAll("@TypeOf(undefined)"),
@@ -561,6 +564,7 @@ pub const Type = extern union {
.fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
.single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
.const_slice_u8 => return Value.initTag(.const_slice_u8_type),
+ .enum_literal => return Value.initTag(.enum_literal_type),
else => {
const ty_payload = try allocator.create(Value.Payload.Ty);
ty_payload.* = .{ .ty = self };
@@ -625,6 +629,7 @@ pub const Type = extern union {
.noreturn,
.@"null",
.@"undefined",
+ .enum_literal,
=> false,
};
}
@@ -716,6 +721,7 @@ pub const Type = extern union {
.noreturn,
.@"null",
.@"undefined",
+ .enum_literal,
=> unreachable,
};
}
@@ -736,6 +742,7 @@ pub const Type = extern union {
.noreturn => unreachable,
.@"null" => unreachable,
.@"undefined" => unreachable,
+ .enum_literal => unreachable,
.u8,
.i8,
@@ -863,6 +870,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.single_const_pointer,
@@ -924,6 +932,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.const_slice_u8 => true,
@@ -980,6 +989,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.single_const_pointer,
@@ -1042,6 +1052,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
};
}
@@ -1147,6 +1158,7 @@ pub const Type = extern union {
.optional,
.optional_single_const_pointer,
.optional_single_mut_pointer,
+ .enum_literal,
=> unreachable,
.array => self.cast(Payload.Array).?.elem_type,
@@ -1252,6 +1264,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
.array => self.cast(Payload.Array).?.len,
@@ -1311,6 +1324,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
.array, .array_u8 => return null,
@@ -1368,6 +1382,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.int_signed,
@@ -1428,6 +1443,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.int_unsigned,
@@ -1478,6 +1494,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
.int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
@@ -1546,6 +1563,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
.usize,
@@ -1643,6 +1661,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
};
}
@@ -1706,6 +1725,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
}
}
@@ -1768,6 +1788,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
}
}
@@ -1830,6 +1851,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
};
}
@@ -1889,6 +1911,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
};
}
@@ -1948,6 +1971,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> unreachable,
};
}
@@ -2007,6 +2031,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> false,
};
}
@@ -2055,6 +2080,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> return null,
.void => return Value.initTag(.void_value),
@@ -2143,6 +2169,7 @@ pub const Type = extern union {
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
+ .enum_literal,
=> return false,
};
}
@@ -2186,6 +2213,7 @@ pub const Type = extern union {
comptime_int,
comptime_float,
noreturn,
+ enum_literal,
@"null",
@"undefined",
fn_noreturn_no_args,
src-self-hosted/value.zig
@@ -60,6 +60,7 @@ pub const Value = extern union {
fn_ccc_void_no_args_type,
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
+ enum_literal_type,
undef,
zero,
@@ -87,6 +88,7 @@ pub const Value = extern union {
float_32,
float_64,
float_128,
+ enum_literal,
pub const last_no_payload_tag = Tag.bool_false;
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
@@ -164,6 +166,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.undef,
.zero,
.void_value,
@@ -213,7 +216,7 @@ pub const Value = extern union {
};
return Value{ .ptr_otherwise = &new_payload.base };
},
- .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes),
+ .enum_literal, .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes),
.repeated => {
const payload = @fieldParentPtr(Payload.Repeated, "base", self.ptr_otherwise);
const new_payload = try allocator.create(Payload.Repeated);
@@ -285,6 +288,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
.single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
.const_slice_u8_type => return out_stream.writeAll("[]const u8"),
+ .enum_literal_type => return out_stream.writeAll("@TypeOf(.EnumLiteral)"),
.null_value => return out_stream.writeAll("null"),
.undef => return out_stream.writeAll("undefined"),
@@ -318,7 +322,7 @@ pub const Value = extern union {
val = elem_ptr.array_ptr;
},
.empty_array => return out_stream.writeAll(".{}"),
- .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream),
+ .enum_literal, .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream),
.repeated => {
try out_stream.writeAll("(repeated) ");
val = val.cast(Payload.Repeated).?.val;
@@ -391,6 +395,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
.single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
.const_slice_u8_type => Type.initTag(.const_slice_u8),
+ .enum_literal_type => Type.initTag(.enum_literal),
.undef,
.zero,
@@ -414,6 +419,7 @@ pub const Value = extern union {
.float_32,
.float_64,
.float_128,
+ .enum_literal,
=> unreachable,
};
}
@@ -462,6 +468,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -476,6 +483,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.undef => unreachable,
@@ -537,6 +545,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -551,6 +560,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.undef => unreachable,
@@ -612,6 +622,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -626,6 +637,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.undef => unreachable,
@@ -713,6 +725,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -728,6 +741,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.zero,
@@ -793,6 +807,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -807,6 +822,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.zero,
@@ -953,6 +969,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.bool_true,
.bool_false,
.null_value,
@@ -970,6 +987,7 @@ pub const Value = extern union {
.empty_array,
.void_value,
.unreachable_value,
+ .enum_literal,
=> unreachable,
.zero => false,
@@ -1025,6 +1043,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.null_value,
.function,
.ref_val,
@@ -1036,6 +1055,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.zero,
@@ -1102,6 +1122,11 @@ pub const Value = extern union {
}
pub fn eql(a: Value, b: Value) bool {
+ if (a.tag() == b.tag() and a.tag() == .enum_literal) {
+ const a_name = @fieldParentPtr(Payload.Bytes, "base", a.ptr_otherwise).data;
+ const b_name = @fieldParentPtr(Payload.Bytes, "base", b.ptr_otherwise).data;
+ return std.mem.eql(u8, a_name, b_name);
+ }
// TODO non numerical comparisons
return compare(a, .eq, b);
}
@@ -1151,6 +1176,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.zero,
.bool_true,
.bool_false,
@@ -1170,6 +1196,7 @@ pub const Value = extern union {
.void_value,
.unreachable_value,
.empty_array,
+ .enum_literal,
=> unreachable,
.ref_val => self.cast(Payload.RefVal).?.val,
@@ -1227,6 +1254,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.zero,
.bool_true,
.bool_false,
@@ -1246,6 +1274,7 @@ pub const Value = extern union {
.float_128,
.void_value,
.unreachable_value,
+ .enum_literal,
=> unreachable,
.empty_array => unreachable, // out of bounds array index
@@ -1320,6 +1349,7 @@ pub const Value = extern union {
.fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
+ .enum_literal_type,
.zero,
.empty_array,
.bool_true,
@@ -1339,6 +1369,7 @@ pub const Value = extern union {
.float_64,
.float_128,
.void_value,
+ .enum_literal,
=> false,
.undef => unreachable,
src-self-hosted/zir.zig
@@ -231,6 +231,8 @@ pub const Inst = struct {
unwrap_err_unsafe,
/// Takes a *E!T and raises a compiler error if T != void
ensure_err_payload_void,
+ /// Enum literal
+ enum_literal,
pub fn Type(tag: Tag) type {
return switch (tag) {
@@ -326,6 +328,7 @@ pub const Inst = struct {
.elemptr => ElemPtr,
.condbr => CondBr,
.ptr_type => PtrType,
+ .enum_literal => EnumLiteral,
};
}
@@ -410,6 +413,7 @@ pub const Inst = struct {
.unwrap_err_unsafe,
.ptr_type,
.ensure_err_payload_void,
+ .enum_literal,
=> false,
.@"break",
@@ -869,6 +873,16 @@ pub const Inst = struct {
},
kw_args: struct {},
};
+
+ pub const EnumLiteral = struct {
+ pub const base_tag = Tag.enum_literal;
+ base: Inst,
+
+ positionals: struct {
+ name: []const u8,
+ },
+ kw_args: struct {},
+ };
};
pub const ErrorMsg = struct {
src-self-hosted/zir_sema.zig
@@ -115,6 +115,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
.array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
.array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
+ .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
}
}
@@ -701,6 +702,18 @@ fn analyzeInstArrayTypeSentinel(mod: *Module, scope: *Scope, array: *zir.Inst.Ar
return mod.constType(scope, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));
}
+fn analyzeInstEnumLiteral(mod: *Module, scope: *Scope, inst: *zir.Inst.EnumLiteral) InnerError!*Inst {
+ const payload = try scope.arena().create(Value.Payload.Bytes);
+ payload.* = .{
+ .base = .{ .tag = .enum_literal },
+ .data = try scope.arena().dupe(u8, inst.positionals.name),
+ };
+ return mod.constInst(scope, inst.base.src, .{
+ .ty = Type.initTag(.enum_literal),
+ .val = Value.initPayload(&payload.base),
+ });
+}
+
fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp, safety_check: bool) InnerError!*Inst {
const operand = try resolveInst(mod, scope, unwrap.positionals.operand);
assert(operand.ty.zigTypeTag() == .Pointer);