authorchloe caruso <git@paperclover.net> 2024-05-20 13:45:39-07:00
committerchloe caruso <git@paperclover.net> 2024-05-20 13:46:36-07:00
logf102fe93319b8fcc9b88bdef0fa69bda967d15a7
treeb7ed26e4570086a94fb865e70f76176583a46e54
parentcf749893b592c342cd21fe524c7c45456876cae3

perf: use more buffered writers


9 files changed, 175 insertions(+), 29 deletions(-)

CHANGELOG.md+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1## 0.1.1-alpha1## 0.1.1-alpha
22
3- introduce `Report` and show errors during Transform.3- introduce `Report` and show errors during Tokenize, Parse, and Transform.
4- add flag --dump-ir for enabling ir dumps4- add flag --dump-ir for enabling ir dumps
55
6## 0.1.0-alpha6## 0.1.0-alpha
build.zig+12
...@@ -6,12 +6,23 @@ pub fn build(b: *std.Build) void {...@@ -6,12 +6,23 @@ pub fn build(b: *std.Build) void {
6 const target = b.standardTargetOptions(.{});6 const target = b.standardTargetOptions(.{});
7 const optimize = b.standardOptimizeOption(.{});7 const optimize = b.standardOptimizeOption(.{});
88
9 const tracing = b.option(enum {
10 none,
11 spall,
12 chrome,
13 log,
14 }, "trace", "Enable tracing") orelse .none;
15
9 const dep_opts = .{ .target = target, .optimize = optimize };16 const dep_opts = .{ .target = target, .optimize = optimize };
1017
11 const zg = b.dependency("zg", dep_opts);18 const zg = b.dependency("zg", dep_opts);
12 const tracer = b.dependency("tracer", dep_opts);19 const tracer = b.dependency("tracer", dep_opts);
13 // const ada = b.dependency("ada", dep_opts);20 // const ada = b.dependency("ada", dep_opts);
1421
22 const opts = b.addOptions();
23 opts.addOption([]const u8, "tracing", @tagName(tracing));
24 const opts_mod = opts.createModule();
25
15 const exe = b.addExecutable(.{26 const exe = b.addExecutable(.{
16 .name = "compiler",27 .name = "compiler",
17 .root_source_file = b.path("src/compiler/main.zig"),28 .root_source_file = b.path("src/compiler/main.zig"),
...@@ -20,6 +31,7 @@ pub fn build(b: *std.Build) void {...@@ -20,6 +31,7 @@ pub fn build(b: *std.Build) void {
20 });31 });
21 b.installArtifact(exe);32 b.installArtifact(exe);
2233
34 exe.root_module.addImport("build_options", opts_mod);
23 exe.root_module.addImport("zg:PropsData", zg.module("PropsData"));35 exe.root_module.addImport("zg:PropsData", zg.module("PropsData"));
24 exe.root_module.addImport("tracer", tracer.module("tracer"));36 exe.root_module.addImport("tracer", tracer.module("tracer"));
25 // if (!target.result.isWasm()) {37 // if (!target.result.isWasm()) {
demo.txt+25-1
...@@ -1 +1,25 @@...@@ -1 +1,25 @@
1no "waay1let print = @js("console").log;
2
3fn doThing(x: float, y: float) -> float {
4 let math = if x < y {
5 x - y
6 } else b: {
7 let sum = x + y;
8 if sum > 100 {
9 break :b sum;
10 }
11 if x == y {
12 return 5;
13 }
14 sum * -sum
15 };
16 if x == y {
17 return 5;
18 }
19 let divisor = if x > 10 { 2 } else { 3 };
20 math / divisor
21}
22
23print(doThing(1, 6));
24print(doThing(6, 4));
25print(doThing(100, 52));
src/compiler/JsLink.zig+37
...@@ -19,6 +19,8 @@ pub fn linkJsCode(...@@ -19,6 +19,8 @@ pub fn linkJsCode(
19 decls: []const Decl.Index,19 decls: []const Decl.Index,
20 writer: anytype,20 writer: anytype,
21) !void {21) !void {
22 var t = tracer.trace(@src());
23 defer t.end();
2224
23 // Arena allocator is used for the main flow25 // Arena allocator is used for the main flow
24 var link: JsLink = .{ .comp = comp };26 var link: JsLink = .{ .comp = comp };
...@@ -79,6 +81,9 @@ pub fn linkJsCode(...@@ -79,6 +81,9 @@ pub fn linkJsCode(
79}81}
8082
81fn deinit(link: *JsLink) void {83fn deinit(link: *JsLink) void {
84 var t = tracer.trace(@src());
85 defer t.end();
86
82 defer link.* = undefined;87 defer link.* = undefined;
83 link.decls.deinit(link.comp.gpa);88 link.decls.deinit(link.comp.gpa);
84 link.link_strings.deinit(link.comp.gpa);89 link.link_strings.deinit(link.comp.gpa);
...@@ -86,6 +91,9 @@ fn deinit(link: *JsLink) void {...@@ -86,6 +91,9 @@ fn deinit(link: *JsLink) void {
86}91}
8792
88fn reserveExternSymbol(link: *JsLink, extern_symbol: String.WithLen) !void {93fn reserveExternSymbol(link: *JsLink, extern_symbol: String.WithLen) !void {
94 var t = tracer.trace(@src());
95 defer t.end();
96
89 const name = extern_symbol.toSlice(&link.comp.intern_pool);97 const name = extern_symbol.toSlice(&link.comp.intern_pool);
90 const gop = try link.link_strings.getOrPutContextAdapted(98 const gop = try link.link_strings.getOrPutContextAdapted(
91 link.comp.gpa,99 link.comp.gpa,
...@@ -104,12 +112,18 @@ fn reserveExternSymbol(link: *JsLink, extern_symbol: String.WithLen) !void {...@@ -104,12 +112,18 @@ fn reserveExternSymbol(link: *JsLink, extern_symbol: String.WithLen) !void {
104}112}
105113
106fn appendLinkString(link: *JsLink, string: []const u8) !LinkString {114fn appendLinkString(link: *JsLink, string: []const u8) !LinkString {
115 var t = tracer.trace(@src());
116 defer t.end();
117
107 const start = link.string_bytes.items.len;118 const start = link.string_bytes.items.len;
108 try link.string_bytes.appendSlice(link.comp.gpa, string);119 try link.string_bytes.appendSlice(link.comp.gpa, string);
109 return .{ .start = @intCast(start), .len = @intCast(string.len) };120 return .{ .start = @intCast(start), .len = @intCast(string.len) };
110}121}
111122
112fn declIdentifier(link: *const JsLink, decl: Decl.Index) []const u8 {123fn declIdentifier(link: *const JsLink, decl: Decl.Index) []const u8 {
124 var t = tracer.trace(@src());
125 defer t.end();
126
113 return (link.decls.get(decl) orelse if (std.debug.runtime_safety) {127 return (link.decls.get(decl) orelse if (std.debug.runtime_safety) {
114 std.debug.panic("Decl {d} ({}) is not present in link decl map", .{128 std.debug.panic("Decl {d} ({}) is not present in link decl map", .{
115 @intFromEnum(decl),129 @intFromEnum(decl),
...@@ -119,6 +133,9 @@ fn declIdentifier(link: *const JsLink, decl: Decl.Index) []const u8 {...@@ -119,6 +133,9 @@ fn declIdentifier(link: *const JsLink, decl: Decl.Index) []const u8 {
119}133}
120134
121fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {135fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {
136 var t = tracer.trace(@src());
137 defer t.end();
138
122 try writer.writeAll("let ");139 try writer.writeAll("let ");
123 try writer.writeAll(link.declIdentifier(decl_index));140 try writer.writeAll(link.declIdentifier(decl_index));
124 try writer.writeAll(" = ");141 try writer.writeAll(" = ");
...@@ -137,6 +154,9 @@ fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {...@@ -137,6 +154,9 @@ fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {
137}154}
138155
139fn printDeclContents(link: *JsLink, tree: *const JsTree, writer: anytype) !void {156fn printDeclContents(link: *JsLink, tree: *const JsTree, writer: anytype) !void {
157 var t = tracer.trace(@src());
158 defer t.end();
159
140 for (tree.mainStatements()) |stmt| {160 for (tree.mainStatements()) |stmt| {
141 try link.printExpr(tree, stmt, writer);161 try link.printExpr(tree, stmt, writer);
142 try writer.writeAll(";\n");162 try writer.writeAll(";\n");
...@@ -144,6 +164,9 @@ fn printDeclContents(link: *JsLink, tree: *const JsTree, writer: anytype) !void...@@ -144,6 +164,9 @@ fn printDeclContents(link: *JsLink, tree: *const JsTree, writer: anytype) !void
144}164}
145165
146fn printBlockContents(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer: anytype) !void {166fn printBlockContents(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer: anytype) !void {
167 var t = tracer.trace(@src());
168 defer t.end();
169
147 assert(list.slice(tree).len > 0);170 assert(list.slice(tree).len > 0);
148 for (list.slice(tree)) |stmt| {171 for (list.slice(tree)) |stmt| {
149 try link.printExpr(tree, stmt, writer);172 try link.printExpr(tree, stmt, writer);
...@@ -158,6 +181,9 @@ fn printBlockContents(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList...@@ -158,6 +181,9 @@ fn printBlockContents(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList
158}181}
159182
160fn printBlock(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer: anytype) !void {183fn printBlock(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer: anytype) !void {
184 var t = tracer.trace(@src());
185 defer t.end();
186
161 if (list.len != 1) {187 if (list.len != 1) {
162 try writer.writeAll("{");188 try writer.writeAll("{");
163 try link.printBlockContents(tree, list, writer);189 try link.printBlockContents(tree, list, writer);
...@@ -168,6 +194,9 @@ fn printBlock(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer...@@ -168,6 +194,9 @@ fn printBlock(link: *JsLink, tree: *const JsTree, list: JsTree.IndexList, writer
168}194}
169195
170fn printExpr(link: *JsLink, tree: *const JsTree, node: Node.Index, writer: anytype) @TypeOf(writer).Error!void {196fn printExpr(link: *JsLink, tree: *const JsTree, node: Node.Index, writer: anytype) @TypeOf(writer).Error!void {
197 var t = tracer.trace(@src());
198 defer t.end();
199
171 switch (tree.nodeTag(node)) {200 switch (tree.nodeTag(node)) {
172 else => |tag| std.debug.panic("TODO: printExpr .{s}", .{@tagName(tag)}),201 else => |tag| std.debug.panic("TODO: printExpr .{s}", .{@tagName(tag)}),
173 .root => unreachable,202 .root => unreachable,
...@@ -328,11 +357,17 @@ fn printExpr(link: *JsLink, tree: *const JsTree, node: Node.Index, writer: anyty...@@ -328,11 +357,17 @@ fn printExpr(link: *JsLink, tree: *const JsTree, node: Node.Index, writer: anyty
328}357}
329358
330fn printLocal(link: *JsLink, local: JsTree.LocalIndex, writer: anytype) !void {359fn printLocal(link: *JsLink, local: JsTree.LocalIndex, writer: anytype) !void {
360 var t = tracer.trace(@src());
361 defer t.end();
362
331 _ = link; // todo: be smarter about this363 _ = link; // todo: be smarter about this
332 try writer.print("v{d}", .{local});364 try writer.print("v{d}", .{local});
333}365}
334366
335fn printLabelIdentifier(link: *JsLink, local: JsTree.LocalIndex, writer: anytype) !void {367fn printLabelIdentifier(link: *JsLink, local: JsTree.LocalIndex, writer: anytype) !void {
368 var t = tracer.trace(@src());
369 defer t.end();
370
336 _ = link; // todo: be smarter about this371 _ = link; // todo: be smarter about this
337 try writer.print("label{d}", .{local});372 try writer.print("label{d}", .{local});
338}373}
...@@ -452,3 +487,5 @@ const Node = JsTree.Node;...@@ -452,3 +487,5 @@ const Node = JsTree.Node;
452487
453const InternPool = @import("InternPool.zig");488const InternPool = @import("InternPool.zig");
454const String = InternPool.String;489const String = InternPool.String;
490
491const tracer = @import("tracer");
src/compiler/JsNodeGen.zig+46
...@@ -29,6 +29,9 @@ const MapEntry = union {...@@ -29,6 +29,9 @@ const MapEntry = union {
29};29};
3030
31pub fn init(gpa: Allocator, arena: Allocator, ip: *const InternPool, air: *const Air) !JsNodeGen {31pub fn init(gpa: Allocator, arena: Allocator, ip: *const InternPool, air: *const Air) !JsNodeGen {
32 const t = tracer.trace(@src());
33 defer t.end();
34
32 const air_node_map = try arena.alloc(MapEntry, air.insts.len);35 const air_node_map = try arena.alloc(MapEntry, air.insts.len);
33 if (std.debug.runtime_safety) {36 if (std.debug.runtime_safety) {
34 @memset(air_node_map, .{ .none = {} });37 @memset(air_node_map, .{ .none = {} });
...@@ -52,6 +55,9 @@ pub fn init(gpa: Allocator, arena: Allocator, ip: *const InternPool, air: *const...@@ -52,6 +55,9 @@ pub fn init(gpa: Allocator, arena: Allocator, ip: *const InternPool, air: *const
52}55}
5356
54pub fn deinit(c: *JsNodeGen) void {57pub fn deinit(c: *JsNodeGen) void {
58 const t = tracer.trace(@src());
59 defer t.end();
60
55 defer c.* = undefined;61 defer c.* = undefined;
56 c.nodes.deinit(c.gpa);62 c.nodes.deinit(c.gpa);
57 c.extra.deinit(c.gpa);63 c.extra.deinit(c.gpa);
...@@ -62,6 +68,9 @@ pub fn deinit(c: *JsNodeGen) void {...@@ -62,6 +68,9 @@ pub fn deinit(c: *JsNodeGen) void {
62}68}
6369
64pub fn finalize(c: *JsNodeGen) !JsTree {70pub fn finalize(c: *JsNodeGen) !JsTree {
71 const t = tracer.trace(@src());
72 defer t.end();
73
65 // todo: errdefer will probably leave memory in a fully invalid state74 // todo: errdefer will probably leave memory in a fully invalid state
66 try c.nodes.setCapacity(c.gpa, c.nodes.len);75 try c.nodes.setCapacity(c.gpa, c.nodes.len);
6776
...@@ -87,6 +96,9 @@ pub fn finalize(c: *JsNodeGen) !JsTree {...@@ -87,6 +96,9 @@ pub fn finalize(c: *JsNodeGen) !JsTree {
87}96}
8897
89pub fn build(c: *JsNodeGen) !void {98pub fn build(c: *JsNodeGen) !void {
99 const t = tracer.trace(@src());
100 defer t.end();
101
90 assert(c.air.instTag(.main_block) == .block);102 assert(c.air.instTag(.main_block) == .block);
91 const statements = c.air.instData(.block, .main_block).slice(c.air);103 const statements = c.air.instData(.block, .main_block).slice(c.air);
92104
...@@ -117,6 +129,9 @@ pub fn build(c: *JsNodeGen) !void {...@@ -117,6 +129,9 @@ pub fn build(c: *JsNodeGen) !void {
117}129}
118130
119fn codeGenInst(c: *JsNodeGen, inst: Air.Inst.Index) Error!void {131fn codeGenInst(c: *JsNodeGen, inst: Air.Inst.Index) Error!void {
132 const t = tracer.traceFmt(@src(), "#{d} {s}", .{ @intFromEnum(inst), @tagName(c.air.instTag(inst)) });
133 defer t.end();
134
120 switch (c.air.instTag(inst)) {135 switch (c.air.instTag(inst)) {
121 .arg => unreachable, // codegen must skip over these instructions.136 .arg => unreachable, // codegen must skip over these instructions.
122137
...@@ -290,6 +305,9 @@ fn codeGenInst(c: *JsNodeGen, inst: Air.Inst.Index) Error!void {...@@ -290,6 +305,9 @@ fn codeGenInst(c: *JsNodeGen, inst: Air.Inst.Index) Error!void {
290}305}
291306
292fn markExpression(c: *JsNodeGen, inst: Air.Inst.Index, node: Node.Index) !void {307fn markExpression(c: *JsNodeGen, inst: Air.Inst.Index, node: Node.Index) !void {
308 const t = tracer.trace(@src());
309 defer t.end();
310
293 const flags: Air.Flags = c.air.instFlags(inst);311 const flags: Air.Flags = c.air.instFlags(inst);
294 const i = @intFromEnum(inst);312 const i = @intFromEnum(inst);
295 switch (flags.uses) {313 switch (flags.uses) {
...@@ -314,6 +332,9 @@ fn markExpression(c: *JsNodeGen, inst: Air.Inst.Index, node: Node.Index) !void {...@@ -314,6 +332,9 @@ fn markExpression(c: *JsNodeGen, inst: Air.Inst.Index, node: Node.Index) !void {
314}332}
315333
316fn fetchExpression(c: *JsNodeGen, inst: Air.Inst.Ref) !Node.Index {334fn fetchExpression(c: *JsNodeGen, inst: Air.Inst.Ref) !Node.Index {
335 const t = tracer.trace(@src());
336 defer t.end();
337
317 return switch (inst.unwrap()) {338 return switch (inst.unwrap()) {
318 .value => |v| c.valueToExpression(v),339 .value => |v| c.valueToExpression(v),
319 .inst => |index| {340 .inst => |index| {
...@@ -332,6 +353,9 @@ fn fetchExpression(c: *JsNodeGen, inst: Air.Inst.Ref) !Node.Index {...@@ -332,6 +353,9 @@ fn fetchExpression(c: *JsNodeGen, inst: Air.Inst.Ref) !Node.Index {
332}353}
333354
334fn valueToExpression(c: *JsNodeGen, v: Value) !Node.Index {355fn valueToExpression(c: *JsNodeGen, v: Value) !Node.Index {
356 const t = tracer.trace(@src());
357 defer t.end();
358
335 const intern_tag = c.ip.items.items(.tag)[@intFromEnum(v.toIntern())];359 const intern_tag = c.ip.items.items(.tag)[@intFromEnum(v.toIntern())];
336 switch (intern_tag) {360 switch (intern_tag) {
337 .removed => unreachable, // UAF361 .removed => unreachable, // UAF
...@@ -352,6 +376,9 @@ fn valueToExpression(c: *JsNodeGen, v: Value) !Node.Index {...@@ -352,6 +376,9 @@ fn valueToExpression(c: *JsNodeGen, v: Value) !Node.Index {
352}376}
353377
354fn addTemporary(c: *JsNodeGen) !Node.Index {378fn addTemporary(c: *JsNodeGen) !Node.Index {
379 const t = tracer.trace(@src());
380 defer t.end();
381
355 try c.addStmt(try c.add(.stmt_declare_local, .{382 try c.addStmt(try c.add(.stmt_declare_local, .{
356 .identifier_index = c.next_id,383 .identifier_index = c.next_id,
357 .init = .none,384 .init = .none,
...@@ -367,6 +394,9 @@ const Branch = struct {...@@ -367,6 +394,9 @@ const Branch = struct {
367};394};
368395
369fn codeGenBranch(c: *JsNodeGen, inst: Air.Inst.Ref, temporary: ?Node.Index) !?Branch {396fn codeGenBranch(c: *JsNodeGen, inst: Air.Inst.Ref, temporary: ?Node.Index) !?Branch {
397 const t = tracer.trace(@src());
398 defer t.end();
399
370 const scratch_top = c.scratch.items.len;400 const scratch_top = c.scratch.items.len;
371 defer c.scratch.shrinkRetainingCapacity(scratch_top);401 defer c.scratch.shrinkRetainingCapacity(scratch_top);
372402
...@@ -430,6 +460,9 @@ fn codeGenBranch(c: *JsNodeGen, inst: Air.Inst.Ref, temporary: ?Node.Index) !?Br...@@ -430,6 +460,9 @@ fn codeGenBranch(c: *JsNodeGen, inst: Air.Inst.Ref, temporary: ?Node.Index) !?Br
430}460}
431461
432fn codeGenBlock(c: *JsNodeGen, inst: Air.Inst.Index) !void {462fn codeGenBlock(c: *JsNodeGen, inst: Air.Inst.Index) !void {
463 const t = tracer.trace(@src());
464 defer t.end();
465
433 const scratch_top = c.scratch.items.len;466 const scratch_top = c.scratch.items.len;
434 errdefer c.scratch.shrinkRetainingCapacity(scratch_top);467 errdefer c.scratch.shrinkRetainingCapacity(scratch_top);
435468
...@@ -467,6 +500,9 @@ fn codeGenBlock(c: *JsNodeGen, inst: Air.Inst.Index) !void {...@@ -467,6 +500,9 @@ fn codeGenBlock(c: *JsNodeGen, inst: Air.Inst.Index) !void {
467}500}
468501
469fn canLowerToExpression(c: *const JsNodeGen, inst: Air.Inst.Ref) bool {502fn canLowerToExpression(c: *const JsNodeGen, inst: Air.Inst.Ref) bool {
503 const t = tracer.trace(@src());
504 defer t.end();
505
470 return switch (inst.unwrap()) {506 return switch (inst.unwrap()) {
471 .value => true,507 .value => true,
472 .inst => |index| switch (c.air.instTag(index)) {508 .inst => |index| switch (c.air.instTag(index)) {
...@@ -493,6 +529,9 @@ fn canLowerToExpression(c: *const JsNodeGen, inst: Air.Inst.Ref) bool {...@@ -493,6 +529,9 @@ fn canLowerToExpression(c: *const JsNodeGen, inst: Air.Inst.Ref) bool {
493}529}
494530
495fn lowerToExpression(c: *JsNodeGen, ref: Air.Inst.Ref) !Node.Index {531fn lowerToExpression(c: *JsNodeGen, ref: Air.Inst.Ref) !Node.Index {
532 const t = tracer.trace(@src());
533 defer t.end();
534
496 assert(c.canLowerToExpression(ref));535 assert(c.canLowerToExpression(ref));
497 return switch (ref.unwrap()) {536 return switch (ref.unwrap()) {
498 .value => |v| try c.valueToExpression(v),537 .value => |v| try c.valueToExpression(v),
...@@ -504,6 +543,9 @@ fn lowerToExpression(c: *JsNodeGen, ref: Air.Inst.Ref) !Node.Index {...@@ -504,6 +543,9 @@ fn lowerToExpression(c: *JsNodeGen, ref: Air.Inst.Ref) !Node.Index {
504}543}
505544
506fn add(c: *JsNodeGen, comptime tag: JsTree.Tag, data: tag.Data()) !Node.Index {545fn add(c: *JsNodeGen, comptime tag: JsTree.Tag, data: tag.Data()) !Node.Index {
546 const t = tracer.trace(@src());
547 defer t.end();
548
507 try c.nodes.append(c.gpa, .{549 try c.nodes.append(c.gpa, .{
508 .tag = tag,550 .tag = tag,
509 .data = EncodedData.encode(tag, data),551 .data = EncodedData.encode(tag, data),
...@@ -512,6 +554,9 @@ fn add(c: *JsNodeGen, comptime tag: JsTree.Tag, data: tag.Data()) !Node.Index {...@@ -512,6 +554,9 @@ fn add(c: *JsNodeGen, comptime tag: JsTree.Tag, data: tag.Data()) !Node.Index {
512}554}
513555
514fn addStmt(c: *JsNodeGen, stmt: Node.Index) !void {556fn addStmt(c: *JsNodeGen, stmt: Node.Index) !void {
557 const t = tracer.trace(@src());
558 defer t.end();
559
515 try c.scratch.append(c.arena, @intFromEnum(stmt));560 try c.scratch.append(c.arena, @intFromEnum(stmt));
516}561}
517562
...@@ -537,3 +582,4 @@ const Air = @import("Air.zig");...@@ -537,3 +582,4 @@ const Air = @import("Air.zig");
537const Value = @import("Value.zig");582const Value = @import("Value.zig");
538583
539const dod = @import("dod.zig");584const dod = @import("dod.zig");
585const tracer = @import("tracer");
src/compiler/Report.zig+16-9
...@@ -183,8 +183,7 @@ pub fn deinit(report: Report, gpa: Allocator) void {...@@ -183,8 +183,7 @@ pub fn deinit(report: Report, gpa: Allocator) void {
183 gpa.free(report.string_bytes);183 gpa.free(report.string_bytes);
184}184}
185185
186pub fn dumpToWriter(report: Report, comp: *Comp, writer: anytype) !void {186pub fn dumpToWriter(report: Report, comp: *Comp, writer: anytype, tty: std.io.tty.Config) !void {
187 const tty = util.detectTTYFromWriter(writer);
188 try writer.print("{d} errors, {d} warnings\n", .{ report.errors.len, report.warnings.len });187 try writer.print("{d} errors, {d} warnings\n", .{ report.errors.len, report.warnings.len });
189 for (report.errors) |item| {188 for (report.errors) |item| {
190 try report.formatItem(item, .@"error", comp, writer, tty);189 try report.formatItem(item, .@"error", comp, writer, tty);
...@@ -348,13 +347,21 @@ pub fn formatItem(...@@ -348,13 +347,21 @@ pub fn formatItem(
348}347}
349348
350pub fn dumpToStdErr(report: Report, comp: *Comp) !void {349pub fn dumpToStdErr(report: Report, comp: *Comp) !void {
351 const stderr = std.io.getStdErr().writer();350 const builtin = @import("builtin");
352351
353 // Disabled because of coloring issues.352 const stderr = std.io.getStdErr();
354 // var buf = std.io.bufferedWriter(stderr);353 const tty = std.io.tty.detectConfig(stderr);
355 // const writer = buf.writer();354
356 try dumpToWriter(report, comp, stderr);355 if (builtin.os.tag == .windows and tty == .windows_api) {
357 // try buf.flush();356 // Windows API uses it's own API calls, so a buffered writer
357 // cannot be used :/
358 try dumpToWriter(report, comp, stderr.writer(), tty);
359 } else {
360 var buf = std.io.bufferedWriter(stderr.writer());
361 const writer = buf.writer();
362 try dumpToWriter(report, comp, writer, tty);
363 try buf.flush();
364 }
358}365}
359366
360pub const Builder = struct {367pub const Builder = struct {
src/compiler/Sema.zig+5-3
...@@ -92,9 +92,11 @@ pub fn deinit(s: *Sema) void {...@@ -92,9 +92,11 @@ pub fn deinit(s: *Sema) void {
92pub fn finalize(s: *Sema) !void {92pub fn finalize(s: *Sema) !void {
93 const air: Air = s.tempAir();93 const air: Air = s.tempAir();
9494
95 std.debug.print("=" ** 20, .{});95 if (s.comp.options.dump_ir) {
96 std.debug.print("\nAir for @ {d}\n", .{@intFromEnum(s.decl.teg_decl_index)});96 std.debug.print("=" ** 20, .{});
97 air.dumpToWriter(s.ip, std.io.getStdErr().writer()) catch {};97 std.debug.print("\nAir for @ {d}\n", .{@intFromEnum(s.decl.teg_decl_index)});
98 air.dumpToWriter(s.ip, std.io.getStdErr().writer()) catch {};
99 }
98100
99 try s.comp.codeGenDecl(s.decl, &air);101 try s.comp.codeGenDecl(s.decl, &air);
100}102}
src/compiler/Transform.zig+4-2
...@@ -603,6 +603,8 @@ fn transformExpression(t: *Transform, decl: BlockContext, node: NodeIndex) Alloc...@@ -603,6 +603,8 @@ fn transformExpression(t: *Transform, decl: BlockContext, node: NodeIndex) Alloc
603 return .void_value;603 return .void_value;
604 };604 };
605605
606 lookup.mutated = true;
607
606 return switch (lookup.data) {608 return switch (lookup.data) {
607 .declaration => try t.addInstRef(.{609 .declaration => try t.addInstRef(.{
608 .tag = .load_decl,610 .tag = .load_decl,
...@@ -1235,11 +1237,11 @@ fn scratchToIndexList(t: *Transform, scratch_top: usize) !IndexList {...@@ -1235,11 +1237,11 @@ fn scratchToIndexList(t: *Transform, scratch_top: usize) !IndexList {
1235 };1237 };
1236}1238}
12371239
1238fn lookupId(t: *Transform, id: []const u8) ?Scope.Symbol {1240fn lookupId(t: *Transform, id: []const u8) ?*Scope.Symbol {
1239 var i = t.scopes.items.len;1241 var i = t.scopes.items.len;
1240 while (i > 0) {1242 while (i > 0) {
1241 i -= 1;1243 i -= 1;
1242 if (t.scopes.items[i].symbols.get(id)) |sym| {1244 if (t.scopes.items[i].symbols.getPtr(id)) |sym| {
1243 return sym;1245 return sym;
1244 }1246 }
1245 }1247 }
src/compiler/main.zig+29-13
...@@ -1,30 +1,40 @@...@@ -1,30 +1,40 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
3
2const Tokenizer = @import("Tokenizer.zig");4const Tokenizer = @import("Tokenizer.zig");
3const Parse = @import("Parse.zig");5const Parse = @import("Parse.zig");
4const Transform = @import("Transform.zig");6const Transform = @import("Transform.zig");
5const Comp = @import("Comp.zig");7const Comp = @import("Comp.zig");
6const unicode_props = @import("unicode_props.zig");8const unicode_props = @import("unicode_props.zig");
7const T = @import("tracer");9
8pub const tracer_impl = @field(T, "none");10const tracer = @import("tracer");
11
12pub const tracer_impl = @field(tracer, @import("build_options").tracing);
913
10pub const Report = @import("Report.zig");14pub const Report = @import("Report.zig");
1115
12pub fn main() !void {16pub fn main() !void {
17 try tracer.init();
18 defer tracer.deinit();
19 try tracer.init_thread(null);
20 defer tracer.deinit_thread();
21
13 try unicode_props.init();22 try unicode_props.init();
1423
15 std.debug.print("\r\x1b[K", .{});24 std.debug.print("\r\x1b[K", .{});
1625
17 try T.init();26 const use_gpa = builtin.mode == .Debug;
18 defer T.deinit();
19
20 try T.init_thread(null);
21 defer T.deinit_thread();
2227
23 var gpa: std.heap.GeneralPurposeAllocator(.{28 var gpa: if (use_gpa) std.heap.GeneralPurposeAllocator(.{
24 .stack_trace_frames = 100,29 .stack_trace_frames = 100,
25 }) = .{};30 }) else struct {} = .{};
26 defer _ = gpa.deinit();31 defer if (use_gpa) {
27 const alloc = gpa.allocator();32 _ = gpa.deinit();
33 };
34 const alloc = if (use_gpa)
35 gpa.allocator()
36 else
37 std.heap.c_allocator;
2838
29 var maybe_file_path: ?[]const u8 = null;39 var maybe_file_path: ?[]const u8 = null;
30 defer if (maybe_file_path) |path| alloc.free(path);40 defer if (maybe_file_path) |path| alloc.free(path);
...@@ -60,7 +70,7 @@ pub fn main() !void {...@@ -60,7 +70,7 @@ pub fn main() !void {
60 std.process.exit(1);70 std.process.exit(1);
61 };71 };
6272
63 var comp: Comp = .{ .gpa = T.tracingAllocator(&alloc) };73 var comp: Comp = .{ .gpa = tracer.tracingAllocator(&alloc) };
64 try comp.init();74 try comp.init();
65 defer comp.deinit();75 defer comp.deinit();
66 const main_file = try comp.getFile(file_path);76 const main_file = try comp.getFile(file_path);
...@@ -72,10 +82,14 @@ pub fn main() !void {...@@ -72,10 +82,14 @@ pub fn main() !void {
72 try fail_report.dumpToStdErr(&comp);82 try fail_report.dumpToStdErr(&comp);
73 std.process.exit(1);83 std.process.exit(1);
74 },84 },
85 error.ParseFail => {
86 // Already printed.
87 std.process.exit(1);
88 },
75 else => return err,89 else => return err,
76 };90 };
7791
78 {92 if (comp.options.dump_ir) {
79 const stderr = std.io.getStdErr().writer();93 const stderr = std.io.getStdErr().writer();
80 try teg.dumpToWriter(stderr);94 try teg.dumpToWriter(stderr);
81 }95 }
...@@ -88,6 +102,8 @@ pub fn main() !void {...@@ -88,6 +102,8 @@ pub fn main() !void {
88 try comp.link(writer);102 try comp.link(writer);
89 try bufw.flush();103 try bufw.flush();
90104
105 std.process.cleanExit();
106
91 // var error_pos: u32 = 0;107 // var error_pos: u32 = 0;
92 // var tokens = Tokenizer.tokenize(source, alloc.allocator(), &error_pos) catch |err| {108 // var tokens = Tokenizer.tokenize(source, alloc.allocator(), &error_pos) catch |err| {
93 // var line: usize = 1;109 // var line: usize = 1;