| author | |
| committer | |
| log | c0540967e974b59bf85f71be9f085b5852d20ef6 |
| tree | ea3027ece32cc67ddd1a2aa14ec878cca3e6c126 |
| parent | 62162a07171ccbdb753650205880c3745a599366 |
| signature | Commit is signed but in an unrecognized format. |
3 files changed, 227 insertions(+), 59 deletions(-)
src/Compilation.zig+1-1| ... | ... | @@ -1334,7 +1334,7 @@ pub fn update(self: *Compilation) !void { |
| 1334 | 1334 | self.c_object_work_queue.writeItemAssumeCapacity(entry.key); |
| 1335 | 1335 | } |
| 1336 | 1336 | |
| 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 | 1338 | if (!use_stage1) { |
| 1339 | 1339 | if (self.bin_file.options.module) |module| { |
| 1340 | 1340 | module.compile_log_text.shrinkAndFree(module.gpa, 0); |
src/translate_c.zig+32-32| ... | ... | @@ -1689,7 +1689,10 @@ fn transStringLiteralAsArray( |
| 1689 | 1689 | init_list[i] = try transCreateNodeNumber(c, 0, .int); |
| 1690 | 1690 | } |
| 1691 | 1691 | |
| 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 | } |
| 1694 | 1697 | |
| 1695 | 1698 | fn cIsEnum(qt: clang.QualType) bool { |
| ... | ... | @@ -1880,6 +1883,7 @@ fn transInitListExprArray( |
| 1880 | 1883 | ) TransError!Node { |
| 1881 | 1884 | const arr_type = ty.getAsArrayTypeUnsafe(); |
| 1882 | 1885 | const child_qt = arr_type.getElementType(); |
| 1886 | const child_type = try transQualType(c, child_qt, loc); | |
| 1883 | 1887 | const init_count = expr.getNumInits(); |
| 1884 | 1888 | assert(@ptrCast(*const clang.Type, arr_type).isConstantArrayType()); |
| 1885 | 1889 | const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, arr_type); |
| ... | ... | @@ -1888,18 +1892,20 @@ fn transInitListExprArray( |
| 1888 | 1892 | const leftover_count = all_count - init_count; |
| 1889 | 1893 | |
| 1890 | 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 | } |
| 1893 | 1897 | |
| 1894 | const ty_node = try transType(c, ty, loc); | |
| 1895 | 1898 | const init_node = if (init_count != 0) blk: { |
| 1896 | 1899 | const init_list = try c.arena.alloc(Node, init_count); |
| 1897 | 1900 | |
| 1898 | 1901 | for (init_list) |*init, i| { |
| 1899 | 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 | 1909 | if (leftover_count == 0) { |
| 1904 | 1910 | return init_node; |
| 1905 | 1911 | } |
| ... | ... | @@ -1908,8 +1914,8 @@ fn transInitListExprArray( |
| 1908 | 1914 | |
| 1909 | 1915 | const filler_val_expr = expr.getArrayFiller(); |
| 1910 | 1916 | const filler_node = try Tag.array_filler.create(c.arena, .{ |
| 1911 | .type = ty_node, | |
| 1912 | .filler = try transExpr(c, scope, filler_val_expr, .used), | |
| 1917 | .type = child_type, | |
| 1918 | .filler = try transExprCoercing(c, scope, filler_val_expr, .used), | |
| 1913 | 1919 | .count = leftover_count, |
| 1914 | 1920 | }); |
| 1915 | 1921 | |
| ... | ... | @@ -2422,9 +2428,7 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re |
| 2422 | 2428 | const decl = @ptrCast(*const clang.NamedDecl, member_decl); |
| 2423 | 2429 | break :blk try c.str(decl.getName_bytes_begin()); |
| 2424 | 2430 | }; |
| 2425 | const ident = try Tag.identifier.create(c.arena, name); | |
| 2426 | ||
| 2427 | const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident }); | |
| 2431 | const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .field_name = name }); | |
| 2428 | 2432 | return maybeSuppressResult(c, scope, result_used, node); |
| 2429 | 2433 | } |
| 2430 | 2434 | |
| ... | ... | @@ -2698,14 +2702,14 @@ fn transCreatePreCrement( |
| 2698 | 2702 | defer block_scope.deinit(); |
| 2699 | 2703 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2700 | 2704 | |
| 2701 | const expr = try transExpr(c, scope, op_expr, .used); | |
| 2705 | const expr = try transExpr(c, &block_scope.base, op_expr, .used); | |
| 2702 | 2706 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2703 | 2707 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2704 | 2708 | try block_scope.statements.append(ref_decl); |
| 2705 | 2709 | |
| 2706 | 2710 | const lhs_node = try Tag.identifier.create(c.arena, ref); |
| 2707 | 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 | 2713 | try block_scope.statements.append(node); |
| 2710 | 2714 | |
| 2711 | 2715 | const break_node = try Tag.break_val.create(c.arena, .{ |
| ... | ... | @@ -2745,7 +2749,7 @@ fn transCreatePostCrement( |
| 2745 | 2749 | defer block_scope.deinit(); |
| 2746 | 2750 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2747 | 2751 | |
| 2748 | const expr = try transExpr(c, scope, op_expr, .used); | |
| 2752 | const expr = try transExpr(c, &block_scope.base, op_expr, .used); | |
| 2749 | 2753 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2750 | 2754 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2751 | 2755 | try block_scope.statements.append(ref_decl); |
| ... | ... | @@ -2757,7 +2761,7 @@ fn transCreatePostCrement( |
| 2757 | 2761 | const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node }); |
| 2758 | 2762 | try block_scope.statements.append(tmp_decl); |
| 2759 | 2763 | |
| 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 | 2765 | try block_scope.statements.append(node); |
| 2762 | 2766 | |
| 2763 | 2767 | const break_node = try Tag.break_val.create(c.arena, .{ |
| ... | ... | @@ -2864,7 +2868,7 @@ fn transCreateCompoundAssign( |
| 2864 | 2868 | defer block_scope.deinit(); |
| 2865 | 2869 | const ref = try block_scope.makeMangledName(c, "ref"); |
| 2866 | 2870 | |
| 2867 | const expr = try transExpr(c, scope, lhs, .used); | |
| 2871 | const expr = try transExpr(c, &block_scope.base, lhs, .used); | |
| 2868 | 2872 | const addr_of = try Tag.address_of.create(c.arena, expr); |
| 2869 | 2873 | const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of }); |
| 2870 | 2874 | try block_scope.statements.append(ref_decl); |
| ... | ... | @@ -2873,16 +2877,16 @@ fn transCreateCompoundAssign( |
| 2873 | 2877 | const ref_node = try Tag.deref.create(c.arena, lhs_node); |
| 2874 | 2878 | |
| 2875 | 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 | 2881 | const builtin = if (is_mod) |
| 2878 | 2882 | try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) |
| 2879 | 2883 | else |
| 2880 | 2884 | try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); |
| 2881 | 2885 | |
| 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 | 2887 | try block_scope.statements.append(assign); |
| 2884 | 2888 | } else { |
| 2885 | var rhs_node = try transExpr(c, scope, rhs, .used); | |
| 2889 | var rhs_node = try transExpr(c, &block_scope.base, rhs, .used); | |
| 2886 | 2890 | |
| 2887 | 2891 | if (is_shift or requires_int_cast) { |
| 2888 | 2892 | // @intCast(rhs) |
| ... | ... | @@ -2894,7 +2898,7 @@ fn transCreateCompoundAssign( |
| 2894 | 2898 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); |
| 2895 | 2899 | } |
| 2896 | 2900 | |
| 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 | 2902 | try block_scope.statements.append(assign); |
| 2899 | 2903 | } |
| 2900 | 2904 | |
| ... | ... | @@ -3395,7 +3399,7 @@ fn transCreateNodeAssign( |
| 3395 | 3399 | defer block_scope.deinit(); |
| 3396 | 3400 | |
| 3397 | 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 | 3403 | const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = rhs_node }); |
| 3400 | 3404 | try block_scope.statements.append(tmp_decl); |
| 3401 | 3405 | |
| ... | ... | @@ -4756,8 +4760,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4756 | 4760 | return error.ParseError; |
| 4757 | 4761 | } |
| 4758 | 4762 | |
| 4759 | const ident = try Tag.identifier.create(c.arena, m.slice()); | |
| 4760 | node = try Tag.field_access.create(c.arena, .{ .lhs = node, .rhs = ident }); | |
| 4763 | node = try Tag.field_access.create(c.arena, .{ .lhs = node, .field_name = m.slice() }); | |
| 4761 | 4764 | }, |
| 4762 | 4765 | .Arrow => { |
| 4763 | 4766 | if (m.next().? != .Identifier) { |
| ... | ... | @@ -4766,8 +4769,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 4766 | 4769 | } |
| 4767 | 4770 | |
| 4768 | 4771 | const deref = try Tag.deref.create(c.arena, node); |
| 4769 | const ident = try Tag.identifier.create(c.arena, m.slice()); | |
| 4770 | node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident }); | |
| 4772 | node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .field_name = m.slice() }); | |
| 4771 | 4773 | }, |
| 4772 | 4774 | .LBracket => { |
| 4773 | 4775 | const index = try macroBoolToInt(c, try parseCExpr(c, m, scope)); |
| ... | ... | @@ -4914,13 +4916,12 @@ fn getContainer(c: *Context, node: Node) ?Node { |
| 4914 | 4916 | }, |
| 4915 | 4917 | |
| 4916 | 4918 | .field_access => { |
| 4917 | const infix = node.castTag(.field_access).?; | |
| 4919 | const field_access = node.castTag(.field_access).?; | |
| 4918 | 4920 | |
| 4919 | if (getContainerTypeOf(c, infix.data.lhs)) |ty_node| { | |
| 4921 | if (getContainerTypeOf(c, field_access.data.lhs)) |ty_node| { | |
| 4920 | 4922 | if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| { |
| 4921 | 4923 | for (container.data.fields) |field| { |
| 4922 | const ident = infix.data.rhs.castTag(.identifier).?; | |
| 4923 | if (mem.eql(u8, field.name, ident.data)) { | |
| 4924 | if (mem.eql(u8, field.name, field_access.data.field_name)) { | |
| 4924 | 4925 | return getContainer(c, field.type); |
| 4925 | 4926 | } |
| 4926 | 4927 | } |
| ... | ... | @@ -4940,12 +4941,11 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node { |
| 4940 | 4941 | return getContainer(c, var_decl.data.type); |
| 4941 | 4942 | } |
| 4942 | 4943 | } |
| 4943 | } else if (ref.castTag(.field_access)) |infix| { | |
| 4944 | if (getContainerTypeOf(c, infix.data.lhs)) |ty_node| { | |
| 4944 | } else if (ref.castTag(.field_access)) |field_access| { | |
| 4945 | if (getContainerTypeOf(c, field_access.data.lhs)) |ty_node| { | |
| 4945 | 4946 | if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| { |
| 4946 | 4947 | for (container.data.fields) |field| { |
| 4947 | const ident = infix.data.rhs.castTag(.identifier).?; | |
| 4948 | if (mem.eql(u8, field.name, ident.data)) { | |
| 4948 | if (mem.eql(u8, field.name, field_access.data.field_name)) { | |
| 4949 | 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 | 291 | .array_cat, |
| 292 | 292 | .ellipsis3, |
| 293 | 293 | .switch_prong, |
| 294 | .field_access, | |
| 295 | 294 | .assign, |
| 296 | 295 | .align_cast, |
| 297 | 296 | .array_access, |
| ... | ... | @@ -309,7 +308,7 @@ pub const Node = extern union { |
| 309 | 308 | => Payload.Value, |
| 310 | 309 | .@"if" => Payload.If, |
| 311 | 310 | .@"while" => Payload.While, |
| 312 | .@"switch" => Payload.Switch, | |
| 311 | .@"switch", .array_init => Payload.Switch, | |
| 313 | 312 | .@"break" => Payload.Break, |
| 314 | 313 | .break_val => Payload.BreakVal, |
| 315 | 314 | .call => Payload.Call, |
| ... | ... | @@ -317,7 +316,7 @@ pub const Node = extern union { |
| 317 | 316 | .func => Payload.Func, |
| 318 | 317 | .@"enum" => Payload.Enum, |
| 319 | 318 | .@"struct", .@"union" => Payload.Record, |
| 320 | .array_init, .tuple => Payload.ArrayInit, | |
| 319 | .tuple => Payload.TupleInit, | |
| 321 | 320 | .container_init => Payload.ContainerInit, |
| 322 | 321 | .std_meta_cast => Payload.Infix, |
| 323 | 322 | .block => Payload.Block, |
| ... | ... | @@ -329,6 +328,7 @@ pub const Node = extern union { |
| 329 | 328 | .enum_redecl => Payload.EnumRedecl, |
| 330 | 329 | .array_filler => Payload.ArrayFiller, |
| 331 | 330 | .pub_inline_fn => Payload.PubInlineFn, |
| 331 | .field_access => Payload.FieldAccess, | |
| 332 | 332 | }; |
| 333 | 333 | } |
| 334 | 334 | |
| ... | ... | @@ -513,7 +513,7 @@ pub const Payload = struct { |
| 513 | 513 | }; |
| 514 | 514 | }; |
| 515 | 515 | |
| 516 | pub const ArrayInit = struct { | |
| 516 | pub const TupleInit = struct { | |
| 517 | 517 | base: Payload, |
| 518 | 518 | data: []Node, |
| 519 | 519 | }; |
| ... | ... | @@ -601,6 +601,14 @@ pub const Payload = struct { |
| 601 | 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 | }; |
| 605 | 613 | |
| 606 | 614 | /// Converts the nodes into a Zig ast. |
| ... | ... | @@ -995,6 +1003,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 995 | 1003 | }); |
| 996 | 1004 | }, |
| 997 | 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 | 1032 | .int_cast => { |
| 999 | 1033 | const payload = node.castTag(.int_cast).?.data; |
| 1000 | 1034 | return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs }); |
| ... | ... | @@ -1339,7 +1373,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1339 | 1373 | _ = try c.addToken(.l_paren, "("); |
| 1340 | 1374 | const cond = try c.addNode(.{ |
| 1341 | 1375 | .tag = .bool_not, |
| 1342 | .main_token = try c.addToken(.bang, "!"), | |
| 1376 | .main_token = try c.addToken(.bang, "!"), | |
| 1343 | 1377 | .data = .{ |
| 1344 | 1378 | .lhs = try renderNodeGrouped(c, payload), |
| 1345 | 1379 | .rhs = undefined, |
| ... | ... | @@ -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 | 1538 | .tag = .identifier, |
| 1435 | 1539 | .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}), |
| 1436 | 1540 | .data = .{ |
| ... | ... | @@ -1441,10 +1545,88 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1441 | 1545 | } |
| 1442 | 1546 | } |
| 1443 | 1547 | |
| 1548 | fn 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 | ||
| 1559 | fn 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 | ||
| 1607 | fn 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 | ||
| 1444 | 1626 | fn addSemicolonIfNeeded(c: *Context, node: Node) !void { |
| 1445 | 1627 | switch (node.tag()) { |
| 1446 | 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 | 1630 | .while_true => { |
| 1449 | 1631 | const payload = node.castTag(.while_true).?.data; |
| 1450 | 1632 | return addSemicolonIfNeeded(c, payload); |
| ... | ... | @@ -1517,6 +1699,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1517 | 1699 | .negate, |
| 1518 | 1700 | .negate_wrap, |
| 1519 | 1701 | .bit_not, |
| 1702 | .func, | |
| 1520 | 1703 | => { |
| 1521 | 1704 | // no grouping needed |
| 1522 | 1705 | return renderNode(c, node); |
| ... | ... | @@ -1572,7 +1755,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1572 | 1755 | .switch_prong, |
| 1573 | 1756 | .warning, |
| 1574 | 1757 | .var_decl, |
| 1575 | .func, | |
| 1576 | 1758 | .fail_decl, |
| 1577 | 1759 | .arg_redecl, |
| 1578 | 1760 | .alias, |
| ... | ... | @@ -1658,22 +1840,8 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde |
| 1658 | 1840 | }); |
| 1659 | 1841 | |
| 1660 | 1842 | var access_chain = import_node; |
| 1661 | access_chain = try c.addNode(.{ | |
| 1662 | .tag = .field_access, | |
| 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 | }); | |
| 1843 | access_chain = try renderFieldAccess(c, access_chain, first); | |
| 1844 | access_chain = try renderFieldAccess(c, access_chain, second); | |
| 1677 | 1845 | return access_chain; |
| 1678 | 1846 | } |
| 1679 | 1847 | |
| ... | ... | @@ -1974,10 +2142,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 1974 | 2142 | |
| 1975 | 2143 | const body = if (payload.body) |some| |
| 1976 | 2144 | try renderNode(c, some) |
| 1977 | else blk: { | |
| 2145 | else if (payload.is_extern) blk: { | |
| 1978 | 2146 | _ = try c.addToken(.semicolon, ";"); |
| 1979 | 2147 | break :blk 0; |
| 1980 | }; | |
| 2148 | } else return fn_proto; | |
| 1981 | 2149 | |
| 1982 | 2150 | return c.addNode(.{ |
| 1983 | 2151 | .tag = .fn_decl, |