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(...@@ -769,7 +769,7 @@ fn transCreateNodeTypedef(
769769
770 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);770 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
771 payload.* = .{771 payload.* = .{
772 .base = .{ .tag = ([2]Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] },772 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(toplevel)] },
773 .data = .{773 .data = .{
774 .name = checked_name,774 .name = checked_name,
775 .init = init_node,775 .init = init_node,
...@@ -1678,7 +1678,7 @@ fn transStringLiteralAsArray(...@@ -1678,7 +1678,7 @@ fn transStringLiteralAsArray(
1678 init_list[i] = try transCreateCharLitNode(c, narrow, code_unit);1678 init_list[i] = try transCreateCharLitNode(c, narrow, code_unit);
1679 }1679 }
1680 while (i < array_size) : (i += 1) {1680 while (i < array_size) : (i += 1) {
1681 init_list[i] = try transCreateNodeNumber(c, 0);1681 init_list[i] = try transCreateNodeNumber(c, 0, .int);
1682 }1682 }
16831683
1684 return Tag.array_init.create(c.arena, init_list);1684 return Tag.array_init.create(c.arena, init_list);
...@@ -2345,7 +2345,7 @@ fn transCharLiteral(...@@ -2345,7 +2345,7 @@ fn transCharLiteral(
2345 // C has a somewhat obscure feature called multi-character character constant2345 // C has a somewhat obscure feature called multi-character character constant
2346 // e.g. 'abcd'2346 // e.g. 'abcd'
2347 const int_lit_node = if (kind == .Ascii and val > 255)2347 const int_lit_node = if (kind == .Ascii and val > 255)
2348 try transCreateNodeNumber(c, val)2348 try transCreateNodeNumber(c, val, .int)
2349 else2349 else
2350 try transCreateCharLitNode(c, narrow, val);2350 try transCreateCharLitNode(c, narrow, val);
23512351
...@@ -2948,7 +2948,7 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {...@@ -2948,7 +2948,7 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
2948fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {2948fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
2949 // TODO use something more accurate2949 // TODO use something more accurate
2950 const dbl = stmt.getValueAsApproximateDouble();2950 const dbl = stmt.getValueAsApproximateDouble();
2951 const node = try transCreateNodeNumber(c, dbl);2951 const node = try transCreateNodeNumber(c, dbl, .float);
2952 return maybeSuppressResult(c, scope, used, node);2952 return maybeSuppressResult(c, scope, used, node);
2953}2953}
29542954
...@@ -3471,13 +3471,16 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {...@@ -3471,13 +3471,16 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
3471 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {3471 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
3472 error.OutOfMemory => return error.OutOfMemory,3472 error.OutOfMemory => return error.OutOfMemory,
3473 };3473 };
3474 return Tag.number_literal.create(c.arena, str);3474 return Tag.integer_literal.create(c.arena, str);
3475}3475}
34763476
3477fn transCreateNodeNumber(c: *Context, int: anytype) !Node {3477fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {
3478 const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}";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, .{int});3479 const str = try std.fmt.allocPrint(c.arena, fmt_s, .{num});
3480 return Tag.number_literal.create(c.arena, str);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);
3481}3484}
34823485
3483fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node {3486fn 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 {...@@ -4162,7 +4165,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
4162 }4165 }
41634166
4164 if (suffix == .none) {4167 if (suffix == .none) {
4165 return transCreateNodeNumber(c, lit_bytes);4168 return transCreateNodeNumber(c, lit_bytes, .int);
4166 }4169 }
41674170
4168 const type_node = try Tag.type.create(c.arena, switch (suffix) {4171 const type_node = try Tag.type.create(c.arena, switch (suffix) {
...@@ -4179,21 +4182,21 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {...@@ -4179,21 +4182,21 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
4179 .llu => 3,4182 .llu => 3,
4180 else => unreachable,4183 else => unreachable,
4181 }];4184 }];
4182 const rhs = try transCreateNodeNumber(c, lit_bytes);4185 const rhs = try transCreateNodeNumber(c, lit_bytes, .int);
4183 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });4186 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
4184 },4187 },
4185 .FloatLiteral => |suffix| {4188 .FloatLiteral => |suffix| {
4186 if (lit_bytes[0] == '.')4189 if (lit_bytes[0] == '.')
4187 lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes});4190 lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes});
4188 if (suffix == .none) {4191 if (suffix == .none) {
4189 return transCreateNodeNumber(c, lit_bytes);4192 return transCreateNodeNumber(c, lit_bytes, .float);
4190 }4193 }
4191 const type_node = try Tag.type.create(c.arena, switch (suffix) {4194 const type_node = try Tag.type.create(c.arena, switch (suffix) {
4192 .f => "f32",4195 .f => "f32",
4193 .l => "c_longdouble",4196 .l => "c_longdouble",
4194 else => unreachable,4197 else => unreachable,
4195 });4198 });
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);
4197 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });4200 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
4198 },4201 },
4199 else => unreachable,4202 else => unreachable,
...@@ -4369,7 +4372,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N...@@ -4369,7 +4372,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
4369 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));4372 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
4370 } else {4373 } else {
4371 const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});4374 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);
4373 }4376 }
4374 },4377 },
4375 .StringLiteral => {4378 .StringLiteral => {
src/translate_c/ast.zig+265-47
...@@ -27,8 +27,8 @@ pub const Node = extern union {...@@ -27,8 +27,8 @@ pub const Node = extern union {
27 usingnamespace_builtins,27 usingnamespace_builtins,
28 // After this, the tag requires a payload.28 // After this, the tag requires a payload.
2929
30 // int or float, doesn't really matter30 integer_literal,
31 number_literal,31 float_literal,
32 string_literal,32 string_literal,
33 char_literal,33 char_literal,
34 identifier,34 identifier,
...@@ -193,10 +193,8 @@ pub const Node = extern union {...@@ -193,10 +193,8 @@ pub const Node = extern union {
193 /// pub const alias = actual;193 /// pub const alias = actual;
194 alias,194 alias,
195 /// const name = init;195 /// const name = init;
196 typedef,
197 var_simple,196 var_simple,
198 /// pub const name = init;197 /// pub const name = init;
199 pub_typedef,
200 pub_var_simple,198 pub_var_simple,
201 /// pub const enum_field_name = @enumToInt(enum_name.field_name);199 /// pub const enum_field_name = @enumToInt(enum_name.field_name);
202 enum_redecl,200 enum_redecl,
...@@ -333,7 +331,8 @@ pub const Node = extern union {...@@ -333,7 +331,8 @@ pub const Node = extern union {
333 .ptr_cast,331 .ptr_cast,
334 => Payload.BinOp,332 => Payload.BinOp,
335333
336 .number_literal,334 .integer_literal,
335 .float_literal,
337 .string_literal,336 .string_literal,
338 .char_literal,337 .char_literal,
339 .identifier,338 .identifier,
...@@ -358,7 +357,7 @@ pub const Node = extern union {...@@ -358,7 +357,7 @@ pub const Node = extern union {
358 .array_type => Payload.Array,357 .array_type => Payload.Array,
359 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,358 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
360 .log2_int_type => Payload.Log2IntType,359 .log2_int_type => Payload.Log2IntType,
361 .typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,360 .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
362 .enum_redecl => Payload.EnumRedecl,361 .enum_redecl => Payload.EnumRedecl,
363 .array_filler => Payload.ArrayFiller,362 .array_filler => Payload.ArrayFiller,
364 .pub_inline_fn => Payload.PubInlineFn,363 .pub_inline_fn => Payload.PubInlineFn,
...@@ -705,7 +704,6 @@ const Context = struct {...@@ -705,7 +704,6 @@ const Context = struct {
705 }704 }
706705
707 fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {706 fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
708 std.debug.assert(tag != .identifier); // use addIdentifier
709 return addTokenFmt(c, tag, "{s}", .{bytes});707 return addTokenFmt(c, tag, "{s}", .{bytes});
710 }708 }
711709
...@@ -726,6 +724,17 @@ const Context = struct {...@@ -726,6 +724,17 @@ const Context = struct {
726 try c.nodes.append(c.gpa, elem);724 try c.nodes.append(c.gpa, elem);
727 return result;725 return result;
728 }726 }
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 }
729};738};
730739
731fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {740fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
...@@ -734,7 +743,8 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {...@@ -734,7 +743,8 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
734743
735 for (nodes) |node| {744 for (nodes) |node| {
736 const res = try renderNode(c, node);745 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
738 try result.append(res);748 try result.append(res);
739 }749 }
740750
...@@ -744,10 +754,10 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {...@@ -744,10 +754,10 @@ fn renderNodes(c: *Context, nodes: []const Node) Allocator.Error!NodeSubRange {
744fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {754fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
745 switch (node.tag()) {755 switch (node.tag()) {
746 .warning => {756 .warning => {
747 const payload = node.castTag(.warning).?;757 const payload = node.castTag(.warning).?.data;
748 try c.buf.appendSlice(payload.data);758 try c.buf.appendSlice(payload);
749 try c.buf.append('\n');759 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'
751 },761 },
752 .usingnamespace_builtins => {762 .usingnamespace_builtins => {
753 // pub usingnamespace @import("std").c.builtins;763 // pub usingnamespace @import("std").c.builtins;
...@@ -766,34 +776,34 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -766,34 +776,34 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
766 });776 });
767 },777 },
768 .std_math_Log2Int => {778 .std_math_Log2Int => {
769 const payload = node.castTag(.std_math_Log2Int).?;779 const payload = node.castTag(.std_math_Log2Int).?.data;
770 const import_node = try renderStdImport(c, "math", "Log2Int");780 const import_node = try renderStdImport(c, "math", "Log2Int");
771 return renderCall(c, import_node, &.{payload.data});781 return renderCall(c, import_node, &.{payload});
772 },782 },
773 .std_meta_cast => {783 .std_meta_cast => {
774 const payload = node.castTag(.std_meta_cast).?;784 const payload = node.castTag(.std_meta_cast).?.data;
775 const import_node = try renderStdImport(c, "meta", "cast");785 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 });
777 },787 },
778 .std_meta_sizeof => {788 .std_meta_sizeof => {
779 const payload = node.castTag(.std_meta_sizeof).?;789 const payload = node.castTag(.std_meta_sizeof).?.data;
780 const import_node = try renderStdImport(c, "meta", "sizeof");790 const import_node = try renderStdImport(c, "meta", "sizeof");
781 return renderCall(c, import_node, &.{payload.data});791 return renderCall(c, import_node, &.{payload});
782 },792 },
783 .std_mem_zeroes => {793 .std_mem_zeroes => {
784 const payload = node.castTag(.std_mem_zeroes).?;794 const payload = node.castTag(.std_mem_zeroes).?.data;
785 const import_node = try renderStdImport(c, "mem", "zeroes");795 const import_node = try renderStdImport(c, "mem", "zeroes");
786 return renderCall(c, import_node, &.{payload.data});796 return renderCall(c, import_node, &.{payload});
787 },797 },
788 .std_mem_zeroinit => {798 .std_mem_zeroinit => {
789 const payload = node.castTag(.std_mem_zeroinit).?;799 const payload = node.castTag(.std_mem_zeroinit).?.data;
790 const import_node = try renderStdImport(c, "mem", "zeroInit");800 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 });
792 },802 },
793 .call => {803 .call => {
794 const payload = node.castTag(.call).?;804 const payload = node.castTag(.call).?.data;
795 const lhs = try renderNode(c, payload.data.lhs);805 const lhs = try renderNode(c, payload.lhs);
796 return renderCall(c, lhs, payload.data.args);806 return renderCall(c, lhs, payload.args);
797 },807 },
798 .null_literal => return c.addNode(.{808 .null_literal => return c.addNode(.{
799 .tag = .null_literal,809 .tag = .null_literal,
...@@ -860,10 +870,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -860,10 +870,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
860 },870 },
861 }),871 }),
862 .type => {872 .type => {
863 const payload = node.castTag(.type).?;873 const payload = node.castTag(.type).?.data;
864 return c.addNode(.{874 return c.addNode(.{
865 .tag = .identifier,875 .tag = .identifier,
866 .main_token = try c.addToken(.identifier, payload.data),876 .main_token = try c.addToken(.identifier, payload),
867 .data = .{877 .data = .{
868 .lhs = undefined,878 .lhs = undefined,
869 .rhs = undefined,879 .rhs = undefined,
...@@ -871,22 +881,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -871,22 +881,32 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
871 });881 });
872 },882 },
873 .identifier => {883 .identifier => {
874 const payload = node.castTag(.identifier).?;884 const payload = node.castTag(.identifier).?.data;
875 return c.addNode(.{885 return c.addNode(.{
876 .tag = .identifier,886 .tag = .identifier,
877 .main_token = try c.addIdentifier(payload.data),887 .main_token = try c.addIdentifier(payload),
878 .data = .{888 .data = .{
879 .lhs = undefined,889 .lhs = undefined,
880 .rhs = undefined,890 .rhs = undefined,
881 },891 },
882 });892 });
883 },893 },
884 .number_literal => {894 .float_literal => {
885 const payload = node.castTag(.number_literal).?;895 const payload = node.castTag(.float_literal).?.data;
886 return c.addNode(.{896 return c.addNode(.{
887 .tag = .identifier,897 .tag = .float_literal,
888 // might be integer or float, but it doesn't matter for rendering898 .main_token = try c.addToken(.float_literal, payload),
889 .main_token = try c.addToken(.integer_literal, payload.data),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),
890 .data = .{910 .data = .{
891 .lhs = undefined,911 .lhs = undefined,
892 .rhs = undefined,912 .rhs = undefined,
...@@ -894,10 +914,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -894,10 +914,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
894 });914 });
895 },915 },
896 .string_literal => {916 .string_literal => {
897 const payload = node.castTag(.string_literal).?;917 const payload = node.castTag(.string_literal).?.data;
898 return c.addNode(.{918 return c.addNode(.{
899 .tag = .identifier,919 .tag = .identifier,
900 .main_token = try c.addToken(.char_literal, payload.data),920 .main_token = try c.addToken(.string_literal, payload),
901 .data = .{921 .data = .{
902 .lhs = undefined,922 .lhs = undefined,
903 .rhs = undefined,923 .rhs = undefined,
...@@ -905,10 +925,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -905,10 +925,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
905 });925 });
906 },926 },
907 .char_literal => {927 .char_literal => {
908 const payload = node.castTag(.char_literal).?;928 const payload = node.castTag(.char_literal).?.data;
909 return c.addNode(.{929 return c.addNode(.{
910 .tag = .identifier,930 .tag = .identifier,
911 .main_token = try c.addToken(.string_literal, payload.data),931 .main_token = try c.addToken(.string_literal, payload),
912 .data = .{932 .data = .{
913 .lhs = undefined,933 .lhs = undefined,
914 .rhs = undefined,934 .rhs = undefined,
...@@ -916,17 +936,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -916,17 +936,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
916 });936 });
917 },937 },
918 .fail_decl => {938 .fail_decl => {
919 const payload = node.castTag(.fail_decl).?;939 const payload = node.castTag(.fail_decl).?.data;
920 // pub const name = @compileError(msg);940 // pub const name = @compileError(msg);
921 _ = try c.addToken(.keyword_pub, "pub");941 _ = try c.addToken(.keyword_pub, "pub");
922 const const_kw = try c.addToken(.keyword_const, "const");942 const const_tok = try c.addToken(.keyword_const, "const");
923 _ = try c.addIdentifier(payload.data.actual);943 _ = try c.addIdentifier(payload.actual);
924 _ = try c.addToken(.equal, "=");944 _ = try c.addToken(.equal, "=");
925945
926
927 const compile_error_tok = try c.addToken(.builtin, "@compileError");946 const compile_error_tok = try c.addToken(.builtin, "@compileError");
928 _ = try c.addToken(.l_paren, "(");947 _ = 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)});
930 const err_msg = try c.addNode(.{949 const err_msg = try c.addNode(.{
931 .tag = .string_literal,950 .tag = .string_literal,
932 .main_token = err_msg_tok,951 .main_token = err_msg_tok,
...@@ -948,17 +967,105 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -948,17 +967,105 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
948967
949 return c.addNode(.{968 return c.addNode(.{
950 .tag = .simple_var_decl,969 .tag = .simple_var_decl,
951 .main_token = const_kw,970 .main_token = const_tok,
952 .data = .{971 .data = .{
953 .lhs = 0,972 .lhs = 0,
954 .rhs = compile_error,973 .rhs = compile_error,
955 }974 },
956 });975 });
957 },976 },
958 else => {977 .pub_var_simple, .var_simple => {
959 try c.buf.writer().print("// TODO renderNode {}\n", .{node.tag()});978 const payload = @fieldParentPtr(Payload.SimpleVarDecl, "base", node.ptr_otherwise).data;
960 return @as(u32, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'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 });
961 },1056 },
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 }),
962 }1069 }
963}1070}
9641071
...@@ -1050,3 +1157,114 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {...@@ -1050,3 +1157,114 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
1050 _ = try c.addToken(.r_paren, ")");1157 _ = try c.addToken(.r_paren, ")");
1051 return res;1158 return res;
1052}1159}
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}