authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-13 21:24:40+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:42+02:00
log685778c5a73bf08487ebfb4b1632aee089a89e79
tree24867132db1fe3eb91402217adb8e46ad22e7d98
parent1147ecc5fda6d46c5e4d02eeda18238f34ae56dd
signature Commit is signed but in an unrecognized format.

translate-c: render unary ops


2 files changed, 234 insertions(+), 32 deletions(-)

src/translate_c.zig+2-2
...@@ -3049,7 +3049,7 @@ fn maybeSuppressResult(...@@ -3049,7 +3049,7 @@ fn maybeSuppressResult(
3049 result: Node,3049 result: Node,
3050) TransError!Node {3050) TransError!Node {
3051 if (used == .used) return result;3051 if (used == .used) return result;
3052 return Tag.ignore.create(c.arena, result);3052 return Tag.discard.create(c.arena, result);
3053}3053}
30543054
3055fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {3055fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
...@@ -4127,7 +4127,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {...@@ -4127,7 +4127,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
4127 var last = node;4127 var last = node;
4128 while (true) {4128 while (true) {
4129 // suppress result4129 // suppress result
4130 const ignore = try Tag.ignore.create(c.arena, last);4130 const ignore = try Tag.discard.create(c.arena, last);
4131 try block_scope.statements.append(ignore);4131 try block_scope.statements.append(ignore);
41324132
4133 last = try parseCCondExpr(c, m, scope);4133 last = try parseCCondExpr(c, m, scope);
src/translate_c/ast.zig+232-30
...@@ -60,6 +60,7 @@ pub const Node = extern union {...@@ -60,6 +60,7 @@ pub const Node = extern union {
60 tuple,60 tuple,
61 container_init,61 container_init,
62 std_meta_cast,62 std_meta_cast,
63 /// _ = operand;
63 discard,64 discard,
6465
65 // a + b66 // a + b
...@@ -67,43 +68,30 @@ pub const Node = extern union {...@@ -67,43 +68,30 @@ pub const Node = extern union {
67 // a = b68 // a = b
68 add_assign,69 add_assign,
69 // c = (a = b)70 // c = (a = b)
70 add_assign_value,
71 add_wrap,71 add_wrap,
72 add_wrap_assign,72 add_wrap_assign,
73 add_wrap_assign_value,
74 sub,73 sub,
75 sub_assign,74 sub_assign,
76 sub_assign_value,
77 sub_wrap,75 sub_wrap,
78 sub_wrap_assign,76 sub_wrap_assign,
79 sub_wrap_assign_value,
80 mul,77 mul,
81 mul_assign,78 mul_assign,
82 mul_assign_value,
83 mul_wrap,79 mul_wrap,
84 mul_wrap_assign,80 mul_wrap_assign,
85 mul_wrap_assign_value,
86 div,81 div,
87 div_assign,82 div_assign,
88 div_assign_value,
89 shl,83 shl,
90 shl_assign,84 shl_assign,
91 shl_assign_value,
92 shr,85 shr,
93 shr_assign,86 shr_assign,
94 shr_assign_value,
95 mod,87 mod,
96 mod_assign,88 mod_assign,
97 mod_assign_value,
98 @"and",89 @"and",
99 and_assign,90 and_assign,
100 and_assign_value,
101 @"or",91 @"or",
102 or_assign,92 or_assign,
103 or_assign_value,
104 xor,93 xor,
105 xor_assign,94 xor_assign,
106 xor_assign_value,
107 less_than,95 less_than,
108 less_than_equal,96 less_than_equal,
109 greater_than,97 greater_than,
...@@ -207,9 +195,6 @@ pub const Node = extern union {...@@ -207,9 +195,6 @@ pub const Node = extern union {
207 /// [1]type{val} ** count195 /// [1]type{val} ** count
208 array_filler,196 array_filler,
209197
210 /// _ = operand;
211 ignore,
212
213 pub const last_no_payload_tag = Tag.usingnamespace_builtins;198 pub const last_no_payload_tag = Tag.usingnamespace_builtins;
214 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;199 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
215200
...@@ -249,7 +234,6 @@ pub const Node = extern union {...@@ -249,7 +234,6 @@ pub const Node = extern union {
249 .while_true,234 .while_true,
250 .if_not_break,235 .if_not_break,
251 .switch_else,236 .switch_else,
252 .ignore,
253 .block_single,237 .block_single,
254 .std_meta_sizeof,238 .std_meta_sizeof,
255 .bool_to_int,239 .bool_to_int,
...@@ -260,43 +244,30 @@ pub const Node = extern union {...@@ -260,43 +244,30 @@ pub const Node = extern union {
260244
261 .add,245 .add,
262 .add_assign,246 .add_assign,
263 .add_assign_value,
264 .add_wrap,247 .add_wrap,
265 .add_wrap_assign,248 .add_wrap_assign,
266 .add_wrap_assign_value,
267 .sub,249 .sub,
268 .sub_assign,250 .sub_assign,
269 .sub_assign_value,
270 .sub_wrap,251 .sub_wrap,
271 .sub_wrap_assign,252 .sub_wrap_assign,
272 .sub_wrap_assign_value,
273 .mul,253 .mul,
274 .mul_assign,254 .mul_assign,
275 .mul_assign_value,
276 .mul_wrap,255 .mul_wrap,
277 .mul_wrap_assign,256 .mul_wrap_assign,
278 .mul_wrap_assign_value,
279 .div,257 .div,
280 .div_assign,258 .div_assign,
281 .div_assign_value,
282 .shl,259 .shl,
283 .shl_assign,260 .shl_assign,
284 .shl_assign_value,
285 .shr,261 .shr,
286 .shr_assign,262 .shr_assign,
287 .shr_assign_value,
288 .mod,263 .mod,
289 .mod_assign,264 .mod_assign,
290 .mod_assign_value,
291 .@"and",265 .@"and",
292 .and_assign,266 .and_assign,
293 .and_assign_value,
294 .@"or",267 .@"or",
295 .or_assign,268 .or_assign,
296 .or_assign_value,
297 .xor,269 .xor,
298 .xor_assign,270 .xor_assign,
299 .xor_assign_value,
300 .less_than,271 .less_than,
301 .less_than_equal,272 .less_than_equal,
302 .greater_than,273 .greater_than,
...@@ -869,6 +840,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -869,6 +840,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
869 .rhs = undefined,840 .rhs = undefined,
870 },841 },
871 }),842 }),
843 .noreturn_type => return try c.addNode(.{
844 .tag = .identifier,
845 .main_token = try c.addToken(.identifier, "noreturn"),
846 .data = .{
847 .lhs = undefined,
848 .rhs = undefined,
849 },
850 }),
872 .type => {851 .type => {
873 const payload = node.castTag(.type).?.data;852 const payload = node.castTag(.type).?.data;
874 return c.addNode(.{853 return c.addNode(.{
...@@ -880,6 +859,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -880,6 +859,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
880 },859 },
881 });860 });
882 },861 },
862 .log2_int_type => {
863 const payload = node.castTag(.log2_int_type).?.data;
864 return c.addNode(.{
865 .tag = .identifier,
866 .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}),
867 .data = .{
868 .lhs = undefined,
869 .rhs = undefined,
870 },
871 });
872 },
883 .identifier => {873 .identifier => {
884 const payload = node.castTag(.identifier).?.data;874 const payload = node.castTag(.identifier).?.data;
885 return c.addNode(.{875 return c.addNode(.{
...@@ -1058,6 +1048,51 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1058,6 +1048,51 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1058 const payload = node.castTag(.ptr_cast).?.data;1048 const payload = node.castTag(.ptr_cast).?.data;
1059 return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });1049 return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });
1060 },1050 },
1051 .sizeof => {
1052 const payload = node.castTag(.sizeof).?.data;
1053 return renderBuiltinCall(c, "@sizeOf", &.{payload});
1054 },
1055 .alignof => {
1056 const payload = node.castTag(.alignof).?.data;
1057 return renderBuiltinCall(c, "@alignOf", &.{payload});
1058 },
1059 .typeof => {
1060 const payload = node.castTag(.typeof).?.data;
1061 return renderBuiltinCall(c, "@TypeOf", &.{payload});
1062 },
1063 .negate => return renderPrefixOp(c, node, .negation, .minus, "-"),
1064 .negate_wrap => return renderPrefixOp(c, node, .negation_wrap, .minus_percent, "-%"),
1065 .bit_not => return renderPrefixOp(c, node, .bit_not, .tilde, "~"),
1066 .not => return renderPrefixOp(c, node, .bool_not, .bang, "!"),
1067 .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"),
1068 .address_of => return renderPrefixOp(c, node, .address_of, .ampersand, "&"),
1069 .deref => {
1070 const payload = node.castTag(.deref).?.data;
1071 const operand = try renderNodeGrouped(c, payload);
1072 const deref_tok = try c.addToken(.period_asterisk, ".*");
1073 return c.addNode(.{
1074 .tag = .deref,
1075 .main_token = deref_tok,
1076 .data = .{
1077 .lhs = operand,
1078 .rhs = undefined,
1079 },
1080 });
1081 },
1082 .unwrap => {
1083 const payload = node.castTag(.unwrap).?.data;
1084 const operand = try renderNodeGrouped(c, payload);
1085 const period = try c.addToken(.period, ".");
1086 const question_mark = try c.addToken(.question_mark, "?");
1087 return c.addNode(.{
1088 .tag = .unwrap_optional,
1089 .main_token = period,
1090 .data = .{
1091 .lhs = operand,
1092 .rhs = question_mark,
1093 },
1094 });
1095 },
1061 else => return c.addNode(.{1096 else => return c.addNode(.{
1062 .tag = .identifier,1097 .tag = .identifier,
1063 .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),1098 .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}),
...@@ -1069,6 +1104,173 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1069,6 +1104,173 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1069 }1104 }
1070}1105}
10711106
1107fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1108 switch (node.tag()) {
1109 .null_literal,
1110 .undefined_literal,
1111 .true_literal,
1112 .false_literal,
1113 .return_void,
1114 .zero_literal,
1115 .one_literal,
1116 .void_type,
1117 .noreturn_type,
1118 .@"anytype",
1119 .div_trunc,
1120 .rem,
1121 .int_cast,
1122 .as,
1123 .truncate,
1124 .bit_cast,
1125 .float_cast,
1126 .float_to_int,
1127 .int_to_float,
1128 .int_to_enum,
1129 .int_to_ptr,
1130 .std_mem_zeroes,
1131 .std_math_Log2Int,
1132 .log2_int_type,
1133 .ptr_to_int,
1134 .enum_to_int,
1135 .sizeof,
1136 .alignof,
1137 .typeof,
1138 .std_meta_sizeof,
1139 .std_meta_cast,
1140 .std_mem_zeroinit,
1141 .integer_literal,
1142 .float_literal,
1143 .string_literal,
1144 .char_literal,
1145 .identifier,
1146 .field_access,
1147 .ptr_cast,
1148 .type,
1149 .array_access,
1150 .align_cast,
1151 => {
1152 // no grouping needed
1153 return renderNode(c, node);
1154 },
1155
1156 .negate,
1157 .negate_wrap,
1158 .bit_not,
1159 .opaque_literal,
1160 .not,
1161 .optional_type,
1162 .address_of,
1163 .unwrap,
1164 .deref,
1165 .empty_array,
1166 .block_single,
1167 .bool_to_int,
1168 .add,
1169 .add_wrap,
1170 .sub,
1171 .sub_wrap,
1172 .mul,
1173 .mul_wrap,
1174 .div,
1175 .shl,
1176 .shr,
1177 .mod,
1178 .@"and",
1179 .@"or",
1180 .xor,
1181 .less_than,
1182 .less_than_equal,
1183 .greater_than,
1184 .greater_than_equal,
1185 .equal,
1186 .not_equal,
1187 .bit_and,
1188 .bit_or,
1189 .bit_xor,
1190 .empty_block,
1191 .array_cat,
1192 .array_filler,
1193 .@"if",
1194 .call,
1195 .@"enum",
1196 .@"struct",
1197 .@"union",
1198 .array_init,
1199 .tuple,
1200 .container_init,
1201 .block,
1202 .c_pointer,
1203 .single_pointer,
1204 .array_type,
1205 => return c.addNode(.{
1206 .tag = .grouped_expression,
1207 .main_token = try c.addToken(.l_paren, "("),
1208 .data = .{
1209 .lhs = try renderNode(c, node),
1210 .rhs = try c.addToken(.r_paren, ")"),
1211 },
1212 }),
1213 .ellipsis3,
1214 .switch_prong,
1215 .warning,
1216 .var_decl,
1217 .func,
1218 .fail_decl,
1219 .arg_redecl,
1220 .alias,
1221 .var_simple,
1222 .pub_var_simple,
1223 .enum_redecl,
1224 .@"while",
1225 .@"switch",
1226 .@"break",
1227 .break_val,
1228 .pub_inline_fn,
1229 .discard,
1230 .@"continue",
1231 .@"return",
1232 .usingnamespace_builtins,
1233 .while_true,
1234 .if_not_break,
1235 .switch_else,
1236 .add_assign,
1237 .add_wrap_assign,
1238 .sub_assign,
1239 .sub_wrap_assign,
1240 .mul_assign,
1241 .mul_wrap_assign,
1242 .div_assign,
1243 .shl_assign,
1244 .shr_assign,
1245 .mod_assign,
1246 .and_assign,
1247 .or_assign,
1248 .xor_assign,
1249 .bit_and_assign,
1250 .bit_or_assign,
1251 .bit_xor_assign,
1252 .assign,
1253 => {
1254 // these should never appear in places where grouping might be needed.
1255 unreachable;
1256 },
1257 }
1258}
1259
1260fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
1261 const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data;
1262 const tok = try c.addToken(tok_tag, bytes);
1263 const operand = try renderNodeGrouped(c, payload);
1264 return c.addNode(.{
1265 .tag = tag,
1266 .main_token = tok,
1267 .data = .{
1268 .lhs = operand,
1269 .rhs = undefined,
1270 },
1271 });
1272}
1273
1072fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {1274fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
1073 const import_tok = try c.addToken(.builtin, "@import");1275 const import_tok = try c.addToken(.builtin, "@import");
1074 _ = try c.addToken(.l_paren, "(");1276 _ = try c.addToken(.l_paren, "(");