authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-20 18:32:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-20 18:32:43-07:00
log971f3d95f907fe438b0531df2f0c9f2a5471271d
treea7a1f3ff0c0ee974990f6c1c9dabbdc3d9ee0e42
parentc69a95f64bc616b9d4185687edeb08544e34a34c

AstGen: implement size zero inferred length arrays


1 files changed, 40 insertions(+), 15 deletions(-)

src/AstGen.zig+40-15
...@@ -897,18 +897,22 @@ pub fn arrayInitExpr(...@@ -897,18 +897,22 @@ pub fn arrayInitExpr(
897 if (node_tags[array_type.ast.elem_count] == .identifier and897 if (node_tags[array_type.ast.elem_count] == .identifier and
898 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))898 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
899 {899 {
900 const tag: Zir.Inst.Tag = switch (node_tags[array_init.ast.type_expr]) {
901 .array_type => .array_type,
902 .array_type_sentinel => .array_type_sentinel,
903 else => unreachable,
904 };
905 const len_inst = try gz.addInt(array_init.ast.elements.len);900 const len_inst = try gz.addInt(array_init.ast.elements.len);
906 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);901 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
907 const array_type_inst = try gz.addBin(tag, len_inst, elem_type);902 if (array_type.ast.sentinel == 0) {
908 break :inst .{903 const array_type_inst = try gz.addBin(.array_type, len_inst, elem_type);
909 .array = array_type_inst,904 break :inst .{
910 .elem = elem_type,905 .array = array_type_inst,
911 };906 .elem = elem_type,
907 };
908 } else {
909 const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel);
910 const array_type_inst = try gz.addArrayTypeSentinel(len_inst, elem_type, sentinel);
911 break :inst .{
912 .array = array_type_inst,
913 .elem = elem_type,
914 };
915 }
912 }916 }
913 }917 }
914 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);918 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
...@@ -1053,11 +1057,33 @@ pub fn structInitExpr(...@@ -1053,11 +1057,33 @@ pub fn structInitExpr(
1053 if (struct_init.ast.fields.len == 0) {1057 if (struct_init.ast.fields.len == 0) {
1054 if (struct_init.ast.type_expr == 0) {1058 if (struct_init.ast.type_expr == 0) {
1055 return rvalue(gz, scope, rl, .empty_struct, node);1059 return rvalue(gz, scope, rl, .empty_struct, node);
1056 } else {
1057 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1058 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1059 return rvalue(gz, scope, rl, result, node);
1060 }1060 }
1061 array: {
1062 const node_tags = tree.nodes.items(.tag);
1063 const main_tokens = tree.nodes.items(.main_token);
1064 const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) {
1065 .array_type => tree.arrayType(struct_init.ast.type_expr),
1066 .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr),
1067 else => break :array,
1068 };
1069 // This intentionally does not support `@"_"` syntax.
1070 if (node_tags[array_type.ast.elem_count] == .identifier and
1071 mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"))
1072 {
1073 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
1074 const array_type_inst = if (array_type.ast.sentinel == 0) blk: {
1075 break :blk try gz.addBin(.array_type, .zero_usize, elem_type);
1076 } else blk: {
1077 const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel);
1078 break :blk try gz.addArrayTypeSentinel(.zero_usize, elem_type, sentinel);
1079 };
1080 const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node);
1081 return rvalue(gz, scope, rl, result, node);
1082 }
1083 }
1084 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1085 const result = try gz.addUnNode(.struct_init_empty, ty_inst, node);
1086 return rvalue(gz, scope, rl, result, node);
1061 }1087 }
1062 switch (rl) {1088 switch (rl) {
1063 .discard => {1089 .discard => {
...@@ -2278,7 +2304,6 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.I...@@ -2278,7 +2304,6 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.I
2278 const node_datas = tree.nodes.items(.data);2304 const node_datas = tree.nodes.items(.data);
2279 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);2305 const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
22802306
2281 // TODO check for [_]T
2282 const len = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].lhs);2307 const len = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].lhs);
2283 const elem_type = try typeExpr(gz, scope, extra.elem_type);2308 const elem_type = try typeExpr(gz, scope, extra.elem_type);
2284 const sentinel = try expr(gz, scope, .{ .ty = elem_type }, extra.sentinel);2309 const sentinel = try expr(gz, scope, .{ .ty = elem_type }, extra.sentinel);