| ... | ... | @@ -848,8 +848,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 848 | 848 | break :blk try c.addIdentifier(some); |
| 849 | 849 | } else 0; |
| 850 | 850 | return c.addNode(.{ |
| 851 | | .tag = .identifier, |
| 852 | | .main_token = try c.addToken(.keyword_break, "break"), |
| 851 | .tag = .@"break", |
| 852 | .main_token = tok, |
| 853 | 853 | .data = .{ |
| 854 | 854 | .lhs = break_label, |
| 855 | 855 | .rhs = 0, |
| ... | ... | @@ -864,8 +864,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 864 | 864 | break :blk try c.addIdentifier(some); |
| 865 | 865 | } else 0; |
| 866 | 866 | return c.addNode(.{ |
| 867 | | .tag = .identifier, |
| 868 | | .main_token = try c.addToken(.keyword_break, "break"), |
| 867 | .tag = .@"break", |
| 868 | .main_token = tok, |
| 869 | 869 | .data = .{ |
| 870 | 870 | .lhs = break_label, |
| 871 | 871 | .rhs = try renderNode(c, payload.val), |
| ... | ... | @@ -1183,7 +1183,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1183 | 1183 | const l_brace = try c.addToken(.l_brace, "{"); |
| 1184 | 1184 | |
| 1185 | 1185 | const stmt = try renderNode(c, payload); |
| 1186 | | _ = try c.addToken(.semicolon, ";"); |
| 1186 | try addSemicolonIfNeeded(c, payload); |
| 1187 | 1187 | |
| 1188 | 1188 | _ = try c.addToken(.r_brace, "}"); |
| 1189 | 1189 | return c.addNode(.{ |
| ... | ... | @@ -1207,11 +1207,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1207 | 1207 | defer stmts.deinit(); |
| 1208 | 1208 | for (payload.stmts) |stmt| { |
| 1209 | 1209 | const res = try renderNode(c, stmt); |
| 1210 | | switch (stmt.tag()) { |
| 1211 | | .warning => continue, |
| 1212 | | .var_decl, .var_simple => {}, |
| 1213 | | else => _ = try c.addToken(.semicolon, ";"), |
| 1214 | | } |
| 1210 | if (res == 0) continue; |
| 1211 | try addSemicolonIfNeeded(c, stmt); |
| 1215 | 1212 | try stmts.append(res); |
| 1216 | 1213 | } |
| 1217 | 1214 | const span = try c.listToSpan(stmts.items); |
| ... | ... | @@ -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 | 1433 | else => return c.addNode(.{ |
| 1249 | 1434 | .tag = .identifier, |
| 1250 | 1435 | .main_token = try c.addTokenFmt(.identifier, "@\"TODO {}\"", .{node.tag()}), |
| ... | ... | @@ -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 | 1466 | fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1260 | 1467 | switch (node.tag()) { |
| 1261 | 1468 | .null_literal, |
| ... | ... | @@ -1303,19 +1510,19 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1303 | 1510 | .optional_type, |
| 1304 | 1511 | .c_pointer, |
| 1305 | 1512 | .single_pointer, |
| 1513 | .unwrap, |
| 1514 | .deref, |
| 1515 | .address_of, |
| 1516 | .not, |
| 1517 | .negate, |
| 1518 | .negate_wrap, |
| 1519 | .bit_not, |
| 1306 | 1520 | => { |
| 1307 | 1521 | // no grouping needed |
| 1308 | 1522 | return renderNode(c, node); |
| 1309 | 1523 | }, |
| 1310 | 1524 | |
| 1311 | | .negate, |
| 1312 | | .negate_wrap, |
| 1313 | | .bit_not, |
| 1314 | 1525 | .opaque_literal, |
| 1315 | | .not, |
| 1316 | | .address_of, |
| 1317 | | .unwrap, |
| 1318 | | .deref, |
| 1319 | 1526 | .empty_array, |
| 1320 | 1527 | .block_single, |
| 1321 | 1528 | .bool_to_int, |
| ... | ... | @@ -1407,13 +1614,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 1407 | 1614 | |
| 1408 | 1615 | fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex { |
| 1409 | 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 | 1617 | return c.addNode(.{ |
| 1413 | 1618 | .tag = tag, |
| 1414 | | .main_token = tok, |
| 1619 | .main_token = try c.addToken(tok_tag, bytes), |
| 1415 | 1620 | .data = .{ |
| 1416 | | .lhs = operand, |
| 1621 | .lhs = try renderNodeGrouped(c, payload), |
| 1417 | 1622 | .rhs = undefined, |
| 1418 | 1623 | }, |
| 1419 | 1624 | }); |
| ... | ... | @@ -1508,7 +1713,7 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { |
| 1508 | 1713 | .main_token = lparen, |
| 1509 | 1714 | .data = .{ |
| 1510 | 1715 | .lhs = lhs, |
| 1511 | | .rhs = try c.addExtra(std.zig.ast.Node.SubRange{ |
| 1716 | .rhs = try c.addExtra(NodeSubRange{ |
| 1512 | 1717 | .start = span.start, |
| 1513 | 1718 | .end = span.end, |
| 1514 | 1719 | }), |
| ... | ... | @@ -1728,7 +1933,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 1728 | 1933 | .tag = .fn_proto_multi, |
| 1729 | 1934 | .main_token = fn_token, |
| 1730 | 1935 | .data = .{ |
| 1731 | | .lhs = try c.addExtra(std.zig.ast.Node.SubRange{ |
| 1936 | .lhs = try c.addExtra(NodeSubRange{ |
| 1732 | 1937 | .start = span.start, |
| 1733 | 1938 | .end = span.end, |
| 1734 | 1939 | }), |