stage2: astgen slice

master
Vexu 2020-08-28 14:55:04 +03:00
parent ff7c6e1e3c
commit 2a628fd401
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
3 changed files with 63 additions and 1 deletions

View File

@ -275,6 +275,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
.For => return forExpr(mod, scope, rl, node.castTag(.For).?),
.ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),
.Slice => return rlWrap(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)),
.Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),
.Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),
.OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),
@ -284,7 +285,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
.Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
.Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
.Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
.ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}),
.ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}),
.StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}),
@ -951,6 +951,36 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array
return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.ElemPtr, .{ .array_ptr = array_ptr, .index = index }, .{}));
}
fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.Slice) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.rtoken].start;
const usize_type = try addZIRInstConst(mod, scope, src, .{
.ty = Type.initTag(.type),
.val = Value.initTag(.usize_type),
});
const array_ptr = try expr(mod, scope, .ref, node.lhs);
const start = try expr(mod, scope, .{ .ty = usize_type }, node.start);
if (node.end == null and node.sentinel == null) {
return try addZIRBinOp(mod, scope, src, .slice_start, array_ptr, start);
}
const end = if (node.end) |end| try expr(mod, scope, .{ .ty = usize_type }, end) else null;
// we could get the child type here, but it is easier to just do it in semantic analysis.
const sentinel = if (node.sentinel) |sentinel| try expr(mod, scope, .none, sentinel) else null;
return try addZIRInst(
mod,
scope,
src,
zir.Inst.Slice,
.{ .array_ptr = array_ptr, .start = start },
.{ .end = end, .sentinel = sentinel },
);
}
fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.rtoken].start;

View File

@ -231,6 +231,10 @@ pub const Inst = struct {
const_slice_type,
/// Create a pointer type with attributes
ptr_type,
/// Slice operation `array_ptr[start..end:sentinel]`
slice,
/// Slice operation with just start `lhs[rhs..]`
slice_start,
/// Write a value to a pointer. For loading, see `deref`.
store,
/// String Literal. Makes an anonymous Decl and then takes a pointer to it.
@ -343,6 +347,7 @@ pub const Inst = struct {
.xor,
.error_union_type,
.merge_error_sets,
.slice_start,
=> BinOp,
.block,
@ -380,6 +385,7 @@ pub const Inst = struct {
.ptr_type => PtrType,
.enum_literal => EnumLiteral,
.error_set => ErrorSet,
.slice => Slice,
};
}
@ -481,6 +487,8 @@ pub const Inst = struct {
.error_union_type,
.bitnot,
.error_set,
.slice,
.slice_start,
=> false,
.@"break",
@ -961,6 +969,20 @@ pub const Inst = struct {
},
kw_args: struct {},
};
pub const Slice = struct {
pub const base_tag = Tag.slice;
base: Inst,
positionals: struct {
array_ptr: *Inst,
start: *Inst,
},
kw_args: struct {
end: ?*Inst = null,
sentinel: ?*Inst = null,
},
};
};
pub const ErrorMsg = struct {

View File

@ -132,6 +132,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
.anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
.error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),
.slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?),
.slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
}
}
@ -1172,6 +1174,14 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne
return mod.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{});
}
fn analyzeInstSlice(mod: *Module, scope: *Scope, inst: *zir.Inst.Slice) InnerError!*Inst {
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstSlice", .{});
}
fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstSliceStart", .{});
}
fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShl", .{});
}