From 5fdcb1a792e271c67f3aec36f8aca9e6c5503013 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 19 Aug 2020 19:12:01 +0300 Subject: [PATCH] stage2: emit zir variable fix, array type and enum literal support --- src-self-hosted/value.zig | 11 ++++++- src-self-hosted/zir.zig | 65 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index 7bebd022ab..95a0746e19 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -218,7 +218,7 @@ pub const Value = extern union { }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .enum_literal, .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), + .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); @@ -232,6 +232,15 @@ pub const Value = extern union { .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32), .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64), .float_128 => return self.copyPayloadShallow(allocator, Payload.Float_128), + .enum_literal => { + const payload = @fieldParentPtr(Payload.Bytes, "base", self.ptr_otherwise); + const new_payload = try allocator.create(Payload.Bytes); + new_payload.* = .{ + .base = payload.base, + .data = try allocator.dupe(u8, payload.data), + }; + return Value{ .ptr_otherwise = &new_payload.base }; + }, } } diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index f59d470ffd..384463caee 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -1878,6 +1878,11 @@ const EmitZIR = struct { if (typed_value.val.cast(Value.Payload.DeclRef)) |decl_ref| { const decl = decl_ref.decl; return try self.emitUnnamedDecl(try self.emitDeclRef(src, decl)); + } else if (typed_value.val.cast(Value.Payload.Variable)) |variable| { + return self.emitTypedValue(src, .{ + .ty = typed_value.ty, + .val = variable.variable.value.?, + }); } if (typed_value.val.isUndef()) { const as_inst = try self.arena.allocator.create(Inst.BinOp); @@ -1967,6 +1972,21 @@ const EmitZIR = struct { return self.emitPrimitive(src, .@"true") else return self.emitPrimitive(src, .@"false"), + .EnumLiteral => { + const enum_literal = @fieldParentPtr(Value.Payload.Bytes, "base", typed_value.val.ptr_otherwise); + const inst = try self.arena.allocator.create(Inst.Str); + inst.* = .{ + .base = .{ + .src = src, + .tag = .enum_literal, + }, + .positionals = .{ + .bytes = enum_literal.data, + }, + .kw_args = .{}, + }; + return self.emitUnnamedDecl(&inst.base); + }, else => |t| std.debug.panic("TODO implement emitTypedValue for {}", .{@tagName(t)}), } } @@ -2437,6 +2457,51 @@ const EmitZIR = struct { }; return self.emitUnnamedDecl(&inst.base); }, + .Array => { + var len_pl = Value.Payload.Int_u64{ .int = ty.arrayLen() }; + const len = Value.initPayload(&len_pl.base); + + const inst = if (ty.arraySentinel()) |sentinel| blk: { + const inst = try self.arena.allocator.create(Inst.ArrayTypeSentinel); + inst.* = .{ + .base = .{ + .src = src, + .tag = .array_type, + }, + .positionals = .{ + .len = (try self.emitTypedValue(src, .{ + .ty = Type.initTag(.usize), + .val = len, + })).inst, + .sentinel = (try self.emitTypedValue(src, .{ + .ty = ty.elemType(), + .val = sentinel, + })).inst, + .elem_type = (try self.emitType(src, ty.elemType())).inst, + }, + .kw_args = .{}, + }; + break :blk &inst.base; + } else blk: { + const inst = try self.arena.allocator.create(Inst.BinOp); + inst.* = .{ + .base = .{ + .src = src, + .tag = .array_type, + }, + .positionals = .{ + .lhs = (try self.emitTypedValue(src, .{ + .ty = Type.initTag(.usize), + .val = len, + })).inst, + .rhs = (try self.emitType(src, ty.elemType())).inst, + }, + .kw_args = .{}, + }; + break :blk &inst.base; + }; + return self.emitUnnamedDecl(inst); + }, else => std.debug.panic("TODO implement emitType for {}", .{ty}), }, }