authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-14 18:06:15+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:43+02:00
logc0540967e974b59bf85f71be9f085b5852d20ef6
treeea3027ece32cc67ddd1a2aa14ec878cca3e6c126
parent62162a07171ccbdb753650205880c3745a599366
signature Commit is signed but in an unrecognized format.

translate-c: render array stuff


3 files changed, 227 insertions(+), 59 deletions(-)

src/Compilation.zig+1-1
...@@ -1334,7 +1334,7 @@ pub fn update(self: *Compilation) !void {...@@ -1334,7 +1334,7 @@ pub fn update(self: *Compilation) !void {
1334 self.c_object_work_queue.writeItemAssumeCapacity(entry.key);1334 self.c_object_work_queue.writeItemAssumeCapacity(entry.key);
1335 }1335 }
13361336
1337 const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_llvm;1337 const use_stage1 = build_options.omit_stage2 or build_options.is_stage1 and self.bin_file.options.use_llvm;
1338 if (!use_stage1) {1338 if (!use_stage1) {
1339 if (self.bin_file.options.module) |module| {1339 if (self.bin_file.options.module) |module| {
1340 module.compile_log_text.shrinkAndFree(module.gpa, 0);1340 module.compile_log_text.shrinkAndFree(module.gpa, 0);
src/translate_c.zig+32-32
...@@ -1689,7 +1689,10 @@ fn transStringLiteralAsArray(...@@ -1689,7 +1689,10 @@ fn transStringLiteralAsArray(
1689 init_list[i] = try transCreateNodeNumber(c, 0, .int);1689 init_list[i] = try transCreateNodeNumber(c, 0, .int);
1690 }1690 }
16911691
1692 return Tag.array_init.create(c.arena, init_list);1692 return Tag.array_init.create(c.arena, .{
1693 .cond = arr_type,
1694 .cases = init_list,
1695 });
1693}1696}
16941697
1695fn cIsEnum(qt: clang.QualType) bool {1698fn cIsEnum(qt: clang.QualType) bool {
...@@ -1880,6 +1883,7 @@ fn transInitListExprArray(...@@ -1880,6 +1883,7 @@ fn transInitListExprArray(
1880) TransError!Node {1883) TransError!Node {
1881 const arr_type = ty.getAsArrayTypeUnsafe();1884 const arr_type = ty.getAsArrayTypeUnsafe();
1882 const child_qt = arr_type.getElementType();1885 const child_qt = arr_type.getElementType();
1886 const child_type = try transQualType(c, child_qt, loc);
1883 const init_count = expr.getNumInits();1887 const init_count = expr.getNumInits();
1884 assert(@ptrCast(*const clang.Type, arr_type).isConstantArrayType());1888 assert(@ptrCast(*const clang.Type, arr_type).isConstantArrayType());
1885 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, arr_type);1889 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, arr_type);
...@@ -1888,18 +1892,20 @@ fn transInitListExprArray(...@@ -1888,18 +1892,20 @@ fn transInitListExprArray(
1888 const leftover_count = all_count - init_count;1892 const leftover_count = all_count - init_count;
18891893
1890 if (all_count == 0) {1894 if (all_count == 0) {
1891 return Tag.empty_array.create(c.arena, try transQualType(c, child_qt, loc));1895 return Tag.empty_array.create(c.arena, child_type);
1892 }1896 }
18931897
1894 const ty_node = try transType(c, ty, loc);
1895 const init_node = if (init_count != 0) blk: {1898 const init_node = if (init_count != 0) blk: {
1896 const init_list = try c.arena.alloc(Node, init_count);1899 const init_list = try c.arena.alloc(Node, init_count);
18971900
1898 for (init_list) |*init, i| {1901 for (init_list) |*init, i| {
1899 const elem_expr = expr.getInit(@intCast(c_uint, i));1902 const elem_expr = expr.getInit(@intCast(c_uint, i));
1900 init.* = try transExpr(c, scope, elem_expr, .used);1903 init.* = try transExprCoercing(c, scope, elem_expr, .used);
1901 }1904 }
1902 const init_node = try Tag.array_init.create(c.arena, init_list);1905 const init_node = try Tag.array_init.create(c.arena, .{
1906 .cond = try Tag.array_type.create(c.arena, .{ .len = init_count, .elem_type = child_type }),
1907 .cases = init_list,
1908 });
1903 if (leftover_count == 0) {1909 if (leftover_count == 0) {
1904 return init_node;1910 return init_node;
1905 }1911 }
...@@ -1908,8 +1914,8 @@ fn transInitListExprArray(...@@ -1908,8 +1914,8 @@ fn transInitListExprArray(
19081914
1909 const filler_val_expr = expr.getArrayFiller();1915 const filler_val_expr = expr.getArrayFiller();
1910 const filler_node = try Tag.array_filler.create(c.arena, .{1916 const filler_node = try Tag.array_filler.create(c.arena, .{
1911 .type = ty_node,1917 .type = child_type,
1912 .filler = try transExpr(c, scope, filler_val_expr, .used),1918 .filler = try transExprCoercing(c, scope, filler_val_expr, .used),
1913 .count = leftover_count,1919 .count = leftover_count,
1914 });1920 });
19151921
...@@ -2422,9 +2428,7 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re...@@ -2422,9 +2428,7 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re
2422 const decl = @ptrCast(*const clang.NamedDecl, member_decl);2428 const decl = @ptrCast(*const clang.NamedDecl, member_decl);
2423 break :blk try c.str(decl.getName_bytes_begin());2429 break :blk try c.str(decl.getName_bytes_begin());
2424 };2430 };
2425 const ident = try Tag.identifier.create(c.arena, name);2431 const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .field_name = name });
2426
2427 const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident });
2428 return maybeSuppressResult(c, scope, result_used, node);2432 return maybeSuppressResult(c, scope, result_used, node);
2429}2433}
24302434
...@@ -2698,14 +2702,14 @@ fn transCreatePreCrement(...@@ -2698,14 +2702,14 @@ fn transCreatePreCrement(
2698 defer block_scope.deinit();2702 defer block_scope.deinit();
2699 const ref = try block_scope.makeMangledName(c, "ref");2703 const ref = try block_scope.makeMangledName(c, "ref");
27002704
2701 const expr = try transExpr(c, scope, op_expr, .used);2705 const expr = try transExpr(c, &block_scope.base, op_expr, .used);
2702 const addr_of = try Tag.address_of.create(c.arena, expr);2706 const addr_of = try Tag.address_of.create(c.arena, expr);
2703 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });2707 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
2704 try block_scope.statements.append(ref_decl);2708 try block_scope.statements.append(ref_decl);
27052709
2706 const lhs_node = try Tag.identifier.create(c.arena, ref);2710 const lhs_node = try Tag.identifier.create(c.arena, ref);
2707 const ref_node = try Tag.deref.create(c.arena, lhs_node);2711 const ref_node = try Tag.deref.create(c.arena, lhs_node);
2708 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used);2712 const node = try transCreateNodeInfixOp(c, &block_scope.base, op, ref_node, Tag.one_literal.init(), .used);
2709 try block_scope.statements.append(node);2713 try block_scope.statements.append(node);
27102714
2711 const break_node = try Tag.break_val.create(c.arena, .{2715 const break_node = try Tag.break_val.create(c.arena, .{
...@@ -2745,7 +2749,7 @@ fn transCreatePostCrement(...@@ -2745,7 +2749,7 @@ fn transCreatePostCrement(
2745 defer block_scope.deinit();2749 defer block_scope.deinit();
2746 const ref = try block_scope.makeMangledName(c, "ref");2750 const ref = try block_scope.makeMangledName(c, "ref");
27472751
2748 const expr = try transExpr(c, scope, op_expr, .used);2752 const expr = try transExpr(c, &block_scope.base, op_expr, .used);
2749 const addr_of = try Tag.address_of.create(c.arena, expr);2753 const addr_of = try Tag.address_of.create(c.arena, expr);
2750 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });2754 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
2751 try block_scope.statements.append(ref_decl);2755 try block_scope.statements.append(ref_decl);
...@@ -2757,7 +2761,7 @@ fn transCreatePostCrement(...@@ -2757,7 +2761,7 @@ fn transCreatePostCrement(
2757 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node });2761 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node });
2758 try block_scope.statements.append(tmp_decl);2762 try block_scope.statements.append(tmp_decl);
27592763
2760 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used);2764 const node = try transCreateNodeInfixOp(c, &block_scope.base, op, ref_node, Tag.one_literal.init(), .used);
2761 try block_scope.statements.append(node);2765 try block_scope.statements.append(node);
27622766
2763 const break_node = try Tag.break_val.create(c.arena, .{2767 const break_node = try Tag.break_val.create(c.arena, .{
...@@ -2864,7 +2868,7 @@ fn transCreateCompoundAssign(...@@ -2864,7 +2868,7 @@ fn transCreateCompoundAssign(
2864 defer block_scope.deinit();2868 defer block_scope.deinit();
2865 const ref = try block_scope.makeMangledName(c, "ref");2869 const ref = try block_scope.makeMangledName(c, "ref");
28662870
2867 const expr = try transExpr(c, scope, lhs, .used);2871 const expr = try transExpr(c, &block_scope.base, lhs, .used);
2868 const addr_of = try Tag.address_of.create(c.arena, expr);2872 const addr_of = try Tag.address_of.create(c.arena, expr);
2869 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });2873 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
2870 try block_scope.statements.append(ref_decl);2874 try block_scope.statements.append(ref_decl);
...@@ -2873,16 +2877,16 @@ fn transCreateCompoundAssign(...@@ -2873,16 +2877,16 @@ fn transCreateCompoundAssign(
2873 const ref_node = try Tag.deref.create(c.arena, lhs_node);2877 const ref_node = try Tag.deref.create(c.arena, lhs_node);
28742878
2875 if ((is_mod or is_div) and is_signed) {2879 if ((is_mod or is_div) and is_signed) {
2876 const rhs_node = try transExpr(c, scope, rhs, .used);2880 const rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
2877 const builtin = if (is_mod)2881 const builtin = if (is_mod)
2878 try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })2882 try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
2879 else2883 else
2880 try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });2884 try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
28812885
2882 const assign = try transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used);2886 const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs_node, builtin, .used);
2883 try block_scope.statements.append(assign);2887 try block_scope.statements.append(assign);
2884 } else {2888 } else {
2885 var rhs_node = try transExpr(c, scope, rhs, .used);2889 var rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
28862890
2887 if (is_shift or requires_int_cast) {2891 if (is_shift or requires_int_cast) {
2888 // @intCast(rhs)2892 // @intCast(rhs)
...@@ -2894,7 +2898,7 @@ fn transCreateCompoundAssign(...@@ -2894,7 +2898,7 @@ fn transCreateCompoundAssign(
2894 rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });2898 rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
2895 }2899 }
28962900
2897 const assign = try transCreateNodeInfixOp(c, scope, op, ref_node, rhs_node, .used);2901 const assign = try transCreateNodeInfixOp(c, &block_scope.base, op, ref_node, rhs_node, .used);
2898 try block_scope.statements.append(assign);2902 try block_scope.statements.append(assign);
2899 }2903 }
29002904
...@@ -3395,7 +3399,7 @@ fn transCreateNodeAssign(...@@ -3395,7 +3399,7 @@ fn transCreateNodeAssign(
3395 defer block_scope.deinit();3399 defer block_scope.deinit();
33963400
3397 const tmp = try block_scope.makeMangledName(c, "tmp");3401 const tmp = try block_scope.makeMangledName(c, "tmp");
3398 const rhs_node = try transExpr(c, scope, rhs, .used);3402 const rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
3399 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = rhs_node });3403 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = rhs_node });
3400 try block_scope.statements.append(tmp_decl);3404 try block_scope.statements.append(tmp_decl);
34013405
...@@ -4756,8 +4760,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {...@@ -4756,8 +4760,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
4756 return error.ParseError;4760 return error.ParseError;
4757 }4761 }
47584762
4759 const ident = try Tag.identifier.create(c.arena, m.slice());4763 node = try Tag.field_access.create(c.arena, .{ .lhs = node, .field_name = m.slice() });
4760 node = try Tag.field_access.create(c.arena, .{ .lhs = node, .rhs = ident });
4761 },4764 },
4762 .Arrow => {4765 .Arrow => {
4763 if (m.next().? != .Identifier) {4766 if (m.next().? != .Identifier) {
...@@ -4766,8 +4769,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {...@@ -4766,8 +4769,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
4766 }4769 }
47674770
4768 const deref = try Tag.deref.create(c.arena, node);4771 const deref = try Tag.deref.create(c.arena, node);
4769 const ident = try Tag.identifier.create(c.arena, m.slice());4772 node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .field_name = m.slice() });
4770 node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident });
4771 },4773 },
4772 .LBracket => {4774 .LBracket => {
4773 const index = try macroBoolToInt(c, try parseCExpr(c, m, scope));4775 const index = try macroBoolToInt(c, try parseCExpr(c, m, scope));
...@@ -4914,13 +4916,12 @@ fn getContainer(c: *Context, node: Node) ?Node {...@@ -4914,13 +4916,12 @@ fn getContainer(c: *Context, node: Node) ?Node {
4914 },4916 },
49154917
4916 .field_access => {4918 .field_access => {
4917 const infix = node.castTag(.field_access).?;4919 const field_access = node.castTag(.field_access).?;
49184920
4919 if (getContainerTypeOf(c, infix.data.lhs)) |ty_node| {4921 if (getContainerTypeOf(c, field_access.data.lhs)) |ty_node| {
4920 if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| {4922 if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| {
4921 for (container.data.fields) |field| {4923 for (container.data.fields) |field| {
4922 const ident = infix.data.rhs.castTag(.identifier).?;4924 if (mem.eql(u8, field.name, field_access.data.field_name)) {
4923 if (mem.eql(u8, field.name, ident.data)) {
4924 return getContainer(c, field.type);4925 return getContainer(c, field.type);
4925 }4926 }
4926 }4927 }
...@@ -4940,12 +4941,11 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node {...@@ -4940,12 +4941,11 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node {
4940 return getContainer(c, var_decl.data.type);4941 return getContainer(c, var_decl.data.type);
4941 }4942 }
4942 }4943 }
4943 } else if (ref.castTag(.field_access)) |infix| {4944 } else if (ref.castTag(.field_access)) |field_access| {
4944 if (getContainerTypeOf(c, infix.data.lhs)) |ty_node| {4945 if (getContainerTypeOf(c, field_access.data.lhs)) |ty_node| {
4945 if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| {4946 if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| {
4946 for (container.data.fields) |field| {4947 for (container.data.fields) |field| {
4947 const ident = infix.data.rhs.castTag(.identifier).?;4948 if (mem.eql(u8, field.name, field_access.data.field_name)) {
4948 if (mem.eql(u8, field.name, ident.data)) {
4949 return getContainer(c, field.type);4949 return getContainer(c, field.type);
4950 }4950 }
4951 }4951 }
src/translate_c/ast.zig+194-26
...@@ -291,7 +291,6 @@ pub const Node = extern union {...@@ -291,7 +291,6 @@ pub const Node = extern union {
291 .array_cat,291 .array_cat,
292 .ellipsis3,292 .ellipsis3,
293 .switch_prong,293 .switch_prong,
294 .field_access,
295 .assign,294 .assign,
296 .align_cast,295 .align_cast,
297 .array_access,296 .array_access,
...@@ -309,7 +308,7 @@ pub const Node = extern union {...@@ -309,7 +308,7 @@ pub const Node = extern union {
309 => Payload.Value,308 => Payload.Value,
310 .@"if" => Payload.If,309 .@"if" => Payload.If,
311 .@"while" => Payload.While,310 .@"while" => Payload.While,
312 .@"switch" => Payload.Switch,311 .@"switch", .array_init => Payload.Switch,
313 .@"break" => Payload.Break,312 .@"break" => Payload.Break,
314 .break_val => Payload.BreakVal,313 .break_val => Payload.BreakVal,
315 .call => Payload.Call,314 .call => Payload.Call,
...@@ -317,7 +316,7 @@ pub const Node = extern union {...@@ -317,7 +316,7 @@ pub const Node = extern union {
317 .func => Payload.Func,316 .func => Payload.Func,
318 .@"enum" => Payload.Enum,317 .@"enum" => Payload.Enum,
319 .@"struct", .@"union" => Payload.Record,318 .@"struct", .@"union" => Payload.Record,
320 .array_init, .tuple => Payload.ArrayInit,319 .tuple => Payload.TupleInit,
321 .container_init => Payload.ContainerInit,320 .container_init => Payload.ContainerInit,
322 .std_meta_cast => Payload.Infix,321 .std_meta_cast => Payload.Infix,
323 .block => Payload.Block,322 .block => Payload.Block,
...@@ -329,6 +328,7 @@ pub const Node = extern union {...@@ -329,6 +328,7 @@ pub const Node = extern union {
329 .enum_redecl => Payload.EnumRedecl,328 .enum_redecl => Payload.EnumRedecl,
330 .array_filler => Payload.ArrayFiller,329 .array_filler => Payload.ArrayFiller,
331 .pub_inline_fn => Payload.PubInlineFn,330 .pub_inline_fn => Payload.PubInlineFn,
331 .field_access => Payload.FieldAccess,
332 };332 };
333 }333 }
334334
...@@ -513,7 +513,7 @@ pub const Payload = struct {...@@ -513,7 +513,7 @@ pub const Payload = struct {
513 };513 };
514 };514 };
515515
516 pub const ArrayInit = struct {516 pub const TupleInit = struct {
517 base: Payload,517 base: Payload,
518 data: []Node,518 data: []Node,
519 };519 };
...@@ -601,6 +601,14 @@ pub const Payload = struct {...@@ -601,6 +601,14 @@ pub const Payload = struct {
601 body: Node,601 body: Node,
602 },602 },
603 };603 };
604
605 pub const FieldAccess = struct {
606 base: Payload,
607 data: struct {
608 lhs: Node,
609 field_name: []const u8,
610 },
611 };
604};612};
605613
606/// Converts the nodes into a Zig ast.614/// Converts the nodes into a Zig ast.
...@@ -995,6 +1003,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -995,6 +1003,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
995 });1003 });
996 },1004 },
997 .var_decl => return renderVar(c, node),1005 .var_decl => return renderVar(c, node),
1006 .arg_redecl, .alias => {
1007 const payload = @fieldParentPtr(Payload.ArgRedecl, "base", node.ptr_otherwise).data;
1008 if (node.tag() == .alias) _ = try c.addToken(.keyword_pub, "pub");
1009 const mut_tok = if (node.tag() == .alias)
1010 try c.addToken(.keyword_const, "const")
1011 else
1012 try c.addToken(.keyword_var, "var");
1013 _ = try c.addIdentifier(payload.actual);
1014 _ = try c.addToken(.equal, "=");
1015
1016 const init = try c.addNode(.{
1017 .tag = .identifier,
1018 .main_token = try c.addIdentifier(payload.mangled),
1019 .data = undefined,
1020 });
1021 _ = try c.addToken(.semicolon, ";");
1022
1023 return c.addNode(.{
1024 .tag = .simple_var_decl,
1025 .main_token = mut_tok,
1026 .data = .{
1027 .lhs = 0,
1028 .rhs = init,
1029 },
1030 });
1031 },
998 .int_cast => {1032 .int_cast => {
999 const payload = node.castTag(.int_cast).?.data;1033 const payload = node.castTag(.int_cast).?.data;
1000 return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs });1034 return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs });
...@@ -1339,7 +1373,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1339,7 +1373,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1339 _ = try c.addToken(.l_paren, "(");1373 _ = try c.addToken(.l_paren, "(");
1340 const cond = try c.addNode(.{1374 const cond = try c.addNode(.{
1341 .tag = .bool_not,1375 .tag = .bool_not,
1342 .main_token = try c.addToken(.bang, "!"),1376 .main_token = try c.addToken(.bang, "!"),
1343 .data = .{1377 .data = .{
1344 .lhs = try renderNodeGrouped(c, payload),1378 .lhs = try renderNodeGrouped(c, payload),
1345 .rhs = undefined,1379 .rhs = undefined,
...@@ -1430,7 +1464,77 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1430,7 +1464,77 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1430 },1464 },
1431 });1465 });
1432 },1466 },
1433 else => return c.addNode(.{1467 .array_access => {
1468 const payload = node.castTag(.array_access).?.data;
1469 const lhs = try renderNode(c, payload.lhs);
1470 const l_bracket = try c.addToken(.l_bracket, "[");
1471 const index_expr = try renderNode(c, payload.rhs);
1472 _ = try c.addToken(.r_bracket, "]");
1473 return c.addNode(.{
1474 .tag = .array_access,
1475 .main_token = l_bracket,
1476 .data = .{
1477 .lhs = lhs,
1478 .rhs = index_expr,
1479 },
1480 });
1481 },
1482 .array_type => {
1483 const payload = node.castTag(.array_type).?.data;
1484 return renderArrayType(c, payload.len, payload.elem_type);
1485 },
1486 .array_filler => {
1487 const payload = node.castTag(.array_filler).?.data;
1488
1489 const type_expr = try renderArrayType(c, 1, payload.type);
1490 const l_brace = try c.addToken(.l_brace, "{");
1491 const val = try renderNode(c, payload.filler);
1492 _ = try c.addToken(.r_brace, "}");
1493
1494 const init = try c.addNode(.{
1495 .tag = .array_init_one,
1496 .main_token = l_brace,
1497 .data = .{
1498 .lhs = type_expr,
1499 .rhs = val,
1500 },
1501 });
1502 return c.addNode(.{
1503 .tag = .array_cat,
1504 .main_token = try c.addToken(.asterisk_asterisk, "**"),
1505 .data = .{
1506 .lhs = init,
1507 .rhs = try c.addNode(.{
1508 .tag = .integer_literal,
1509 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{payload.count}),
1510 .data = .{ .lhs = undefined, .rhs = undefined },
1511 }),
1512 },
1513 });
1514 },
1515 .empty_array => {
1516 const payload = node.castTag(.empty_array).?.data;
1517
1518 const type_expr = try renderArrayType(c, 0, payload);
1519 return renderArrayInit(c, 0, &.{});
1520 },
1521 .array_init => {
1522 const payload = node.castTag(.array_init).?.data;
1523 const type_expr = try renderNode(c, payload.cond);
1524 return renderArrayInit(c, type_expr, payload.cases);
1525 },
1526 .field_access => {
1527 const payload = node.castTag(.field_access).?.data;
1528 const lhs = try renderNode(c, payload.lhs);
1529 return renderFieldAccess(c, lhs, payload.field_name);
1530 },
1531 .tuple,
1532 .@"enum",
1533 .@"struct",
1534 .@"union",
1535 .container_init,
1536 .enum_redecl,
1537 => return c.addNode(.{
1434 .tag = .identifier,1538 .tag = .identifier,
1435 .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),1539 .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),
1436 .data = .{1540 .data = .{
...@@ -1441,10 +1545,88 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1441,10 +1545,88 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1441 }1545 }
1442}1546}
14431547
1548fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeIndex {
1549 return c.addNode(.{
1550 .tag = .field_access,
1551 .main_token = try c.addToken(.period, "."),
1552 .data = .{
1553 .lhs = lhs,
1554 .rhs = try c.addIdentifier(field_name),
1555 },
1556 });
1557}
1558
1559fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex {
1560 const l_brace = try c.addToken(.l_brace, "{");
1561 const res = switch (inits.len) {
1562 0 => try c.addNode(.{
1563 .tag = .struct_init_one,
1564 .main_token = l_brace,
1565 .data = .{
1566 .lhs = lhs,
1567 .rhs = 0,
1568 },
1569 }),
1570 1 => blk: {
1571 const init = try renderNode(c, inits[0]);
1572 break :blk try c.addNode(.{
1573 .tag = .array_init_one,
1574 .main_token = l_brace,
1575 .data = .{
1576 .lhs = lhs,
1577 .rhs = init,
1578 },
1579 });
1580 },
1581 else => blk: {
1582 var rendered = try c.gpa.alloc(NodeIndex, inits.len);
1583 defer c.gpa.free(rendered);
1584
1585 for (inits) |init, i| {
1586 if (i != 0) _ = try c.addToken(.comma, ",");
1587 rendered[i] = try renderNode(c, init);
1588 }
1589 const span = try c.listToSpan(rendered);
1590 break :blk try c.addNode(.{
1591 .tag = .array_init,
1592 .main_token = l_brace,
1593 .data = .{
1594 .lhs = lhs,
1595 .rhs = try c.addExtra(NodeSubRange{
1596 .start = span.start,
1597 .end = span.end,
1598 }),
1599 },
1600 });
1601 },
1602 };
1603 _ = try c.addToken(.r_brace, "}");
1604 return res;
1605}
1606
1607fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
1608 const l_bracket = try c.addToken(.l_bracket, "[");
1609 const len_expr = try c.addNode(.{
1610 .tag = .integer_literal,
1611 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{len}),
1612 .data = .{ .lhs = undefined, .rhs = undefined },
1613 });
1614 _ = try c.addToken(.r_bracket, "]");
1615 const elem_type_expr = try renderNode(c, elem_type);
1616 return c.addNode(.{
1617 .tag = .array_type,
1618 .main_token = l_bracket,
1619 .data = .{
1620 .lhs = len_expr,
1621 .rhs = elem_type_expr,
1622 },
1623 });
1624}
1625
1444fn addSemicolonIfNeeded(c: *Context, node: Node) !void {1626fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
1445 switch (node.tag()) {1627 switch (node.tag()) {
1446 .warning => unreachable,1628 .warning => unreachable,
1447 .var_decl, .var_simple, .block, .empty_block, .@"switch" => {},1629 .var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .@"switch" => {},
1448 .while_true => {1630 .while_true => {
1449 const payload = node.castTag(.while_true).?.data;1631 const payload = node.castTag(.while_true).?.data;
1450 return addSemicolonIfNeeded(c, payload);1632 return addSemicolonIfNeeded(c, payload);
...@@ -1517,6 +1699,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1517,6 +1699,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1517 .negate,1699 .negate,
1518 .negate_wrap,1700 .negate_wrap,
1519 .bit_not,1701 .bit_not,
1702 .func,
1520 => {1703 => {
1521 // no grouping needed1704 // no grouping needed
1522 return renderNode(c, node);1705 return renderNode(c, node);
...@@ -1572,7 +1755,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1572,7 +1755,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1572 .switch_prong,1755 .switch_prong,
1573 .warning,1756 .warning,
1574 .var_decl,1757 .var_decl,
1575 .func,
1576 .fail_decl,1758 .fail_decl,
1577 .arg_redecl,1759 .arg_redecl,
1578 .alias,1760 .alias,
...@@ -1658,22 +1840,8 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde...@@ -1658,22 +1840,8 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde
1658 });1840 });
16591841
1660 var access_chain = import_node;1842 var access_chain = import_node;
1661 access_chain = try c.addNode(.{1843 access_chain = try renderFieldAccess(c, access_chain, first);
1662 .tag = .field_access,1844 access_chain = try renderFieldAccess(c, access_chain, second);
1663 .main_token = try c.addToken(.period, "."),
1664 .data = .{
1665 .lhs = access_chain,
1666 .rhs = try c.addIdentifier(first),
1667 },
1668 });
1669 access_chain = try c.addNode(.{
1670 .tag = .field_access,
1671 .main_token = try c.addToken(.period, "."),
1672 .data = .{
1673 .lhs = access_chain,
1674 .rhs = try c.addIdentifier(second),
1675 },
1676 });
1677 return access_chain;1845 return access_chain;
1678}1846}
16791847
...@@ -1974,10 +2142,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -1974,10 +2142,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
19742142
1975 const body = if (payload.body) |some|2143 const body = if (payload.body) |some|
1976 try renderNode(c, some)2144 try renderNode(c, some)
1977 else blk: {2145 else if (payload.is_extern) blk: {
1978 _ = try c.addToken(.semicolon, ";");2146 _ = try c.addToken(.semicolon, ";");
1979 break :blk 0;2147 break :blk 0;
1980 };2148 } else return fn_proto;
19812149
1982 return c.addNode(.{2150 return c.addNode(.{
1983 .tag = .fn_decl,2151 .tag = .fn_decl,