stage2: astgen for ptr types and address of

This commit is contained in:
Vexu
2020-08-14 17:39:18 +03:00
parent 8d8d568854
commit c52513e25b
3 changed files with 76 additions and 2 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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", .{});
}