authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-13 20:50:39+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:42+02:00
log1147ecc5fda6d46c5e4d02eeda18238f34ae56dd
tree27949e56cc75f6dad3a0c2c27c01ddd8e2ed9a37
parentd7460db044ef6649486a27f2b9ebb1de9e2ce2b0
signature Commit is signed but in an unrecognized format.

translate-c: render variables and builtin calls


2 files changed, 282 insertions(+), 61 deletions(-)

src/translate_c.zig+17-14
......@@ -769,7 +769,7 @@ fn transCreateNodeTypedef(
769769
770770 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
771771 payload.* = .{
772 .base = .{ .tag = ([2]Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] },
772 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(toplevel)] },
773773 .data = .{
774774 .name = checked_name,
775775 .init = init_node,
......@@ -1678,7 +1678,7 @@ fn transStringLiteralAsArray(
16781678 init_list[i] = try transCreateCharLitNode(c, narrow, code_unit);
16791679 }
16801680 while (i < array_size) : (i += 1) {
1681 init_list[i] = try transCreateNodeNumber(c, 0);
1681 init_list[i] = try transCreateNodeNumber(c, 0, .int);
16821682 }
16831683
16841684 return Tag.array_init.create(c.arena, init_list);
......@@ -2345,7 +2345,7 @@ fn transCharLiteral(
23452345 // C has a somewhat obscure feature called multi-character character constant
23462346 // e.g. 'abcd'
23472347 const int_lit_node = if (kind == .Ascii and val > 255)
2348 try transCreateNodeNumber(c, val)
2348 try transCreateNodeNumber(c, val, .int)
23492349 else
23502350 try transCreateCharLitNode(c, narrow, val);
23512351
......@@ -2948,7 +2948,7 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
29482948fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
29492949 // TODO use something more accurate
29502950 const dbl = stmt.getValueAsApproximateDouble();
2951 const node = try transCreateNodeNumber(c, dbl);
2951 const node = try transCreateNodeNumber(c, dbl, .float);
29522952 return maybeSuppressResult(c, scope, used, node);
29532953}
29542954
......@@ -3471,13 +3471,16 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
34713471 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
34723472 error.OutOfMemory => return error.OutOfMemory,
34733473 };
3474 return Tag.number_literal.create(c.arena, str);
3474 return Tag.integer_literal.create(c.arena, str);
34753475}
34763476
3477fn transCreateNodeNumber(c: *Context, int: anytype) !Node {
3478 const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}";
3479 const str = try std.fmt.allocPrint(c.arena, fmt_s, .{int});
3480 return Tag.number_literal.create(c.arena, str);
3477fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {
3478 const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(num))) "{d}" else "{s}";
3479 const str = try std.fmt.allocPrint(c.arena, fmt_s, .{num});
3480 if (num_kind == .float)
3481 return Tag.float_literal.create(c.arena, str)
3482 else
3483 return Tag.integer_literal.create(c.arena, str);
34813484}
34823485
34833486fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node {
......@@ -4162,7 +4165,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
41624165 }
41634166
41644167 if (suffix == .none) {
4165 return transCreateNodeNumber(c, lit_bytes);
4168 return transCreateNodeNumber(c, lit_bytes, .int);
41664169 }
41674170
41684171 const type_node = try Tag.type.create(c.arena, switch (suffix) {
......@@ -4179,21 +4182,21 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
41794182 .llu => 3,
41804183 else => unreachable,
41814184 }];
4182 const rhs = try transCreateNodeNumber(c, lit_bytes);
4185 const rhs = try transCreateNodeNumber(c, lit_bytes, .int);
41834186 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
41844187 },
41854188 .FloatLiteral => |suffix| {
41864189 if (lit_bytes[0] == '.')
41874190 lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes});
41884191 if (suffix == .none) {
4189 return transCreateNodeNumber(c, lit_bytes);
4192 return transCreateNodeNumber(c, lit_bytes, .float);
41904193 }
41914194 const type_node = try Tag.type.create(c.arena, switch (suffix) {
41924195 .f => "f32",
41934196 .l => "c_longdouble",
41944197 else => unreachable,
41954198 });
4196 const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1]);
4199 const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1], .float);
41974200 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
41984201 },
41994202 else => unreachable,
......@@ -4369,7 +4372,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
43694372 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
43704373 } else {
43714374 const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});
4372 return Tag.number_literal.create(c.arena, str);
4375 return Tag.integer_literal.create(c.arena, str);
43734376 }
43744377 },
43754378 .StringLiteral => {
src/translate_c/ast.zig+265-47
......@@ -27,8 +27,8 @@ pub const Node = extern union {
2727 usingnamespace_builtins,
2828 // After this, the tag requires a payload.
2929
30 // int or float, doesn't really matter
31 number_literal,
30 integer_literal,
31 float_literal,
3232 string_literal,
3333 char_literal,
3434 identifier,
......@@ -193,10 +193,8 @@ pub const Node = extern union {
193193 /// pub const alias = actual;
194194 alias,
195195 /// const name = init;
196 typedef,
197196 var_simple,
198197 /// pub const name = init;
199 pub_typedef,
200198 pub_var_simple,
201199 /// pub const enum_field_name = @enumToInt(enum_name.field_name);
202200 enum_redecl,
......@@ -333,7 +331,8 @@ pub const Node = extern union {
333331 .ptr_cast,
334332 => Payload.BinOp,
335333
336 .number_literal,
334 .integer_literal,
335 .float_literal,
337336 .string_literal,
338337 .char_literal,
339338 .identifier,
......@@ -358,7 +357,7 @@ pub const Node = extern union {
358357 .array_type => Payload.Array,
359358 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
360359 .log2_int_type => Payload.Log2IntType,
361 .typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
360 .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
362361 .enum_redecl => Payload.EnumRedecl,
363362 .array_filler => Payload.ArrayFiller,
364363 .pub_inline_fn => Payload.PubInlineFn,
......@@ -705,7 +704,6 @@ const Context = struct {
705704 }
706705
707706 fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
708 std.debug.assert(tag != .identifier); // use addIdentifier
709707 return addTokenFmt(c, tag, "{s}", .{bytes});
710708 }
711709
......@@ -726,6 +724,17 @@ const Context = struct {
726724 try c.nodes.append(c.gpa, elem);
727725 return result;
728726 }
727
728 fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex {
729 const fields = std.meta.fields(@TypeOf(extra));
730 try c.extra_data.ensureCapacity(c.gpa, c.extra_data.items.len + fields.len);
731 const result = @intCast(u32, c.extra_data.items.len);
732 inline for (fields) |field| {
733 comptime std.debug.assert(field.field_type == NodeIndex);
734 c.extra_data.appendAssumeCapacity(@field(extra, field.name));
735 }
736 return result;
737 }
729738};
730739
731740fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
......@@ -734,7 +743,8 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
734743
735744 for (nodes) |node| {
736745 const res = try renderNode(c, node);
737 if (res == 0) continue;
746 if (node.tag() == .warning) continue;
747 if (c.nodes.items(.tag)[res] == .identifier) continue; // TODO remove
738748 try result.append(res);
739749 }
740750
......@@ -744,10 +754,10 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
744754fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
745755 switch (node.tag()) {
746756 .warning => {
747 const payload = node.castTag(.warning).?;
748 try c.buf.appendSlice(payload.data);
757 const payload = node.castTag(.warning).?.data;
758 try c.buf.appendSlice(payload);
749759 try c.buf.append('\n');
750 return 0;
760 return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
751761 },
752762 .usingnamespace_builtins => {
753763 // pub usingnamespace @import("std").c.builtins;
......@@ -766,34 +776,34 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
766776 });
767777 },
768778 .std_math_Log2Int => {
769 const payload = node.castTag(.std_math_Log2Int).?;
779 const payload = node.castTag(.std_math_Log2Int).?.data;
770780 const import_node = try renderStdImport(c, "math", "Log2Int");
771 return renderCall(c, import_node, &.{payload.data});
781 return renderCall(c, import_node, &.{payload});
772782 },
773783 .std_meta_cast => {
774 const payload = node.castTag(.std_meta_cast).?;
784 const payload = node.castTag(.std_meta_cast).?.data;
775785 const import_node = try renderStdImport(c, "meta", "cast");
776 return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
786 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
777787 },
778788 .std_meta_sizeof => {
779 const payload = node.castTag(.std_meta_sizeof).?;
789 const payload = node.castTag(.std_meta_sizeof).?.data;
780790 const import_node = try renderStdImport(c, "meta", "sizeof");
781 return renderCall(c, import_node, &.{payload.data});
791 return renderCall(c, import_node, &.{payload});
782792 },
783793 .std_mem_zeroes => {
784 const payload = node.castTag(.std_mem_zeroes).?;
794 const payload = node.castTag(.std_mem_zeroes).?.data;
785795 const import_node = try renderStdImport(c, "mem", "zeroes");
786 return renderCall(c, import_node, &.{payload.data});
796 return renderCall(c, import_node, &.{payload});
787797 },
788798 .std_mem_zeroinit => {
789 const payload = node.castTag(.std_mem_zeroinit).?;
799 const payload = node.castTag(.std_mem_zeroinit).?.data;
790800 const import_node = try renderStdImport(c, "mem", "zeroInit");
791 return renderCall(c, import_node, &.{ payload.data.lhs, payload.data.rhs });
801 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
792802 },
793803 .call => {
794 const payload = node.castTag(.call).?;
795 const lhs = try renderNode(c, payload.data.lhs);
796 return renderCall(c, lhs, payload.data.args);
804 const payload = node.castTag(.call).?.data;
805 const lhs = try renderNode(c, payload.lhs);
806 return renderCall(c, lhs, payload.args);
797807 },
798808 .null_literal => return c.addNode(.{
799809 .tag = .null_literal,
......@@ -860,10 +870,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
860870 },
861871 }),
862872 .type => {
863 const payload = node.castTag(.type).?;
873 const payload = node.castTag(.type).?.data;
864874 return c.addNode(.{
865875 .tag = .identifier,
866 .main_token = try c.addToken(.identifier, payload.data),
876 .main_token = try c.addToken(.identifier, payload),
867877 .data = .{
868878 .lhs = undefined,
869879 .rhs = undefined,
......@@ -871,22 +881,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
871881 });
872882 },
873883 .identifier => {
874 const payload = node.castTag(.identifier).?;
884 const payload = node.castTag(.identifier).?.data;
875885 return c.addNode(.{
876886 .tag = .identifier,
877 .main_token = try c.addIdentifier(payload.data),
887 .main_token = try c.addIdentifier(payload),
878888 .data = .{
879889 .lhs = undefined,
880890 .rhs = undefined,
881891 },
882892 });
883893 },
884 .number_literal => {
885 const payload = node.castTag(.number_literal).?;
894 .float_literal => {
895 const payload = node.castTag(.float_literal).?.data;
886896 return c.addNode(.{
887 .tag = .identifier,
888 // might be integer or float, but it doesn't matter for rendering
889 .main_token = try c.addToken(.integer_literal, payload.data),
897 .tag = .float_literal,
898 .main_token = try c.addToken(.float_literal, payload),
899 .data = .{
900 .lhs = undefined,
901 .rhs = undefined,
902 },
903 });
904 },
905 .integer_literal => {
906 const payload = node.castTag(.integer_literal).?.data;
907 return c.addNode(.{
908 .tag = .integer_literal,
909 .main_token = try c.addToken(.integer_literal, payload),
890910 .data = .{
891911 .lhs = undefined,
892912 .rhs = undefined,
......@@ -894,10 +914,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
894914 });
895915 },
896916 .string_literal => {
897 const payload = node.castTag(.string_literal).?;
917 const payload = node.castTag(.string_literal).?.data;
898918 return c.addNode(.{
899919 .tag = .identifier,
900 .main_token = try c.addToken(.char_literal, payload.data),
920 .main_token = try c.addToken(.string_literal, payload),
901921 .data = .{
902922 .lhs = undefined,
903923 .rhs = undefined,
......@@ -905,10 +925,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
905925 });
906926 },
907927 .char_literal => {
908 const payload = node.castTag(.char_literal).?;
928 const payload = node.castTag(.char_literal).?.data;
909929 return c.addNode(.{
910930 .tag = .identifier,
911 .main_token = try c.addToken(.string_literal, payload.data),
931 .main_token = try c.addToken(.string_literal, payload),
912932 .data = .{
913933 .lhs = undefined,
914934 .rhs = undefined,
......@@ -916,17 +936,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
916936 });
917937 },
918938 .fail_decl => {
919 const payload = node.castTag(.fail_decl).?;
939 const payload = node.castTag(.fail_decl).?.data;
920940 // pub const name = @compileError(msg);
921941 _ = try c.addToken(.keyword_pub, "pub");
922 const const_kw = try c.addToken(.keyword_const, "const");
923 _ = try c.addIdentifier(payload.data.actual);
942 const const_tok = try c.addToken(.keyword_const, "const");
943 _ = try c.addIdentifier(payload.actual);
924944 _ = try c.addToken(.equal, "=");
925945
926
927946 const compile_error_tok = try c.addToken(.builtin, "@compileError");
928947 _ = try c.addToken(.l_paren, "(");
929 const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(payload.data.mangled)});
948 const err_msg_tok = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(payload.mangled)});
930949 const err_msg = try c.addNode(.{
931950 .tag = .string_literal,
932951 .main_token = err_msg_tok,
......@@ -948,17 +967,105 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
948967
949968 return c.addNode(.{
950969 .tag = .simple_var_decl,
951 .main_token = const_kw,
970 .main_token = const_tok,
952971 .data = .{
953972 .lhs = 0,
954973 .rhs = compile_error,
955 }
974 },
956975 });
957976 },
958 else => {
959 try c.buf.writer().print("// TODO renderNode {}\n", .{node.tag()});
960 return @as(u32, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
977 .pub_var_simple, .var_simple => {
978 const payload = @fieldParentPtr(Payload.SimpleVarDecl, "base", node.ptr_otherwise).data;
979 if (node.tag() == .pub_var_simple) _ = try c.addToken(.keyword_pub, "pub");
980 const const_tok = try c.addToken(.keyword_const, "const");
981 _ = try c.addIdentifier(payload.name);
982 _ = try c.addToken(.equal, "=");
983
984 const init = try renderNode(c, payload.init);
985 _ = try c.addToken(.semicolon, ";");
986
987 return c.addNode(.{
988 .tag = .simple_var_decl,
989 .main_token = const_tok,
990 .data = .{
991 .lhs = 0,
992 .rhs = init,
993 },
994 });
995 },
996 .var_decl => return renderVar(c, node),
997 .int_cast => {
998 const payload = node.castTag(.int_cast).?.data;
999 return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs });
1000 },
1001 .rem => {
1002 const payload = node.castTag(.rem).?.data;
1003 return renderBuiltinCall(c, "@rem", &.{ payload.lhs, payload.rhs });
1004 },
1005 .div_trunc => {
1006 const payload = node.castTag(.div_trunc).?.data;
1007 return renderBuiltinCall(c, "@divTrunc", &.{ payload.lhs, payload.rhs });
1008 },
1009 .bool_to_int => {
1010 const payload = node.castTag(.bool_to_int).?.data;
1011 return renderBuiltinCall(c, "@boolToInt", &.{payload});
1012 },
1013 .as => {
1014 const payload = node.castTag(.as).?.data;
1015 return renderBuiltinCall(c, "@as", &.{ payload.lhs, payload.rhs });
1016 },
1017 .truncate => {
1018 const payload = node.castTag(.truncate).?.data;
1019 return renderBuiltinCall(c, "@truncate", &.{ payload.lhs, payload.rhs });
1020 },
1021 .bit_cast => {
1022 const payload = node.castTag(.bit_cast).?.data;
1023 return renderBuiltinCall(c, "@bitCast", &.{ payload.lhs, payload.rhs });
1024 },
1025 .float_cast => {
1026 const payload = node.castTag(.float_cast).?.data;
1027 return renderBuiltinCall(c, "@floatCast", &.{ payload.lhs, payload.rhs });
1028 },
1029 .float_to_int => {
1030 const payload = node.castTag(.float_to_int).?.data;
1031 return renderBuiltinCall(c, "@floatToInt", &.{ payload.lhs, payload.rhs });
1032 },
1033 .int_to_float => {
1034 const payload = node.castTag(.int_to_float).?.data;
1035 return renderBuiltinCall(c, "@intToFloat", &.{ payload.lhs, payload.rhs });
1036 },
1037 .int_to_enum => {
1038 const payload = node.castTag(.int_to_enum).?.data;
1039 return renderBuiltinCall(c, "@intToEnum", &.{ payload.lhs, payload.rhs });
1040 },
1041 .enum_to_int => {
1042 const payload = node.castTag(.enum_to_int).?.data;
1043 return renderBuiltinCall(c, "@enumToInt", &.{payload});
1044 },
1045 .int_to_ptr => {
1046 const payload = node.castTag(.int_to_ptr).?.data;
1047 return renderBuiltinCall(c, "@intToPtr", &.{ payload.lhs, payload.rhs });
1048 },
1049 .ptr_to_int => {
1050 const payload = node.castTag(.ptr_to_int).?.data;
1051 return renderBuiltinCall(c, "@ptrToInt", &.{payload});
1052 },
1053 .align_cast => {
1054 const payload = node.castTag(.align_cast).?.data;
1055 return renderBuiltinCall(c, "@alignCast", &.{ payload.lhs, payload.rhs });
9611056 },
1057 .ptr_cast => {
1058 const payload = node.castTag(.ptr_cast).?.data;
1059 return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });
1060 },
1061 else => return c.addNode(.{
1062 .tag = .identifier,
1063 .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),
1064 .data = .{
1065 .lhs = undefined,
1066 .rhs = undefined,
1067 },
1068 }),
9621069 }
9631070}
9641071
......@@ -1050,3 +1157,114 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
10501157 _ = try c.addToken(.r_paren, ")");
10511158 return res;
10521159}
1160
1161fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex {
1162 const builtin_tok = try c.addToken(.builtin, builtin);
1163 _ = try c.addToken(.l_paren, "(");
1164 var arg_1: NodeIndex = 0;
1165 var arg_2: NodeIndex = 0;
1166 switch (args.len) {
1167 0 => {},
1168 1 => {
1169 arg_1 = try renderNode(c, args[0]);
1170 },
1171 2 => {
1172 arg_1 = try renderNode(c, args[0]);
1173 _ = try c.addToken(.comma, ",");
1174 arg_2 = try renderNode(c, args[1]);
1175 },
1176 else => unreachable, // expand this function as needed.
1177 }
1178
1179 _ = try c.addToken(.r_paren, ")");
1180 return c.addNode(.{
1181 .tag = .builtin_call_two,
1182 .main_token = builtin_tok,
1183 .data = .{
1184 .lhs = arg_1,
1185 .rhs = arg_2,
1186 },
1187 });
1188}
1189
1190fn renderVar(c: *Context, node: Node) !NodeIndex {
1191 const payload = node.castTag(.var_decl).?.data;
1192 if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
1193 if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
1194 if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
1195 const mut_tok = if (payload.is_const)
1196 try c.addToken(.keyword_const, "const")
1197 else
1198 try c.addToken(.keyword_var, "var");
1199 _ = try c.addIdentifier(payload.name);
1200 _ = try c.addToken(.colon, ":");
1201 const type_node = try renderNode(c, payload.type);
1202
1203 const align_node = if (payload.alignment) |some| blk: {
1204 _ = try c.addToken(.keyword_align, "align");
1205 _ = try c.addToken(.l_paren, "(");
1206 const res = try c.addNode(.{
1207 .tag = .integer_literal,
1208 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
1209 .data = .{ .lhs = undefined, .rhs = undefined },
1210 });
1211 _ = try c.addToken(.r_paren, ")");
1212 break :blk res;
1213 } else 0;
1214
1215 const section_node = if (payload.linksection_string) |some| blk: {
1216 _ = try c.addToken(.keyword_linksection, "linksection");
1217 _ = try c.addToken(.l_paren, "(");
1218 const res = try c.addNode(.{
1219 .tag = .string_literal,
1220 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
1221 .data = .{ .lhs = undefined, .rhs = undefined },
1222 });
1223 _ = try c.addToken(.r_paren, ")");
1224 break :blk res;
1225 } else 0;
1226
1227 const init_node = if (payload.init) |some| blk: {
1228 _ = try c.addToken(.equal, "=");
1229 break :blk try renderNode(c, some);
1230 } else 0;
1231 _ = try c.addToken(.semicolon, ";");
1232
1233 if (section_node == 0) {
1234 if (align_node == 0) {
1235 return c.addNode(.{
1236 .tag = .simple_var_decl,
1237 .main_token = mut_tok,
1238 .data = .{
1239 .lhs = type_node,
1240 .rhs = init_node,
1241 },
1242 });
1243 } else {
1244 return c.addNode(.{
1245 .tag = .local_var_decl,
1246 .main_token = mut_tok,
1247 .data = .{
1248 .lhs = try c.addExtra(std.zig.ast.Node.LocalVarDecl{
1249 .type_node = type_node,
1250 .align_node = align_node,
1251 }),
1252 .rhs = init_node,
1253 },
1254 });
1255 }
1256 } else {
1257 return c.addNode(.{
1258 .tag = .global_var_decl,
1259 .main_token = mut_tok,
1260 .data = .{
1261 .lhs = try c.addExtra(std.zig.ast.Node.GlobalVarDecl{
1262 .type_node = type_node,
1263 .align_node = align_node,
1264 .section_node = section_node,
1265 }),
1266 .rhs = init_node,
1267 },
1268 });
1269 }
1270}