| author | |
| committer | |
| log | 31529f912bae6fae32d2a25e873dcc23ba4e96c4 |
| tree | 7f368f3c5ecc72810595956f1066e7a555630b44 |
| parent | a2f4adbd19ffea051a4fa0318bb0154e07660e55 |
3 files changed, 49 insertions(+), 4 deletions(-)
lib/std/zig/render.zig+24-1| ... | @@ -24,23 +24,28 @@ pub const Fixups = struct { | ... | @@ -24,23 +24,28 @@ pub const Fixups = struct { |
| 24 | gut_functions: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, | 24 | gut_functions: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, |
| 25 | /// These global declarations will be omitted. | 25 | /// These global declarations will be omitted. |
| 26 | omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, | 26 | omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, |
| 27 | /// These expressions will be replaced with `undefined`. | ||
| 28 | replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, | ||
| 27 | 29 | ||
| 28 | pub fn count(f: Fixups) usize { | 30 | pub fn count(f: Fixups) usize { |
| 29 | return f.unused_var_decls.count() + | 31 | return f.unused_var_decls.count() + |
| 30 | f.gut_functions.count() + | 32 | f.gut_functions.count() + |
| 31 | f.omit_nodes.count(); | 33 | f.omit_nodes.count() + |
| 34 | f.replace_nodes.count(); | ||
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | pub fn clearRetainingCapacity(f: *Fixups) void { | 37 | pub fn clearRetainingCapacity(f: *Fixups) void { |
| 35 | f.unused_var_decls.clearRetainingCapacity(); | 38 | f.unused_var_decls.clearRetainingCapacity(); |
| 36 | f.gut_functions.clearRetainingCapacity(); | 39 | f.gut_functions.clearRetainingCapacity(); |
| 37 | f.omit_nodes.clearRetainingCapacity(); | 40 | f.omit_nodes.clearRetainingCapacity(); |
| 41 | f.replace_nodes.clearRetainingCapacity(); | ||
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | pub fn deinit(f: *Fixups, gpa: Allocator) void { | 44 | pub fn deinit(f: *Fixups, gpa: Allocator) void { |
| 41 | f.unused_var_decls.deinit(gpa); | 45 | f.unused_var_decls.deinit(gpa); |
| 42 | f.gut_functions.deinit(gpa); | 46 | f.gut_functions.deinit(gpa); |
| 43 | f.omit_nodes.deinit(gpa); | 47 | f.omit_nodes.deinit(gpa); |
| 48 | f.replace_nodes.deinit(gpa); | ||
| 44 | f.* = undefined; | 49 | f.* = undefined; |
| 45 | } | 50 | } |
| 46 | }; | 51 | }; |
| ... | @@ -272,6 +277,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -272,6 +277,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 272 | const main_tokens = tree.nodes.items(.main_token); | 277 | const main_tokens = tree.nodes.items(.main_token); |
| 273 | const node_tags = tree.nodes.items(.tag); | 278 | const node_tags = tree.nodes.items(.tag); |
| 274 | const datas = tree.nodes.items(.data); | 279 | const datas = tree.nodes.items(.data); |
| 280 | if (r.fixups.replace_nodes.contains(node)) { | ||
| 281 | try ais.writer().writeAll("undefined"); | ||
| 282 | try renderOnlySpace(r, space); | ||
| 283 | return; | ||
| 284 | } | ||
| 275 | switch (node_tags[node]) { | 285 | switch (node_tags[node]) { |
| 276 | .identifier => { | 286 | .identifier => { |
| 277 | const token_index = main_tokens[node]; | 287 | const token_index = main_tokens[node]; |
| ... | @@ -2775,6 +2785,19 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space | ... | @@ -2775,6 +2785,19 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space |
| 2775 | } | 2785 | } |
| 2776 | } | 2786 | } |
| 2777 | 2787 | ||
| 2788 | fn renderOnlySpace(r: *Render, space: Space) Error!void { | ||
| 2789 | const ais = r.ais; | ||
| 2790 | switch (space) { | ||
| 2791 | .none => {}, | ||
| 2792 | .space => try ais.writer().writeByte(' '), | ||
| 2793 | .newline => try ais.insertNewline(), | ||
| 2794 | .comma => try ais.writer().writeAll(",\n"), | ||
| 2795 | .comma_space => try ais.writer().writeAll(", "), | ||
| 2796 | .semicolon => try ais.writer().writeAll(";\n"), | ||
| 2797 | .skip => unreachable, | ||
| 2798 | } | ||
| 2799 | } | ||
| 2800 | |||
| 2778 | const QuoteBehavior = enum { | 2801 | const QuoteBehavior = enum { |
| 2779 | preserve_when_shadowing, | 2802 | preserve_when_shadowing, |
| 2780 | eagerly_unquote, | 2803 | eagerly_unquote, |
src/reduce.zig+3| ... | @@ -253,6 +253,9 @@ fn transformationsToFixups( | ... | @@ -253,6 +253,9 @@ fn transformationsToFixups( |
| 253 | .delete_node => |decl_node| { | 253 | .delete_node => |decl_node| { |
| 254 | try fixups.omit_nodes.put(gpa, decl_node, {}); | 254 | try fixups.omit_nodes.put(gpa, decl_node, {}); |
| 255 | }, | 255 | }, |
| 256 | .replace_with_undef => |node| { | ||
| 257 | try fixups.replace_nodes.put(gpa, node, {}); | ||
| 258 | }, | ||
| 256 | }; | 259 | }; |
| 257 | } | 260 | } |
| 258 | 261 |
src/reduce/Walk.zig+22-3| ... | @@ -14,6 +14,8 @@ pub const Transformation = union(enum) { | ... | @@ -14,6 +14,8 @@ pub const Transformation = union(enum) { |
| 14 | gut_function: Ast.Node.Index, | 14 | gut_function: Ast.Node.Index, |
| 15 | /// Omit a global declaration. | 15 | /// Omit a global declaration. |
| 16 | delete_node: Ast.Node.Index, | 16 | delete_node: Ast.Node.Index, |
| 17 | /// Replace an expression with `undefined`. | ||
| 18 | replace_with_undef: Ast.Node.Index, | ||
| 17 | }; | 19 | }; |
| 18 | 20 | ||
| 19 | pub const Error = error{OutOfMemory}; | 21 | pub const Error = error{OutOfMemory}; |
| ... | @@ -279,7 +281,8 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -279,7 +281,8 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 279 | .local_var_decl, | 281 | .local_var_decl, |
| 280 | .simple_var_decl, | 282 | .simple_var_decl, |
| 281 | .aligned_var_decl, | 283 | .aligned_var_decl, |
| 282 | => try walkVarDecl(w, ast.fullVarDecl(lhs_node).?), | 284 | => try walkLocalVarDecl(w, ast.fullVarDecl(lhs_node).?), |
| 285 | |||
| 283 | else => try walkExpression(w, lhs_node), | 286 | else => try walkExpression(w, lhs_node), |
| 284 | } | 287 | } |
| 285 | } | 288 | } |
| ... | @@ -539,7 +542,7 @@ fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.Var | ... | @@ -539,7 +542,7 @@ fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.Var |
| 539 | return walkExpression(w, var_decl.ast.init_node); | 542 | return walkExpression(w, var_decl.ast.init_node); |
| 540 | } | 543 | } |
| 541 | 544 | ||
| 542 | fn walkVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { | 545 | fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { |
| 543 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name | 546 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name |
| 544 | 547 | ||
| 545 | if (var_decl.ast.type_node != 0) { | 548 | if (var_decl.ast.type_node != 0) { |
| ... | @@ -559,6 +562,9 @@ fn walkVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { | ... | @@ -559,6 +562,9 @@ fn walkVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { |
| 559 | } | 562 | } |
| 560 | 563 | ||
| 561 | assert(var_decl.ast.init_node != 0); | 564 | assert(var_decl.ast.init_node != 0); |
| 565 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | ||
| 566 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | ||
| 567 | } | ||
| 562 | 568 | ||
| 563 | return walkExpression(w, var_decl.ast.init_node); | 569 | return walkExpression(w, var_decl.ast.init_node); |
| 564 | } | 570 | } |
| ... | @@ -588,7 +594,7 @@ fn walkBlock( | ... | @@ -588,7 +594,7 @@ fn walkBlock( |
| 588 | .local_var_decl, | 594 | .local_var_decl, |
| 589 | .simple_var_decl, | 595 | .simple_var_decl, |
| 590 | .aligned_var_decl, | 596 | .aligned_var_decl, |
| 591 | => try walkVarDecl(w, ast.fullVarDecl(stmt).?), | 597 | => try walkLocalVarDecl(w, ast.fullVarDecl(stmt).?), |
| 592 | 598 | ||
| 593 | else => try walkExpression(w, stmt), | 599 | else => try walkExpression(w, stmt), |
| 594 | } | 600 | } |
| ... | @@ -872,3 +878,16 @@ fn isDiscardIdent(ast: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -872,3 +878,16 @@ fn isDiscardIdent(ast: *const Ast, node: Ast.Node.Index) bool { |
| 872 | else => return false, | 878 | else => return false, |
| 873 | } | 879 | } |
| 874 | } | 880 | } |
| 881 | |||
| 882 | fn isUndefinedIdent(ast: *const Ast, node: Ast.Node.Index) bool { | ||
| 883 | const node_tags = ast.nodes.items(.tag); | ||
| 884 | const main_tokens = ast.nodes.items(.main_token); | ||
| 885 | switch (node_tags[node]) { | ||
| 886 | .identifier => { | ||
| 887 | const token_index = main_tokens[node]; | ||
| 888 | const name_bytes = ast.tokenSlice(token_index); | ||
| 889 | return std.mem.eql(u8, name_bytes, "undefined"); | ||
| 890 | }, | ||
| 891 | else => return false, | ||
| 892 | } | ||
| 893 | } |