Commit c52513e25b

Vexu <git@vexu.eu>
2020-08-14 16:39:18
stage2: astgen for ptr types and address of
1 parent 8d8d568
Changed files (3)
src-self-hosted/astgen.zig
@@ -113,6 +113,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
         .Period => return rlWrap(mod, scope, rl, try field(mod, scope, node.castTag(.Period).?)),
         .Deref => return rlWrap(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
         .BoolNot => return rlWrap(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
+        .AddressOf => return rlWrap(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
         .FloatLiteral => return rlWrap(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
         .UndefinedLiteral => return rlWrap(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
         .BoolLiteral => return rlWrap(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),
@@ -122,6 +123,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
         .Block => return rlWrapVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),
         .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?),
         .Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
+        .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
 
         .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
         .Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
@@ -131,7 +133,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
         .MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}),
         .Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),
         .OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),
-        .AddressOf => return mod.failNode(scope, node, "TODO implement astgen.expr for .AddressOf", .{}),
         .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
         .BitNot => return mod.failNode(scope, node, "TODO implement astgen.expr for .BitNot", .{}),
         .Negation => return mod.failNode(scope, node, "TODO implement astgen.expr for .Negation", .{}),
@@ -140,7 +141,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
         .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
         .ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}),
         .ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}),
-        .PtrType => return mod.failNode(scope, node, "TODO implement astgen.expr for .PtrType", .{}),
         .SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
         .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
         .ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),
@@ -452,6 +452,12 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
     return addZIRUnOp(mod, scope, src, .boolnot, operand);
 }
 
+fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
+    const tree = scope.tree();
+    const src = tree.token_locs[node.op_token].start;
+    return expr(mod, scope, .lvalue, node.rhs);
+}
+
 fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
     const tree = scope.tree();
     const src = tree.token_locs[node.op_token].start;
@@ -463,6 +469,47 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn
     return addZIRUnOp(mod, scope, src, .optional_type, operand);
 }
 
+fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst {
+    const tree = scope.tree();
+    const src = tree.token_locs[node.op_token].start;
+    const meta_type = try addZIRInstConst(mod, scope, src, .{
+        .ty = Type.initTag(.type),
+        .val = Value.initTag(.type_type),
+    });
+
+    const simple = node.ptr_info.allowzero_token == null and
+        node.ptr_info.align_info == null and
+        node.ptr_info.volatile_token == null and
+        node.ptr_info.sentinel == null;
+
+    if (simple) {
+        const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+        return addZIRUnOp(mod, scope, src, if (node.ptr_info.const_token == null)
+            .single_mut_ptr_type
+        else
+            .single_const_ptr_type, child_type);
+    }
+
+    const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+
+    var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{};
+    kw_args.@"allowzero" = node.ptr_info.allowzero_token != null;
+    if (node.ptr_info.align_info) |some| {
+        kw_args.@"align" = try expr(mod, scope, .none, some.node);
+        if (some.bit_range) |bit_range| {
+            kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start);
+            kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);
+        }
+    }
+    kw_args.@"const" = node.ptr_info.const_token != null;
+    kw_args.@"volatile" = node.ptr_info.volatile_token != null;
+    if (node.ptr_info.sentinel) |some| {
+        kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, some);
+    }
+
+    return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
+}
+
 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/zir.zig
@@ -192,6 +192,8 @@ pub const Inst = struct {
         single_const_ptr_type,
         /// Create a mutable pointer type based on the element type. `*T`
         single_mut_ptr_type,
+        /// Create a pointer type with attributes
+        ptr_type,
         /// Write a value to a pointer. For loading, see `deref`.
         store,
         /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
@@ -305,6 +307,7 @@ pub const Inst = struct {
                 .fntype => FnType,
                 .elemptr => ElemPtr,
                 .condbr => CondBr,
+                .ptr_type => PtrType,
             };
         }
 
@@ -382,6 +385,7 @@ pub const Inst = struct {
                 .optional_type,
                 .unwrap_optional_safe,
                 .unwrap_optional_unsafe,
+                .ptr_type,
                 => false,
 
                 .@"break",
@@ -811,6 +815,24 @@ pub const Inst = struct {
         },
         kw_args: struct {},
     };
+
+    pub const PtrType = struct {
+        pub const base_tag = Tag.ptr_type;
+        base: Inst,
+
+        positionals: struct {
+            child_type: *Inst,
+        },
+        kw_args: struct {
+            @"allowzero": bool = false,
+            @"align": ?*Inst = null,
+            align_bit_start: ?*Inst = null,
+            align_bit_end: ?*Inst = null,
+            @"const": bool = true,
+            @"volatile": bool = false,
+            sentinel: ?*Inst = null,
+        },
+    };
 };
 
 pub const ErrorMsg = struct {
src-self-hosted/zir_sema.zig
@@ -53,6 +53,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
         .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?),
         .single_const_ptr_type => return analyzeInstSingleConstPtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?),
         .single_mut_ptr_type => return analyzeInstSingleMutPtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?),
+        .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?),
         .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?),
         .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?),
         .int => {
@@ -1287,3 +1288,7 @@ fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp
     const ty = try mod.singleMutPtrType(scope, inst.base.src, elem_type);
     return mod.constType(scope, inst.base.src, ty);
 }
+
+fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst {
+    return mod.fail(scope, inst.base.src, "TODO implement ptr_type", .{});
+}