| ... | @@ -848,8 +848,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -848,8 +848,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 848 | break :blk try c.addIdentifier(some); | 848 | break :blk try c.addIdentifier(some); |
| 849 | } else 0; | 849 | } else 0; |
| 850 | return c.addNode(.{ | 850 | return c.addNode(.{ |
| 851 | .tag = .identifier, | 851 | .tag = .@"break", |
| 852 | .main_token = try c.addToken(.keyword_break, "break"), | 852 | .main_token = tok, |
| 853 | .data = .{ | 853 | .data = .{ |
| 854 | .lhs = break_label, | 854 | .lhs = break_label, |
| 855 | .rhs = 0, | 855 | .rhs = 0, |
| ... | @@ -864,8 +864,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -864,8 +864,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 864 | break :blk try c.addIdentifier(some); | 864 | break :blk try c.addIdentifier(some); |
| 865 | } else 0; | 865 | } else 0; |
| 866 | return c.addNode(.{ | 866 | return c.addNode(.{ |
| 867 | .tag = .identifier, | 867 | .tag = .@"break", |
| 868 | .main_token = try c.addToken(.keyword_break, "break"), | 868 | .main_token = tok, |
| 869 | .data = .{ | 869 | .data = .{ |
| 870 | .lhs = break_label, | 870 | .lhs = break_label, |
| 871 | .rhs = try renderNode(c, payload.val), | 871 | .rhs = try renderNode(c, payload.val), |
| ... | @@ -1183,7 +1183,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1183,7 +1183,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1183 | const l_brace = try c.addToken(.l_brace, "{"); | 1183 | const l_brace = try c.addToken(.l_brace, "{"); |
| 1184 | | 1184 | |
| 1185 | const stmt = try renderNode(c, payload); | 1185 | const stmt = try renderNode(c, payload); |
| 1186 | _ = try c.addToken(.semicolon, ";"); | 1186 | try addSemicolonIfNeeded(c, payload); |
| 1187 | | 1187 | |
| 1188 | _ = try c.addToken(.r_brace, "}"); | 1188 | _ = try c.addToken(.r_brace, "}"); |
| 1189 | return c.addNode(.{ | 1189 | return c.addNode(.{ |
| ... | @@ -1207,11 +1207,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1207,11 +1207,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1207 | defer stmts.deinit(); | 1207 | defer stmts.deinit(); |
| 1208 | for (payload.stmts) |stmt| { | 1208 | for (payload.stmts) |stmt| { |
| 1209 | const res = try renderNode(c, stmt); | 1209 | const res = try renderNode(c, stmt); |
| 1210 | switch (stmt.tag()) { | 1210 | if (res == 0) continue; |
| 1211 | .warning => continue, | 1211 | try addSemicolonIfNeeded(c, stmt); |
| 1212 | .var_decl, .var_simple => {}, | | |
| 1213 | else => _ = try c.addToken(.semicolon, ";"), | | |
| 1214 | } | | |
| 1215 | try stmts.append(res); | 1212 | try stmts.append(res); |
| 1216 | } | 1213 | } |
| 1217 | const span = try c.listToSpan(stmts.items); | 1214 | const span = try c.listToSpan(stmts.items); |
| ... | @@ -1245,6 +1242,194 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1245,6 +1242,194 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1245 | }, | 1242 | }, |
| 1246 | }); | 1243 | }); |
| 1247 | }, | 1244 | }, |
| | 1245 | .@"while" => { |
| | 1246 | const payload = node.castTag(.@"while").?.data; |
| | 1247 | const while_tok = try c.addToken(.keyword_while, "while"); |
| | 1248 | _ = try c.addToken(.l_paren, "("); |
| | 1249 | const cond = try renderNode(c, payload.cond); |
| | 1250 | _ = try c.addToken(.r_paren, ")"); |
| | 1251 | |
| | 1252 | const cont_expr = if (payload.cont_expr) |some| blk: { |
| | 1253 | _ = try c.addToken(.colon, ":"); |
| | 1254 | _ = try c.addToken(.l_paren, "("); |
| | 1255 | const res = try renderNode(c, some); |
| | 1256 | _ = try c.addToken(.r_paren, ")"); |
| | 1257 | break :blk res; |
| | 1258 | } else 0; |
| | 1259 | const body = try renderNode(c, payload.body); |
| | 1260 | |
| | 1261 | if (cont_expr == 0) { |
| | 1262 | return c.addNode(.{ |
| | 1263 | .tag = .while_simple, |
| | 1264 | .main_token = while_tok, |
| | 1265 | .data = .{ |
| | 1266 | .lhs = cond, |
| | 1267 | .rhs = body, |
| | 1268 | }, |
| | 1269 | }); |
| | 1270 | } else { |
| | 1271 | return c.addNode(.{ |
| | 1272 | .tag = .while_cont, |
| | 1273 | .main_token = while_tok, |
| | 1274 | .data = .{ |
| | 1275 | .lhs = cond, |
| | 1276 | .rhs = try c.addExtra(std.zig.ast.Node.WhileCont{ |
| | 1277 | .cont_expr = cont_expr, |
| | 1278 | .then_expr = body, |
| | 1279 | }), |
| | 1280 | }, |
| | 1281 | }); |
| | 1282 | } |
| | 1283 | }, |
| | 1284 | .while_true => { |
| | 1285 | const payload = node.castTag(.while_true).?.data; |
| | 1286 | const while_tok = try c.addToken(.keyword_while, "while"); |
| | 1287 | _ = try c.addToken(.l_paren, "("); |
| | 1288 | const cond = try c.addNode(.{ |
| | 1289 | .tag = .true_literal, |
| | 1290 | .main_token = try c.addToken(.keyword_true, "true"), |
| | 1291 | .data = undefined, |
| | 1292 | }); |
| | 1293 | _ = try c.addToken(.r_paren, ")"); |
| | 1294 | const body = try renderNode(c, payload); |
| | 1295 | |
| | 1296 | return c.addNode(.{ |
| | 1297 | .tag = .while_simple, |
| | 1298 | .main_token = while_tok, |
| | 1299 | .data = .{ |
| | 1300 | .lhs = cond, |
| | 1301 | .rhs = body, |
| | 1302 | }, |
| | 1303 | }); |
| | 1304 | }, |
| | 1305 | .@"if" => { |
| | 1306 | const payload = node.castTag(.@"if").?.data; |
| | 1307 | const if_tok = try c.addToken(.keyword_if, "if"); |
| | 1308 | _ = try c.addToken(.l_paren, "("); |
| | 1309 | const cond = try renderNode(c, payload.cond); |
| | 1310 | _ = try c.addToken(.r_paren, ")"); |
| | 1311 | |
| | 1312 | const then_expr = try renderNode(c, payload.then); |
| | 1313 | const else_node = payload.@"else" orelse return c.addNode(.{ |
| | 1314 | .tag = .if_simple, |
| | 1315 | .main_token = if_tok, |
| | 1316 | .data = .{ |
| | 1317 | .lhs = cond, |
| | 1318 | .rhs = then_expr, |
| | 1319 | }, |
| | 1320 | }); |
| | 1321 | _ = try c.addToken(.keyword_else, "else"); |
| | 1322 | const else_expr = try renderNode(c, else_node); |
| | 1323 | |
| | 1324 | return c.addNode(.{ |
| | 1325 | .tag = .@"if", |
| | 1326 | .main_token = if_tok, |
| | 1327 | .data = .{ |
| | 1328 | .lhs = cond, |
| | 1329 | .rhs = try c.addExtra(std.zig.ast.Node.If{ |
| | 1330 | .then_expr = then_expr, |
| | 1331 | .else_expr = else_expr, |
| | 1332 | }), |
| | 1333 | }, |
| | 1334 | }); |
| | 1335 | }, |
| | 1336 | .if_not_break => { |
| | 1337 | const payload = node.castTag(.if_not_break).?.data; |
| | 1338 | const if_tok = try c.addToken(.keyword_if, "if"); |
| | 1339 | _ = try c.addToken(.l_paren, "("); |
| | 1340 | const cond = try c.addNode(.{ |
| | 1341 | .tag = .bool_not, |
| | 1342 | .main_token = try c.addToken(.bang, "!"), |
| | 1343 | .data = .{ |
| | 1344 | .lhs = try renderNodeGrouped(c, payload), |
| | 1345 | .rhs = undefined, |
| | 1346 | }, |
| | 1347 | }); |
| | 1348 | _ = try c.addToken(.r_paren, ")"); |
| | 1349 | const then_expr = try c.addNode(.{ |
| | 1350 | .tag = .@"break", |
| | 1351 | .main_token = try c.addToken(.keyword_break, "break"), |
| | 1352 | .data = .{ |
| | 1353 | .lhs = 0, |
| | 1354 | .rhs = 0, |
| | 1355 | }, |
| | 1356 | }); |
| | 1357 | |
| | 1358 | return c.addNode(.{ |
| | 1359 | .tag = .if_simple, |
| | 1360 | .main_token = if_tok, |
| | 1361 | .data = .{ |
| | 1362 | .lhs = cond, |
| | 1363 | .rhs = then_expr, |
| | 1364 | }, |
| | 1365 | }); |
| | 1366 | }, |
| | 1367 | .@"switch" => { |
| | 1368 | const payload = node.castTag(.@"switch").?.data; |
| | 1369 | const switch_tok = try c.addToken(.keyword_switch, "switch"); |
| | 1370 | _ = try c.addToken(.l_paren, "("); |
| | 1371 | const cond = try renderNode(c, payload.cond); |
| | 1372 | _ = try c.addToken(.r_paren, ")"); |
| | 1373 | |
| | 1374 | _ = try c.addToken(.l_brace, "{"); |
| | 1375 | var cases = try c.gpa.alloc(NodeIndex, payload.cases.len); |
| | 1376 | defer c.gpa.free(cases); |
| | 1377 | for (payload.cases) |case, i| { |
| | 1378 | if (i != 0) _ = try c.addToken(.comma, ","); |
| | 1379 | cases[i] = try renderNode(c, case); |
| | 1380 | } |
| | 1381 | const span = try c.listToSpan(cases); |
| | 1382 | _ = try c.addToken(.r_brace, "}"); |
| | 1383 | return c.addNode(.{ |
| | 1384 | .tag = .@"switch", |
| | 1385 | .main_token = switch_tok, |
| | 1386 | .data = .{ |
| | 1387 | .lhs = cond, |
| | 1388 | .rhs = try c.addExtra(NodeSubRange{ |
| | 1389 | .start = span.start, |
| | 1390 | .end = span.end, |
| | 1391 | }), |
| | 1392 | }, |
| | 1393 | }); |
| | 1394 | }, |
| | 1395 | .switch_else => { |
| | 1396 | const payload = node.castTag(.switch_else).?.data; |
| | 1397 | _ = try c.addToken(.keyword_else, "else"); |
| | 1398 | return c.addNode(.{ |
| | 1399 | .tag = .switch_case_one, |
| | 1400 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), |
| | 1401 | .data = .{ |
| | 1402 | .lhs = 0, |
| | 1403 | .rhs = try renderNode(c, payload), |
| | 1404 | }, |
| | 1405 | }); |
| | 1406 | }, |
| | 1407 | .switch_prong => { |
| | 1408 | const payload = node.castTag(.switch_prong).?.data; |
| | 1409 | const item = try renderNode(c, payload.lhs); |
| | 1410 | return c.addNode(.{ |
| | 1411 | .tag = .switch_case_one, |
| | 1412 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), |
| | 1413 | .data = .{ |
| | 1414 | .lhs = item, |
| | 1415 | .rhs = try renderNode(c, payload.rhs), |
| | 1416 | }, |
| | 1417 | }); |
| | 1418 | }, |
| | 1419 | .opaque_literal => { |
| | 1420 | const opaque_tok = try c.addToken(.keyword_opaque, "opaque"); |
| | 1421 | _ = try c.addToken(.l_brace, "{"); |
| | 1422 | _ = try c.addToken(.r_brace, "}"); |
| | 1423 | |
| | 1424 | return c.addNode(.{ |
| | 1425 | .tag = .container_decl_two, |
| | 1426 | .main_token = opaque_tok, |
| | 1427 | .data = .{ |
| | 1428 | .lhs = 0, |
| | 1429 | .rhs = 0, |
| | 1430 | }, |
| | 1431 | }); |
| | 1432 | }, |
| 1248 | else => return c.addNode(.{ | 1433 | else => return c.addNode(.{ |
| 1249 | .tag = .identifier, | 1434 | .tag = .identifier, |
| 1250 | .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}), | 1435 | .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}), |
| ... | @@ -1256,6 +1441,28 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1256,6 +1441,28 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1256 | } | 1441 | } |
| 1257 | } | 1442 | } |
| 1258 | | 1443 | |
| | 1444 | fn addSemicolonIfNeeded(c: *Context, node: Node) !void { |
| | 1445 | switch (node.tag()) { |
| | 1446 | .warning => unreachable, |
| | 1447 | .var_decl, .var_simple, .block, .empty_block, .@"switch" => {}, |
| | 1448 | .while_true => { |
| | 1449 | const payload = node.castTag(.while_true).?.data; |
| | 1450 | return addSemicolonIfNeeded(c, payload); |
| | 1451 | }, |
| | 1452 | .@"while" => { |
| | 1453 | const payload = node.castTag(.@"while").?.data; |
| | 1454 | return addSemicolonIfNeeded(c, payload.body); |
| | 1455 | }, |
| | 1456 | .@"if" => { |
| | 1457 | const payload = node.castTag(.@"if").?.data; |
| | 1458 | if (payload.@"else") |some| |
| | 1459 | return addSemicolonIfNeeded(c, some); |
| | 1460 | return addSemicolonIfNeeded(c, payload.then); |
| | 1461 | }, |
| | 1462 | else => _ = try c.addToken(.semicolon, ";"), |
| | 1463 | } |
| | 1464 | } |
| | 1465 | |
| 1259 | fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | 1466 | fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1260 | switch (node.tag()) { | 1467 | switch (node.tag()) { |
| 1261 | .null_literal, | 1468 | .null_literal, |
| ... | @@ -1303,19 +1510,19 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -1303,19 +1510,19 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1303 | .optional_type, | 1510 | .optional_type, |
| 1304 | .c_pointer, | 1511 | .c_pointer, |
| 1305 | .single_pointer, | 1512 | .single_pointer, |
| | 1513 | .unwrap, |
| | 1514 | .deref, |
| | 1515 | .address_of, |
| | 1516 | .not, |
| | 1517 | .negate, |
| | 1518 | .negate_wrap, |
| | 1519 | .bit_not, |
| 1306 | => { | 1520 | => { |
| 1307 | // no grouping needed | 1521 | // no grouping needed |
| 1308 | return renderNode(c, node); | 1522 | return renderNode(c, node); |
| 1309 | }, | 1523 | }, |
| 1310 | | 1524 | |
| 1311 | .negate, | | |
| 1312 | .negate_wrap, | | |
| 1313 | .bit_not, | | |
| 1314 | .opaque_literal, | 1525 | .opaque_literal, |
| 1315 | .not, | | |
| 1316 | .address_of, | | |
| 1317 | .unwrap, | | |
| 1318 | .deref, | | |
| 1319 | .empty_array, | 1526 | .empty_array, |
| 1320 | .block_single, | 1527 | .block_single, |
| 1321 | .bool_to_int, | 1528 | .bool_to_int, |
| ... | @@ -1407,13 +1614,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -1407,13 +1614,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1407 | | 1614 | |
| 1408 | fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { | 1615 | fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { |
| 1409 | const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data; | 1616 | const payload = @fieldParentPtr(Payload.UnOp, "base", node.ptr_otherwise).data; |
| 1410 | const tok = try c.addToken(tok_tag, bytes); | | |
| 1411 | const operand = try renderNodeGrouped(c, payload); | | |
| 1412 | return c.addNode(.{ | 1617 | return c.addNode(.{ |
| 1413 | .tag = tag, | 1618 | .tag = tag, |
| 1414 | .main_token = tok, | 1619 | .main_token = try c.addToken(tok_tag, bytes), |
| 1415 | .data = .{ | 1620 | .data = .{ |
| 1416 | .lhs = operand, | 1621 | .lhs = try renderNodeGrouped(c, payload), |
| 1417 | .rhs = undefined, | 1622 | .rhs = undefined, |
| 1418 | }, | 1623 | }, |
| 1419 | }); | 1624 | }); |
| ... | @@ -1508,7 +1713,7 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { | ... | @@ -1508,7 +1713,7 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { |
| 1508 | .main_token = lparen, | 1713 | .main_token = lparen, |
| 1509 | .data = .{ | 1714 | .data = .{ |
| 1510 | .lhs = lhs, | 1715 | .lhs = lhs, |
| 1511 | .rhs = try c.addExtra(std.zig.ast.Node.SubRange{ | 1716 | .rhs = try c.addExtra(NodeSubRange{ |
| 1512 | .start = span.start, | 1717 | .start = span.start, |
| 1513 | .end = span.end, | 1718 | .end = span.end, |
| 1514 | }), | 1719 | }), |
| ... | @@ -1728,7 +1933,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -1728,7 +1933,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 1728 | .tag = .fn_proto_multi, | 1933 | .tag = .fn_proto_multi, |
| 1729 | .main_token = fn_token, | 1934 | .main_token = fn_token, |
| 1730 | .data = .{ | 1935 | .data = .{ |
| 1731 | .lhs = try c.addExtra(std.zig.ast.Node.SubRange{ | 1936 | .lhs = try c.addExtra(NodeSubRange{ |
| 1732 | .start = span.start, | 1937 | .start = span.start, |
| 1733 | .end = span.end, | 1938 | .end = span.end, |
| 1734 | }), | 1939 | }), |