| author | |
| committer | |
| log | 2a628fd401bf057a71175c8b723375fd4f375a84 |
| tree | f4775061f46aa18edc86fd13aaa3efbcfb0ce294 |
| parent | ff7c6e1e3cea86e130e15a720c729a05763b5f08 |
| signature | Commit is signed but in an unrecognized format. |
3 files changed, 63 insertions(+), 1 deletions(-)
src-self-hosted/astgen.zig+31-1| ... | ... | @@ -275,6 +275,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 275 | 275 | .ErrorType => return rlWrap(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)), |
| 276 | 276 | .For => return forExpr(mod, scope, rl, node.castTag(.For).?), |
| 277 | 277 | .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?), |
| 278 | .Slice => return rlWrap(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)), | |
| 278 | 279 | .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?), |
| 279 | 280 | .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?), |
| 280 | 281 | .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 |
| 284 | 285 | .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}), |
| 285 | 286 | .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}), |
| 286 | 287 | .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}), |
| 287 | .Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}), | |
| 288 | 288 | .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}), |
| 289 | 289 | .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}), |
| 290 | 290 | .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 |
| 951 | 951 | return rlWrapPtr(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.ElemPtr, .{ .array_ptr = array_ptr, .index = index }, .{})); |
| 952 | 952 | } |
| 953 | 953 | |
| 954 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.Slice) InnerError!*zir.Inst { | |
| 955 | const tree = scope.tree(); | |
| 956 | const src = tree.token_locs[node.rtoken].start; | |
| 957 | ||
| 958 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | |
| 959 | .ty = Type.initTag(.type), | |
| 960 | .val = Value.initTag(.usize_type), | |
| 961 | }); | |
| 962 | ||
| 963 | const array_ptr = try expr(mod, scope, .ref, node.lhs); | |
| 964 | const start = try expr(mod, scope, .{ .ty = usize_type }, node.start); | |
| 965 | ||
| 966 | if (node.end == null and node.sentinel == null) { | |
| 967 | return try addZIRBinOp(mod, scope, src, .slice_start, array_ptr, start); | |
| 968 | } | |
| 969 | ||
| 970 | const end = if (node.end) |end| try expr(mod, scope, .{ .ty = usize_type }, end) else null; | |
| 971 | // we could get the child type here, but it is easier to just do it in semantic analysis. | |
| 972 | const sentinel = if (node.sentinel) |sentinel| try expr(mod, scope, .none, sentinel) else null; | |
| 973 | ||
| 974 | return try addZIRInst( | |
| 975 | mod, | |
| 976 | scope, | |
| 977 | src, | |
| 978 | zir.Inst.Slice, | |
| 979 | .{ .array_ptr = array_ptr, .start = start }, | |
| 980 | .{ .end = end, .sentinel = sentinel }, | |
| 981 | ); | |
| 982 | } | |
| 983 | ||
| 954 | 984 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 955 | 985 | const tree = scope.tree(); |
| 956 | 986 | const src = tree.token_locs[node.rtoken].start; |
src-self-hosted/zir.zig+22| ... | ... | @@ -231,6 +231,10 @@ pub const Inst = struct { |
| 231 | 231 | const_slice_type, |
| 232 | 232 | /// Create a pointer type with attributes |
| 233 | 233 | ptr_type, |
| 234 | /// Slice operation `array_ptr[start..end:sentinel]` | |
| 235 | slice, | |
| 236 | /// Slice operation with just start `lhs[rhs..]` | |
| 237 | slice_start, | |
| 234 | 238 | /// Write a value to a pointer. For loading, see `deref`. |
| 235 | 239 | store, |
| 236 | 240 | /// String Literal. Makes an anonymous Decl and then takes a pointer to it. |
| ... | ... | @@ -343,6 +347,7 @@ pub const Inst = struct { |
| 343 | 347 | .xor, |
| 344 | 348 | .error_union_type, |
| 345 | 349 | .merge_error_sets, |
| 350 | .slice_start, | |
| 346 | 351 | => BinOp, |
| 347 | 352 | |
| 348 | 353 | .block, |
| ... | ... | @@ -380,6 +385,7 @@ pub const Inst = struct { |
| 380 | 385 | .ptr_type => PtrType, |
| 381 | 386 | .enum_literal => EnumLiteral, |
| 382 | 387 | .error_set => ErrorSet, |
| 388 | .slice => Slice, | |
| 383 | 389 | }; |
| 384 | 390 | } |
| 385 | 391 | |
| ... | ... | @@ -481,6 +487,8 @@ pub const Inst = struct { |
| 481 | 487 | .error_union_type, |
| 482 | 488 | .bitnot, |
| 483 | 489 | .error_set, |
| 490 | .slice, | |
| 491 | .slice_start, | |
| 484 | 492 | => false, |
| 485 | 493 | |
| 486 | 494 | .@"break", |
| ... | ... | @@ -961,6 +969,20 @@ pub const Inst = struct { |
| 961 | 969 | }, |
| 962 | 970 | kw_args: struct {}, |
| 963 | 971 | }; |
| 972 | ||
| 973 | pub const Slice = struct { | |
| 974 | pub const base_tag = Tag.slice; | |
| 975 | base: Inst, | |
| 976 | ||
| 977 | positionals: struct { | |
| 978 | array_ptr: *Inst, | |
| 979 | start: *Inst, | |
| 980 | }, | |
| 981 | kw_args: struct { | |
| 982 | end: ?*Inst = null, | |
| 983 | sentinel: ?*Inst = null, | |
| 984 | }, | |
| 985 | }; | |
| 964 | 986 | }; |
| 965 | 987 | |
| 966 | 988 | pub const ErrorMsg = struct { |
src-self-hosted/zir_sema.zig+10| ... | ... | @@ -132,6 +132,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! |
| 132 | 132 | .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?), |
| 133 | 133 | .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?), |
| 134 | 134 | .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?), |
| 135 | .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?), | |
| 136 | .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?), | |
| 135 | 137 | } |
| 136 | 138 | } |
| 137 | 139 | |
| ... | ... | @@ -1172,6 +1174,14 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne |
| 1172 | 1174 | return mod.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{}); |
| 1173 | 1175 | } |
| 1174 | 1176 | |
| 1177 | fn analyzeInstSlice(mod: *Module, scope: *Scope, inst: *zir.Inst.Slice) InnerError!*Inst { | |
| 1178 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstSlice", .{}); | |
| 1179 | } | |
| 1180 | ||
| 1181 | fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { | |
| 1182 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstSliceStart", .{}); | |
| 1183 | } | |
| 1184 | ||
| 1175 | 1185 | fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |
| 1176 | 1186 | return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShl", .{}); |
| 1177 | 1187 | } |