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