From 1eedbe39492f981ee0cfaf692af0707cf3d99383 Mon Sep 17 00:00:00 2001 From: chloe caruso Date: Sat, 21 Sep 2024 01:25:24 -0700 Subject: [PATCH] chore: rename Teg -> Hir --- README.md | 5 +- doc/architecture.md | 14 +- doc/language-manual.md | 2 +- src/cli_compiler.zig | 4 +- src/cli_transform.zig | 10 +- src/core/Air.Dump.zig | 2 +- src/core/Ast.zig | 2 +- src/core/Comp.zig | 60 +++---- src/core/{Teg.Dump.zig => Hir.Dump.zig} | 128 +++++++------- src/core/{Teg.zig => Hir.zig} | 211 +++++++++++++----------- src/core/InternPool.zig | 12 +- src/core/Report.zig | 16 +- src/core/Sema.zig | 186 ++++++++++----------- src/core/StoredTrace.zig | 6 +- src/core/Transform.zig | 104 ++++++------ src/core/array.zig | 2 +- src/core/mod.zig | 2 +- src/main.zig | 4 +- src/wasm/enum_codegen.zig | 6 +- test/compiler_tests.zig | 10 +- 20 files changed, 397 insertions(+), 389 deletions(-) rename src/core/{Teg.Dump.zig => Hir.Dump.zig} (81%) rename src/core/{Teg.zig => Hir.zig} (78%) diff --git a/README.md b/README.md index c36e87250efe7a2648ecb5858ea9c7cdd919f603..0aa742511ebc6dd1a609cf6988331aa4890286e0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Ix -Ix (**I**nferable E**x**pression) is a high-level, general purpose programming -language. It features a mix of Rust, Zig, and JavaScript's great points. +Ix (***I***nferable E***x***pression) is a high-level, general purpose +programming language. It features a mix of Rust, Zig, and JavaScript's great +points. For a guide on how to use Ix, see the manual included in the binary distribution. Additionally, the latest commit of the manual is hosted online at diff --git a/doc/architecture.md b/doc/architecture.md index de45d0b46a315d16d7b5ebeb7fba01e5f3a11762..9413bc82c1623f2b93c0cba8435a798989ae0d6a 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -34,13 +34,13 @@ compiler tests into these categories: runtime, testing both the semantic analysis pass as well as the code generation backend. - **Transform Error Tests** (`test/transform_error`) confirm that the transform - pass errors are correct. A passing `Teg` fails the test. + pass errors are correct. A passing `Hir` fails the test. -All compiler tests can be run with `zig build test`, or the test suite can be -filtered using flags, see `zig build test --help` +All compiler tests can be run with `./build test`, or the test suite can be +filtered using flags, see `./build test -- --help` -To run Zig tests for an associated module, use `zig build test-{name}`, or run -`zig build test-all` to run all tests in the codebase. +To run Zig tests for an associated module, use `./build test-{name}`, or run +`./build test-all` to run all tests in the codebase. ## Core @@ -48,7 +48,7 @@ The `core` module contains most of the compiler: - Tokenizing and Parsing files. (`Tokenizer.zig`, `Parse.zig`, `Ast.zig`) - Transform Pass, moving from Ast to an untyped intermediate representation - (`Transform.zig`) + (`Transform.zig`, `Hir.zig`) - Semantic Analysis, resolving all types and comptime values. (`Sema.zig`) - Intern Pool, storing and de-duplicating objects in a compilation. (`InternPool.zig`) @@ -56,7 +56,7 @@ The `core` module contains most of the compiler: Note that components like the formatter and module fetching code are not here. Keeping this module as small as possible is important for keeping compile times -low. Using `zig build compiler -- --help` instead of the fully featured binary +low. Using `./build compiler -- --help` instead of the fully featured binary will allow for faster and more focused iteration. ## Manual diff --git a/doc/language-manual.md b/doc/language-manual.md index ffca26d424414617bbe800242efbf1d5dc49b9b3..b6dde2e8da040ddafad1af0001c509e367235fbf 100644 --- a/doc/language-manual.md +++ b/doc/language-manual.md @@ -1,6 +1,6 @@ # Ix Programming Language -Ix (**I**nferable E**x**pression) is a high-level programming language for +Ix (***I***nferable E***x***pression) is a high-level programming language for developing web applications and games. Key goals of this project are: diff --git a/src/cli_compiler.zig b/src/cli_compiler.zig index a13fe48184ffa3dfd1e3aa9fb9c06940645e9de3..43c866cdc0fef3d9b7dcf390119a547541a5c157 100644 --- a/src/cli_compiler.zig +++ b/src/cli_compiler.zig @@ -81,7 +81,7 @@ pub fn main() !u8 { const main_file = try comp.getFile(file_path); var fail_report: Report = undefined; - const teg = main_file.getTeg(&comp, &fail_report) catch |err| switch (err) { + const hir = main_file.getHir(&comp, &fail_report) catch |err| switch (err) { error.TransformFail => { std.debug.print("Transform failed:\n", .{}); try fail_report.dump(.initComp(&comp, main_file), comp.out); @@ -97,7 +97,7 @@ pub fn main() !u8 { if (comp.options.dump_ir) { const stderr = std.io.getStdErr().writer(); - try teg.dumpToWriter(stderr, null); + try hir.dumpToWriter(stderr, null); } const entry_point = try comp.enqueueEntryModule(main_file); diff --git a/src/cli_transform.zig b/src/cli_transform.zig index 501353608d31b9e0e2523c4a608263a56929a8f9..b687ddf5e857e3b1d04343cab96bfe319a8facfd 100644 --- a/src/cli_transform.zig +++ b/src/cli_transform.zig @@ -66,7 +66,7 @@ pub fn main() !u8 { } var teg_report: core.Report = undefined; - var teg = core.Transform.transform(ast, alloc, &teg_report) catch |err| switch (err) { + var hir = core.Transform.transform(ast, alloc, &teg_report) catch |err| switch (err) { error.OutOfMemory => return err, error.TransformFail => { defer teg_report.deinit(alloc); @@ -81,13 +81,13 @@ pub fn main() !u8 { return 1; }, }; - defer teg.deinit(alloc); + defer hir.deinit(alloc); - // const file = try std.fs.cwd().createFile("serialized.teg", .{}); + // const file = try std.fs.cwd().createFile("serialized.hir", .{}); // defer file.close(); - // try teg.serialize(.{ .file = file }); + // try hir.serialize(.{ .file = file }); - try teg.dumpToWriter(out.writer, out.tty); + try hir.dumpToWriter(out.writer, out.tty); return 0; } diff --git a/src/core/Air.Dump.zig b/src/core/Air.Dump.zig index 03f29ece0026eeec8b67714a9531b6b2ed612b33..d95fe6e89ff03e21ffc1188369aefe606239aed4 100644 --- a/src/core/Air.Dump.zig +++ b/src/core/Air.Dump.zig @@ -1,4 +1,4 @@ -//! This implements a debug formatter for Teg +//! This implements a debug formatter for Air air: Air, ip: *const InternPool, tty: std.io.tty.Config, diff --git a/src/core/Ast.zig b/src/core/Ast.zig index 18a10acf8d28760a9e03c5cabcb4abd1dfa83dac..5fbfba34a7793845b15fbc35223e064d6455b46d 100644 --- a/src/core/Ast.zig +++ b/src/core/Ast.zig @@ -1,6 +1,6 @@ //! The Abstract Syntax Tree preserves most details of the source code, //! as it is used for formatting. Before semantic analysis, this -//! structure is normalized into `Teg`, which removes constructs like +//! structure is normalized into `Hir`, which removes constructs like //! whitespace, unneeded let bindings, and other transforms. //! //! `ast.nodes` contains nodes stored as three parts: diff --git a/src/core/Comp.zig b/src/core/Comp.zig index 118b19df45534443da4ddd7fd4b786b25d8d1e41..667560a920c7971bbd8db7b51ecdf90e4ce6041b 100644 --- a/src/core/Comp.zig +++ b/src/core/Comp.zig @@ -110,14 +110,14 @@ const Job = union(enum) { pub fn enqueueEntryModule(comp: *Comp, file: *File) !Decl.Index { var report: Report = undefined; - const teg = try file.getTeg(comp, &report); + const hir = try file.getHir(comp, &report); // TODO, move this elsewhere. we should print all errors and warnings at once - if (teg.report.warnings.len > 0) { - try teg.report.dump(.initComp(comp, file), comp.out); + if (hir.report.warnings.len > 0) { + try hir.report.dump(.initComp(comp, file), comp.out); } - const ns = try comp.indexTegModule(file, .main_module_inst); + const ns = try comp.indexHirModule(file, .main_module_inst); const main_str = try comp.intern_pool.getOrPutString(comp.gpa, "main", .no_embedded_nulls); const decl_index = comp.intern_pool.namespacePtr(ns).lookupDirect(comp, main_str) orelse { // TODO: add a helper function into Report to render a single error @@ -168,12 +168,12 @@ fn runAnalysisJob(comp: *Comp, unit: InternPool.AnalysisUnit, first_blocked_sema }; const decl = comp.intern_pool.declPtr(decl_index); const file = comp.intern_pool.namespacePtr(decl.src_namespace).file_scope; - const teg = file.teg orelse @panic("TODO: make sure teg is loaded to avoid annoying error set?"); + const hir = file.hir orelse @panic("TODO: make sure hir is loaded to avoid annoying error set?"); try sema.init( comp, file, - teg, + hir, unit, decl.src_namespace, std.heap.ArenaAllocator.init(comp.gpa), @@ -266,7 +266,7 @@ pub fn getFile(comp: *Comp, absolute_file_path: []const u8) !*File { .root_namespace = .none, .source = null, .ast = null, - .teg = null, + .hir = null, }; gop.value_ptr.* = file; return file; @@ -277,7 +277,7 @@ pub const Source = struct { stat: Stat, }; -/// A file in the compilation and it's associated data structures. Ast and Teg +/// A file in the compilation and it's associated data structures. Ast and Hir /// are not guaranteed to be loaded, even if it's `status` says `success`. pub const File = struct { /// TODO: change this to a URL @@ -287,7 +287,7 @@ pub const File = struct { source: ?Source, ast: ?Ast, - teg: ?Teg, + hir: ?Hir, path_digest: ?Cache.BinDigest, @@ -323,7 +323,7 @@ pub const File = struct { // Here we do not modify stat fields because this function is the one // used for error reporting. We need to keep the stat fields stale so that - // transformFile can know to regenerate Teg. + // transformFile can know to regenerate Hir. const loaded_source: Source = .{ .code = source, @@ -370,11 +370,11 @@ pub const File = struct { return &(file.ast.?); } - pub const GetTegError = GetAstError || Transform.Error; + pub const GetHirError = GetAstError || Transform.Error; - pub fn getTeg(file: *File, comp: *Comp, fail_report: *Report) GetTegError!Teg { - if (file.teg) |teg| { - return teg; + pub fn getHir(file: *File, comp: *Comp, fail_report: *Report) GetHirError!Hir { + if (file.hir) |hir| { + return hir; } const bin_digest = hash: { @@ -387,10 +387,10 @@ pub const File = struct { }; file.path_digest = bin_digest; - const teg = try Transform.transform((try file.getAst(comp)).*, comp.gpa, fail_report); + const hir = try Transform.transform((try file.getAst(comp)).*, comp.gpa, fail_report); - file.teg = teg; - return teg; + file.hir = hir; + return hir; } pub fn unloadSource(file: *File, gpa: Allocator) void { @@ -407,15 +407,15 @@ pub const File = struct { } } - pub fn unloadTeg(file: *File, gpa: Allocator) void { - if (file.teg) |*teg| { - teg.deinit(gpa); - file.teg = null; + pub fn unloadHir(file: *File, gpa: Allocator) void { + if (file.hir) |*hir| { + hir.deinit(gpa); + file.hir = null; } } pub fn deinit(file: *File, gpa: Allocator) void { - file.unloadTeg(gpa); + file.unloadHir(gpa); file.unloadAst(gpa); file.unloadSource(gpa); gpa.destroy(file); @@ -476,7 +476,7 @@ pub const Decl = struct { // /// This value is absolute. // src_line: u32, - /// Index of the Teg `declaration` instruction from which this `Decl` was created. + /// Index of the Hir `declaration` instruction from which this `Decl` was created. teg_decl_index: InternPool.TrackedInst.Index, /// Represents the "shallow" analysis status. For example, for decls that are functions, @@ -620,10 +620,10 @@ pub const Namespace = struct { pub const Index = InternPool.NamespaceIndex; }; -/// Index a Teg's module scope as a namespace. This prepares `Decl` objects for +/// Index a Hir's module scope as a namespace. This prepares `Decl` objects for /// every declaration, but does not begin analysis of them. -pub fn indexTegModule(comp: *Comp, file: *File, module_index: Teg.Inst.Index) !Namespace.Index { - const teg = file.teg.?; +pub fn indexHirModule(comp: *Comp, file: *File, module_index: Hir.Inst.Index) !Namespace.Index { + const hir = file.hir.?; assert(file.root_namespace == .none); @@ -635,12 +635,12 @@ pub fn indexTegModule(comp: *Comp, file: *File, module_index: Teg.Inst.Index) !N const ns_ptr = comp.intern_pool.namespacePtr(ns); errdefer comp.intern_pool.destroyNamespace(comp.gpa, ns); - for (teg.moduleDeclarations(module_index)) |decl_index| { - switch (teg.instTag(decl_index)) { + for (hir.moduleDeclarations(module_index)) |decl_index| { + switch (hir.instTag(decl_index)) { .declaration => { const name = try comp.intern_pool.getOrPutString( comp.gpa, - teg.declName(decl_index), + hir.declName(decl_index), .no_embedded_nulls, ); const tracked_inst = try comp.intern_pool.trackInst(comp.gpa, file, decl_index); @@ -736,7 +736,7 @@ const InternPool = core.InternPool; const Ast = core.Ast; const Air = core.Air; -const Teg = core.Teg; +const Hir = core.Hir; const Cache = core.Cache; const Sema = core.Sema; const Transform = core.Transform; diff --git a/src/core/Teg.Dump.zig b/src/core/Hir.Dump.zig similarity index 81% rename from src/core/Teg.Dump.zig rename to src/core/Hir.Dump.zig index a244b796e151855de91e8d27322795120aec7a99..53ee3b62b2379aa76b05b38af5132b0e6af6ebe7 100644 --- a/src/core/Teg.Dump.zig +++ b/src/core/Hir.Dump.zig @@ -1,13 +1,13 @@ -//! This implements a debug formatter for Teg -teg: Teg, +//! This implements a debug formatter for Hir +hir: Hir, tty: ?std.io.tty.Config = null, const State = struct { arena: std.mem.Allocator, - teg: *const Teg, + hir: *const Hir, indent: usize = 0, tty: std.io.tty.Config, - visited: std.AutoHashMapUnmanaged(Teg.Inst.Index, void) = .{}, + visited: std.AutoHashMapUnmanaged(Hir.Inst.Index, void) = .{}, fn newline(state: State, writer: anytype) !void { try writer.writeByte('\n'); @@ -15,16 +15,16 @@ const State = struct { try writer.writeByteNTimes(' ', state.indent * 2); } - fn dumpInst(s: *State, writer: anytype, inst: Teg.Inst.Index) @TypeOf(writer).Error!void { - const teg = s.teg; + fn dumpInst(s: *State, writer: anytype, inst: Hir.Inst.Index) @TypeOf(writer).Error!void { + const hir = s.hir; const tty = s.tty; try writer.print("%{} = ", .{@intFromEnum(inst)}); - const tag = s.teg.instTag(inst); + const tag = s.hir.instTag(inst); try tty.setColor(writer, .bright_black); - const node_offset = teg.instNodeOffset(inst); + const node_offset = hir.instNodeOffset(inst); try writer.print("{c}{d} ", .{ @as(u8, if (node_offset >= 0) '+' else '-'), @abs(node_offset), @@ -44,13 +44,13 @@ const State = struct { switch (tag) { .module => { - try s.dumpInstList(writer, teg.moduleDeclarations(inst), '{', '}'); + try s.dumpInstList(writer, hir.moduleDeclarations(inst), '{', '}'); }, .declaration, .variable_declaration, .test_declaration => { - const decl = teg.fullDecl(inst); + const decl = hir.fullDecl(inst); try writer.writeAll(" "); - const name = decl.name.slice(teg.string_bytes); + const name = decl.name.slice(hir.string_bytes); if (name.len == 0) { try tty.setColor(writer, .bold); try writer.writeAll("[no name]"); @@ -76,12 +76,12 @@ const State = struct { try writer.writeAll(")"); }, .func => { - const func: Teg.Func = teg.instPayload(.func, inst); + const func: Hir.Func = hir.instPayload(.func, inst); try writer.writeAll(" {"); s.indent += 1; try s.newline(writer); try writer.writeAll("params: "); - try s.dumpOptionalRefList(writer, func.params.slice(teg), '[', ']'); + try s.dumpOptionalRefList(writer, func.params.slice(hir), '[', ']'); try s.newline(writer); try writer.writeAll("return_type: "); if (func.return_type.unwrap()) |ret| @@ -93,7 +93,7 @@ const State = struct { } try s.newline(writer); try writer.writeAll("captures: "); - try s.dumpInstList2(writer, func.captures.slice(teg), '[', ']'); + try s.dumpInstList2(writer, func.captures.slice(hir), '[', ']'); try s.newline(writer); try writer.writeAll("body: "); try s.dumpInst(writer, func.body); @@ -102,7 +102,7 @@ const State = struct { try writer.writeAll("}"); }, .param => { - const data = teg.instData(.param, inst); + const data = hir.instData(.param, inst); try writer.writeAll("("); if (data.data == std.math.maxInt(u32)) { try tty.setColor(writer, .bright_black); @@ -115,13 +115,13 @@ const State = struct { try writer.writeAll(")"); }, inline .block, .@"comptime" => |t| { - const block = teg.instData(t, inst); - const index_list = block.extra_index.get(teg); - try s.dumpInstList(writer, index_list.slice(teg), '[', ']'); + const block = hir.instData(t, inst); + const index_list = block.extra_index.get(hir); + try s.dumpInstList(writer, index_list.slice(hir), '[', ']'); }, .number => { - const number = teg.instData(.number, inst); - const float = number.extra_index.get(teg).decode(); + const number = hir.instData(.number, inst); + const float = number.extra_index.get(hir).decode(); try tty.setColor(writer, .yellow); try writer.print(" {d}", .{float}); try tty.setColor(writer, .reset); @@ -148,7 +148,7 @@ const State = struct { .gt, .ge, => |comptime_tag| { - const data = teg.instData(comptime_tag, inst).extra_index.get(teg); + const data = hir.instData(comptime_tag, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, data.lhs); try writer.writeAll(", "); @@ -156,7 +156,7 @@ const State = struct { try writer.writeAll(")"); }, .coercion => { - const data = teg.instData(.coercion, inst).extra_index.get(teg); + const data = hir.instData(.coercion, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, data.type); try writer.writeAll(", "); @@ -164,7 +164,7 @@ const State = struct { try writer.writeAll(")"); }, .@"break" => { - const data: Teg.Break = teg.instData(.@"break", inst).extra_index.get(teg); + const data: Hir.Break = hir.instData(.@"break", inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, data.block.toRef()); try writer.writeAll(", "); @@ -172,7 +172,7 @@ const State = struct { try writer.writeAll(")"); }, .store => { - const data: Teg.Store = teg.instData(.store, inst).extra_index.get(teg); + const data: Hir.Store = hir.instData(.store, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, data.memory.toRef()); try writer.writeAll(", "); @@ -180,7 +180,7 @@ const State = struct { try writer.writeAll(")"); }, .store_field => { - const data: Teg.StoreField = teg.instData(.store_field, inst).extra_index.get(teg); + const data: Hir.StoreField = hir.instData(.store_field, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, data.base); try writer.writeAll(", "); @@ -190,20 +190,20 @@ const State = struct { try writer.writeAll(")"); }, .store_decl => { - const data: Teg.StoreVarDecl = teg.instData(.store_decl, inst).extra_index.get(teg); + const data: Hir.StoreVarDecl = hir.instData(.store_decl, inst).extra_index.get(hir); try writer.writeAll("("); try tty.setColor(writer, .magenta); - try writer.writeAll(data.var_decl.slice(teg.string_bytes)); + try writer.writeAll(data.var_decl.slice(hir.string_bytes)); try tty.setColor(writer, .reset); try writer.writeAll(", "); try s.dumpRefMarker(writer, data.operand); try writer.writeAll(")"); }, .string => { - const data: Teg.SlicedString = teg.instData(.string, inst).extra_index.get(teg); + const data: Hir.SlicedString = hir.instData(.string, inst).extra_index.get(hir); try tty.setColor(writer, .green); try writer.writeAll(" \""); - try writer.writeAll(data.slice(teg.string_bytes)); + try writer.writeAll(data.slice(hir.string_bytes)); try writer.writeAll("\""); try tty.setColor(writer, .reset); }, @@ -221,36 +221,36 @@ const State = struct { .array_type, .assert, => |comptime_tag| { - const data = teg.instData(comptime_tag, inst); + const data = hir.instData(comptime_tag, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.operand); try writer.writeAll(")"); }, .call => { - const call: Teg.Call = teg.instData(.call, inst).extra_index.get(teg); + const call: Hir.Call = hir.instData(.call, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, call.base); try writer.writeAll(", "); - try s.dumpRefMarkerList(writer, call.args.slice(teg), '[', ']'); + try s.dumpRefMarkerList(writer, call.args.slice(hir), '[', ']'); try writer.writeAll(")"); }, .js_new => { - const call: Teg.JsNew = teg.instData(.js_new, inst).extra_index.get(teg); + const call: Hir.JsNew = hir.instData(.js_new, inst).extra_index.get(hir); try writer.writeAll("("); try s.dumpRefMarker(writer, call.base); try writer.writeAll(", "); - try s.dumpRefMarkerList(writer, call.args.slice(teg), '[', ']'); + try s.dumpRefMarkerList(writer, call.args.slice(hir), '[', ']'); try writer.writeAll(")"); }, .load_decl => { - const call: Teg.StrNode = teg.instData(.load_decl, inst); + const call: Hir.StrNode = hir.instData(.load_decl, inst); try tty.setColor(writer, .red); - try writer.print(" {s}", .{call.string.slice(teg.string_bytes)}); + try writer.print(" {s}", .{call.string.slice(hir.string_bytes)}); try tty.setColor(writer, .reset); }, .@"if" => { - const data: Teg.If = teg.instPayload(.@"if", inst); + const data: Hir.If = hir.instPayload(.@"if", inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.cond); try writer.writeAll(") {"); @@ -266,14 +266,14 @@ const State = struct { try writer.writeAll("}"); }, .struct_decl => { - const data: Teg.StructDecl = teg.instPayload(.struct_decl, inst); + const data: Hir.StructDecl = hir.instPayload(.struct_decl, inst); try writer.writeAll(" {"); s.indent += 1; try s.newline(writer); - for (data.keys(teg), data.types(teg), 0..) |key, value, i| { + for (data.keys(hir), data.types(hir), 0..) |key, value, i| { if (i != 0) try s.newline(writer); - try writer.print("{s}: ", .{key.slice(teg.string_bytes)}); + try writer.print("{s}: ", .{key.slice(hir.string_bytes)}); try s.dumpRefMarker(writer, value); } s.indent -= 1; @@ -281,16 +281,16 @@ const State = struct { try writer.writeAll("}"); }, .struct_init => { - const data: Teg.StructInit = teg.instPayload(.struct_init, inst); + const data: Hir.StructInit = hir.instPayload(.struct_init, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.base_type); try writer.writeAll(") {"); s.indent += 1; try s.newline(writer); - for (data.keys(teg), data.inits(teg), 0..) |key, value, i| { + for (data.keys(hir), data.inits(hir), 0..) |key, value, i| { if (i != 0) try s.newline(writer); - try writer.print("{s}: ", .{key.slice(teg.string_bytes)}); + try writer.print("{s}: ", .{key.slice(hir.string_bytes)}); try s.dumpRefMarker(writer, value); } s.indent -= 1; @@ -298,7 +298,7 @@ const State = struct { try writer.writeAll("}"); }, .array_init => { - const data: Teg.ArrayInit = teg.instPayload(.array_init, inst); + const data: Hir.ArrayInit = hir.instPayload(.array_init, inst); if (data.type_hint.unwrap()) |type_hint| { try writer.writeAll("("); @@ -310,7 +310,7 @@ const State = struct { s.indent += 1; - for (data.list.slice(teg)) |item| { + for (data.list.slice(hir)) |item| { try s.newline(writer); try s.dumpRefMarker(writer, item); try writer.writeAll(","); @@ -325,25 +325,25 @@ const State = struct { try writer.writeAll(")"); }, .tuple_type => { - const data: Teg.TupleType = teg.instPayload(.tuple_type, inst); + const data: Hir.TupleType = hir.instPayload(.tuple_type, inst); try writer.writeAll("("); - try s.dumpRefMarkerList(writer, data.items.slice(teg), '[', ']'); + try s.dumpRefMarkerList(writer, data.items.slice(hir), '[', ']'); try writer.writeAll(")"); }, .tuple_init => { - const data: Teg.TupleInit = teg.instPayload(.tuple_init, inst); + const data: Hir.TupleInit = hir.instPayload(.tuple_init, inst); try writer.writeAll("("); if (data.type_hint.unwrap()) |type_hint| { try s.dumpRef(writer, type_hint); try writer.writeAll(", "); } - try s.dumpRefMarkerList(writer, data.items.slice(teg), '[', ']'); + try s.dumpRefMarkerList(writer, data.items.slice(hir), '[', ']'); try writer.writeAll(")"); }, .result_type_argument => { - const data: Teg.ResultTypeArgument = teg.instData(.result_type_argument, inst); + const data: Hir.ResultTypeArgument = hir.instData(.result_type_argument, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.call_base); @@ -351,15 +351,15 @@ const State = struct { try writer.writeAll(")"); }, .result_type_struct_field => { - const data: Teg.ResultTypeStructField = teg.instData(.result_type_struct_field, inst); + const data: Hir.ResultTypeStructField = hir.instData(.result_type_struct_field, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.type); - try writer.print(", {s}", .{data.field.slice(s.teg.string_bytes)}); + try writer.print(", {s}", .{data.field.slice(s.hir.string_bytes)}); try writer.writeAll(")"); }, .result_type_tuple_field => { - const data: Teg.ResultTypeTupleField = teg.instData(.result_type_tuple_field, inst); + const data: Hir.ResultTypeTupleField = hir.instData(.result_type_tuple_field, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.type); @@ -367,7 +367,7 @@ const State = struct { try writer.writeAll(")"); }, .result_type_array_value => { - const data: Teg.ResultTypeArrayValue = teg.instData(.result_type_array_value, inst); + const data: Hir.ResultTypeArrayValue = hir.instData(.result_type_array_value, inst); try writer.writeAll("("); try s.dumpRefMarker(writer, data.type); @@ -376,7 +376,7 @@ const State = struct { } } - fn dumpRef(s: *State, writer: anytype, ref: Teg.Inst.Ref) !void { + fn dumpRef(s: *State, writer: anytype, ref: Hir.Inst.Ref) !void { switch (ref.decode()) { .index => |index| try s.dumpInst(writer, index), .value => { @@ -387,7 +387,7 @@ const State = struct { } } - fn dumpRefMarker(s: *State, writer: anytype, ref: Teg.Inst.Ref) !void { + fn dumpRefMarker(s: *State, writer: anytype, ref: Hir.Inst.Ref) !void { switch (ref.decode()) { .index => |index| { try s.tty.setColor(writer, .blue); @@ -402,7 +402,7 @@ const State = struct { } } - fn dumpInstList(state: *State, writer: anytype, list: []const Teg.Inst.Index, l: u8, r: u8) !void { + fn dumpInstList(state: *State, writer: anytype, list: []const Hir.Inst.Index, l: u8, r: u8) !void { try writer.print(" {c}", .{l}); if (list.len > 0) { state.indent += 1; @@ -418,7 +418,7 @@ const State = struct { try writer.print("{c}", .{r}); } - fn dumpInstList2(state: *State, writer: anytype, list: []const Teg.Inst.Index, l: u8, r: u8) !void { + fn dumpInstList2(state: *State, writer: anytype, list: []const Hir.Inst.Index, l: u8, r: u8) !void { try writer.print(" {c}", .{l}); if (list.len > 0) { state.indent += 1; @@ -434,7 +434,7 @@ const State = struct { try writer.print("{c}", .{r}); } - fn dumpRefList(state: *State, writer: anytype, list: []const Teg.Inst.Ref, l: u8, r: u8) !void { + fn dumpRefList(state: *State, writer: anytype, list: []const Hir.Inst.Ref, l: u8, r: u8) !void { try writer.print(" {c}", .{l}); if (list.len > 0) { state.indent += 1; @@ -451,7 +451,7 @@ const State = struct { try writer.print("{c}", .{r}); } - fn dumpOptionalRefList(state: *State, writer: anytype, list: []const Teg.Inst.Ref.Optional, l: u8, r: u8) !void { + fn dumpOptionalRefList(state: *State, writer: anytype, list: []const Hir.Inst.Ref.Optional, l: u8, r: u8) !void { try writer.print(" {c}", .{l}); if (list.len > 0) { state.indent += 1; @@ -474,7 +474,7 @@ const State = struct { try writer.print("{c}", .{r}); } - fn dumpRefMarkerList(state: *State, writer: anytype, list: []const Teg.Inst.Ref, l: u8, r: u8) !void { + fn dumpRefMarkerList(state: *State, writer: anytype, list: []const Hir.Inst.Ref, l: u8, r: u8) !void { try writer.print("{c}", .{l}); if (list.len > 0) { state.indent += 1; @@ -503,9 +503,9 @@ pub fn format( var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); - const teg = dump.teg; + const hir = dump.hir; var state = State{ - .teg = &teg, + .hir = &hir, .tty = dump.tty orelse detectTTYFromWriter(writer), .arena = arena.allocator(), }; @@ -518,5 +518,5 @@ const std = @import("std"); const assert = std.debug.assert; const core = @import("mod.zig"); -const Teg = core.Teg; +const Hir = core.Hir; const detectTTYFromWriter = core.detectTTYFromWriter; diff --git a/src/core/Teg.zig b/src/core/Hir.zig similarity index 78% rename from src/core/Teg.zig rename to src/core/Hir.zig index 11b844392eb6864598b6b79f087ba3af50f1b51e..9225070af8bc6b57955d667d7f732c9cdcc68d27 100644 --- a/src/core/Teg.zig +++ b/src/core/Hir.zig @@ -1,14 +1,25 @@ -//! TODO: rename this to EIR (expression intermediate representation) +//! High-level Intermediate Representation is an instruction list format that +//! describes a source file in a manner effective for Semantic Analysis to +//! process. The root instruction of every Hir is a `.module` that contains the +//! root declarations. Each declaration's value contains a list of instructions. +//! In contrast to the nested nature of syntax trees, Hir represents nested +//! expressions as flat instruction sequences. +//! +//! Hir for a given file has no dependencies on it's imports, meaning it can be +//! computed in parallel and cached when not changed. +//! +//! A helper program exists to visualize Hir: './build transform -- ./file.ix' +//! Alternatively, `ix build` has the `--dump-ir` option. insts: Inst.List.Slice, string_bytes: []const u8, extra: ExtraStore = .{}, report: Report, -pub const ExtraStore = dod.ExtraStore(.teg, .@"const"); +pub const ExtraStore = dod.ExtraStore(.hir, .@"const"); pub const EncodedData = dod.EncodedData(Tag, u64); pub const ExtraIndex = ExtraStore.Index; -pub const Dump = @import("Teg.Dump.zig"); +pub const Dump = @import("Hir.Dump.zig"); pub const Tag = enum(u8) { /// Either the top level module or a `module` keyword. Contains a list of `.declarations` @@ -230,9 +241,9 @@ pub const Inst = struct { tag: Tag, data: EncodedData, - /// The position of a Teg instruction within the `Teg` instructions array. + /// The position of a Hir instruction within the `Hir` instructions array. pub const Index = enum(u32) { - /// Teg is structured so that the outermost "main" struct of any file + /// Hir is structured so that the outermost "main" struct of any file /// is always at index 0. main_module_inst = 0, _, @@ -291,7 +302,7 @@ pub const Inst = struct { pub const Decoded = union(enum) { value: InternPool.Value, - index: Teg.Inst.Index, + index: Hir.Inst.Index, }; pub fn decode(ref: Ref) Decoded { @@ -390,15 +401,15 @@ pub const StructDecl = struct { payload_index: u32, field_len: u32, - pub fn keys(decl: StructDecl, teg: *const Teg) []const NullTerminatedString { + pub fn keys(decl: StructDecl, hir: *const Hir) []const NullTerminatedString { return @ptrCast( - teg.extra.list.items[decl.payload_index..][0..decl.field_len], + hir.extra.list.items[decl.payload_index..][0..decl.field_len], ); } - pub fn types(decl: StructDecl, teg: *const Teg) []const Inst.Ref { + pub fn types(decl: StructDecl, hir: *const Hir) []const Inst.Ref { return @ptrCast( - teg.extra.list.items[decl.payload_index + decl.field_len ..][0..decl.field_len], + hir.extra.list.items[decl.payload_index + decl.field_len ..][0..decl.field_len], ); } }; @@ -409,15 +420,15 @@ pub const StructInit = struct { payload_index: u32, field_len: u32, - pub fn keys(decl: StructInit, teg: *const Teg) []const NullTerminatedString { + pub fn keys(decl: StructInit, hir: *const Hir) []const NullTerminatedString { return @ptrCast( - teg.extra.list.items[decl.payload_index..][0..decl.field_len], + hir.extra.list.items[decl.payload_index..][0..decl.field_len], ); } - pub fn inits(decl: StructInit, teg: *const Teg) []const Inst.Ref { + pub fn inits(decl: StructInit, hir: *const Hir) []const Inst.Ref { return @ptrCast( - teg.extra.list.items[decl.payload_index + decl.field_len ..][0..decl.field_len], + hir.extra.list.items[decl.payload_index + decl.field_len ..][0..decl.field_len], ); } }; @@ -532,8 +543,8 @@ pub const RefList = struct { start: u32, len: u32, - pub fn slice(self: RefList, teg: *const Teg) []const Inst.Ref { - return @ptrCast(teg.extra.list.items[self.start..][0..self.len]); + pub fn slice(self: RefList, hir: *const Hir) []const Inst.Ref { + return @ptrCast(hir.extra.list.items[self.start..][0..self.len]); } }; @@ -541,8 +552,8 @@ pub const OptionalRefList = struct { start: u32, len: u32, - pub fn slice(self: OptionalRefList, teg: *const Teg) []const Inst.Ref.Optional { - return @ptrCast(teg.extra.list.items[self.start..][0..self.len]); + pub fn slice(self: OptionalRefList, hir: *const Hir) []const Inst.Ref.Optional { + return @ptrCast(hir.extra.list.items[self.start..][0..self.len]); } }; @@ -550,8 +561,8 @@ pub const IndexList = struct { start: u32, len: u32, - pub fn slice(self: IndexList, teg: *const Teg) []const Inst.Index { - return @ptrCast(teg.extra.list.items[self.start..][0..self.len]); + pub fn slice(self: IndexList, hir: *const Hir) []const Inst.Index { + return @ptrCast(hir.extra.list.items[self.start..][0..self.len]); } }; @@ -559,42 +570,42 @@ pub const NullTermStringList = struct { start: u32, len: u32, - pub fn slice(self: IndexList, teg: *const Teg) []const NullTerminatedString { - return @ptrCast(teg.extra.list.items[self.start..][0..self.len]); + pub fn slice(self: IndexList, hir: *const Hir) []const NullTerminatedString { + return @ptrCast(hir.extra.list.items[self.start..][0..self.len]); } }; -pub fn deinit(teg: *Teg, gpa: std.mem.Allocator) void { - gpa.free(teg.string_bytes); - teg.extra.deinit(gpa); - teg.insts.deinit(gpa); - teg.report.deinit(gpa); - teg.* = undefined; +pub fn deinit(hir: *Hir, gpa: std.mem.Allocator) void { + gpa.free(hir.string_bytes); + hir.extra.deinit(gpa); + hir.insts.deinit(gpa); + hir.report.deinit(gpa); + hir.* = undefined; } -pub fn instTag(teg: *const Teg, index: Inst.Index) Teg.Tag { - return teg.insts.items(.tag)[@intFromEnum(index)]; +pub fn instTag(hir: *const Hir, index: Inst.Index) Hir.Tag { + return hir.insts.items(.tag)[@intFromEnum(index)]; } -pub fn instEncodedData(teg: *const Teg, index: Inst.Index) EncodedData { - return teg.insts.items(.data)[@intFromEnum(index)]; +pub fn instEncodedData(hir: *const Hir, index: Inst.Index) EncodedData { + return hir.insts.items(.data)[@intFromEnum(index)]; } -pub fn instData(teg: *const Teg, comptime tag: Teg.Tag, index: Inst.Index) tag.Data() { - return teg.instEncodedData(index).decode(tag, teg.instTag(index)); +pub fn instData(hir: *const Hir, comptime tag: Hir.Tag, index: Inst.Index) tag.Data() { + return hir.instEncodedData(index).decode(tag, hir.instTag(index)); } -pub fn instDataUnsafe(teg: *const Teg, comptime T: type, index: Inst.Index) T { - return teg.instEncodedData(index).decodeUnsafe(T, teg.instTag(index)); +pub fn instDataUnsafe(hir: *const Hir, comptime T: type, index: Inst.Index) T { + return hir.instEncodedData(index).decodeUnsafe(T, hir.instTag(index)); } -pub fn instPayload(teg: *const Teg, comptime tag: Teg.Tag, index: Inst.Index) tag.Data().T { - return teg.instData(tag, index).extra_index.get(teg); +pub fn instPayload(hir: *const Hir, comptime tag: Hir.Tag, index: Inst.Index) tag.Data().T { + return hir.instData(tag, index).extra_index.get(hir); } -pub fn instNodeOffset(teg: *const Teg, index: Inst.Index) i32 { - return switch (teg.instTag(index)) { - // these nodes never get errors, but Teg.Dump will print these regardless +pub fn instNodeOffset(hir: *const Hir, index: Inst.Index) i32 { + return switch (hir.instTag(index)) { + // these nodes never get errors, but Hir.Dump will print these regardless // TODO: .declaration, .result_type_argument, @@ -603,23 +614,23 @@ pub fn instNodeOffset(teg: *const Teg, index: Inst.Index) i32 { .result_type_array_value, => 0, - inline else => |tag| teg.instData(tag, index).src_node, + inline else => |tag| hir.instData(tag, index).src_node, }; } -pub fn blockInstructions(teg: *const Teg, index: Inst.Index) []const Inst.Index { - return teg.instData(.block, index).extra_index.get(teg).slice(teg); +pub fn blockInstructions(hir: *const Hir, index: Inst.Index) []const Inst.Index { + return hir.instData(.block, index).extra_index.get(hir).slice(hir); } -pub fn fullFuncDecl(teg: *const Teg, index: Inst.Index) struct { Teg.Decl, Teg.DeclFn } { - const decl, var trail = teg.instData(.declaration, index).extra_index.getTrail(teg); +pub fn fullFuncDecl(hir: *const Hir, index: Inst.Index) struct { Hir.Decl, Hir.DeclFn } { + const decl, var trail = hir.instData(.declaration, index).extra_index.getTrail(hir); assert(decl.kind == .function); - const decl_fn = trail.read(&teg.extra, Teg.DeclFn); + const decl_fn = trail.read(&hir.extra, Hir.DeclFn); return .{ decl, decl_fn }; } -pub fn fullDecl(teg: *const Teg, index: Inst.Index) Decl { - const decl = teg.instEncodedData(index).decodeUnsafe(PlNode(Decl), teg.instTag(index)).extra_index.get(teg); +pub fn fullDecl(hir: *const Hir, index: Inst.Index) Decl { + const decl = hir.instEncodedData(index).decodeUnsafe(PlNode(Decl), hir.instTag(index)).extra_index.get(hir); return .{ .name = decl.name, .hash = decl.hash, @@ -628,20 +639,20 @@ pub fn fullDecl(teg: *const Teg, index: Inst.Index) Decl { }; } -pub fn declData(teg: *const Teg, index: Inst.Index) Teg.Decl { - return teg.instDataUnsafe(PlNode(Decl), index).extra_index.get(teg); +pub fn declData(hir: *const Hir, index: Inst.Index) Hir.Decl { + return hir.instDataUnsafe(PlNode(Decl), index).extra_index.get(hir); } -pub fn moduleDeclarations(teg: *const Teg, module_index: Inst.Index) []const Inst.Index { - const module = teg.instData(.module, module_index); - const module_data: IndexList = module.extra_index.get(teg); - const slice = module_data.slice(teg); +pub fn moduleDeclarations(hir: *const Hir, module_index: Inst.Index) []const Inst.Index { + const module = hir.instData(.module, module_index); + const module_data: IndexList = module.extra_index.get(hir); + const slice = module_data.slice(hir); if (core.runtime_safety) { for (slice) |item| { - switch (teg.instTag(item)) { + switch (hir.instTag(item)) { .declaration, .variable_declaration, .test_declaration => {}, else => { - std.debug.panic("\ngot unknown tag {s}\n", .{@tagName(teg.instTag(item))}); + std.debug.panic("\ngot unknown tag {s}\n", .{@tagName(hir.instTag(item))}); }, } } @@ -649,21 +660,21 @@ pub fn moduleDeclarations(teg: *const Teg, module_index: Inst.Index) []const Ins return slice; } -pub fn rootFunction(teg: *const Teg) Inst.Index { - const decls = teg.moduleDeclarations(.main_module_inst); +pub fn rootFunction(hir: *const Hir) Inst.Index { + const decls = hir.moduleDeclarations(.main_module_inst); const root_fn = decls[decls.len - 1]; - assert(teg.declName(root_fn).len == 0); + assert(hir.declName(root_fn).len == 0); return root_fn; } -pub fn declName(teg: *const Teg, decl_index: Inst.Index) []const u8 { - const decl = teg.instDataUnsafe(PlNode(Decl), decl_index); - const decl_data: Decl = decl.extra_index.get(teg); - return decl_data.name.slice(teg.string_bytes); +pub fn declName(hir: *const Hir, decl_index: Inst.Index) []const u8 { + const decl = hir.instDataUnsafe(PlNode(Decl), decl_index); + const decl_data: Decl = decl.extra_index.get(hir); + return decl_data.name.slice(hir.string_bytes); } -pub fn dumpToWriter(teg: Teg, writer: anytype, tty: ?std.io.tty.Config) !void { - try writer.print("{}", .{Dump{ .teg = teg, .tty = tty }}); +pub fn dumpToWriter(hir: Hir, writer: anytype, tty: ?std.io.tty.Config) !void { + try writer.print("{}", .{Dump{ .hir = hir, .tty = tty }}); } /// Used for generating decl hashes @@ -680,7 +691,7 @@ fn isolatedIndexValue(decl_index: Inst.Index, index_to_hash: Inst.Index) u32 { } pub fn writeToHasher( - teg: *const Teg, + hir: *const Hir, hasher: *HashHelper, tag_list: []Tag, data_list: []EncodedData, @@ -692,7 +703,7 @@ pub fn writeToHasher( // Add all of the data for (tag_list, data_list) |tag, data| { - // This should roughly line up with Teg.Tag.Data + // This should roughly line up with Hir.Tag.Data switch (tag) { // PlNode(IndexList), .module, @@ -701,7 +712,7 @@ pub fn writeToHasher( => { const pl_node = data.decodeUnsafe(PlNode(IndexList), tag); hasher.add(pl_node.src_node); - writeIndexListToHasher(hasher, pl_node.extra_index.get(teg).slice(teg), decl_index); + writeIndexListToHasher(hasher, pl_node.extra_index.get(hir).slice(hir), decl_index); }, // PlNode @@ -727,13 +738,13 @@ pub fn writeToHasher( => |pl_node_tag| { const pl_node = data.decode(pl_node_tag, tag); hasher.add(pl_node.src_node); - teg.writePlNodeInnerToHasher(hasher, pl_node_tag.Data().T, pl_node.extra_index.get(teg), decl_index); + hir.writePlNodeInnerToHasher(hasher, pl_node_tag.Data().T, pl_node.extra_index.get(hir), decl_index); }, // StrNode .load_decl => { const str_node = data.decodeUnsafe(StrNode, tag); hasher.add(str_node.src_node); - hasher.addBytes(str_node.string.slice(teg.string_bytes)); + hasher.addBytes(str_node.string.slice(hir.string_bytes)); }, // DataNode .param => { @@ -784,7 +795,7 @@ pub fn writeToHasher( .ge, => { const pl_node = data.decodeUnsafe(PlNode(Bin), tag); - const bin = pl_node.extra_index.get(teg); + const bin = pl_node.extra_index.get(hir); hasher.add(isolatedRefValue(decl_index, bin.lhs)); hasher.add(isolatedRefValue(decl_index, bin.rhs)); }, @@ -797,7 +808,7 @@ pub fn writeToHasher( .result_type_struct_field => { const struct_field = data.decodeUnsafe(ResultTypeStructField, tag); hasher.add(isolatedRefValue(decl_index, struct_field.type)); - hasher.addBytes(struct_field.field.slice(teg.string_bytes)); + hasher.addBytes(struct_field.field.slice(hir.string_bytes)); }, .result_type_tuple_field => { const tuple_field = data.decodeUnsafe(ResultTypeTupleField, tag); @@ -835,7 +846,7 @@ fn writeRefListToHasher( } fn writePlNodeInnerToHasher( - teg: *const Teg, + hir: *const Hir, hasher: *HashHelper, comptime T: type, data: T, @@ -844,7 +855,7 @@ fn writePlNodeInnerToHasher( switch (T) { Decl => { hasher.addBytes(&data.hash); - hasher.addBytes(data.name.slice(teg.string_bytes)); + hasher.addBytes(data.name.slice(hir.string_bytes)); }, Float => { const as_bytes: [2]u32 = .{ @@ -854,7 +865,7 @@ fn writePlNodeInnerToHasher( hasher.add(@as(u64, @bitCast(as_bytes))); }, SlicedString => { - hasher.addBytes(data.slice(teg.string_bytes)); + hasher.addBytes(data.slice(hir.string_bytes)); }, Coercion => { hasher.add(isolatedRefValue(decl_index, data.type)); @@ -866,7 +877,7 @@ fn writePlNodeInnerToHasher( }, Call => { hasher.add(isolatedRefValue(decl_index, data.base)); - writeRefListToHasher(hasher, decl_index, data.args.slice(teg)); + writeRefListToHasher(hasher, decl_index, data.args.slice(hir)); }, If => { hasher.add(isolatedRefValue(decl_index, data.cond)); @@ -883,25 +894,25 @@ fn writePlNodeInnerToHasher( hasher.add(isolatedRefValue(decl_index, data.operand)); }, StoreVarDecl => { - hasher.addBytes(data.var_decl.slice(teg.string_bytes)); + hasher.addBytes(data.var_decl.slice(hir.string_bytes)); hasher.add(isolatedRefValue(decl_index, data.operand)); }, JsNew => { hasher.add(isolatedRefValue(decl_index, data.base)); - writeRefListToHasher(hasher, decl_index, data.args.slice(teg)); + writeRefListToHasher(hasher, decl_index, data.args.slice(hir)); }, StructDecl => { hasher.add(data.field_len); - for (data.keys(teg), data.types(teg)) |key, ty| { - hasher.addBytes(key.slice(teg.string_bytes)); + for (data.keys(hir), data.types(hir)) |key, ty| { + hasher.addBytes(key.slice(hir.string_bytes)); hasher.add(isolatedRefValue(decl_index, ty)); } }, StructInit => { hasher.add(isolatedRefValue(decl_index, data.base_type)); hasher.add(data.field_len); - for (data.keys(teg), data.inits(teg)) |key, init| { - hasher.addBytes(key.slice(teg.string_bytes)); + for (data.keys(hir), data.inits(hir)) |key, init| { + hasher.addBytes(key.slice(hir.string_bytes)); hasher.add(isolatedRefValue(decl_index, init)); } }, @@ -910,10 +921,10 @@ fn writePlNodeInnerToHasher( hasher.add(isolatedRefValue(decl_index, type_hint)) else hasher.add(@as(i32, std.math.maxInt(i32))); - writeRefListToHasher(hasher, decl_index, data.list.slice(teg)); + writeRefListToHasher(hasher, decl_index, data.list.slice(hir)); }, Func => { - for (data.params.slice(teg)) |optional| { + for (data.params.slice(hir)) |optional| { if (optional.unwrap()) |item| hasher.add(isolatedRefValue(decl_index, item)); } @@ -928,7 +939,7 @@ fn writePlNodeInnerToHasher( }, TupleType => { hasher.add(data.items.len); - for (data.items.slice(teg)) |item| { + for (data.items.slice(hir)) |item| { hasher.add(isolatedRefValue(decl_index, item)); } }, @@ -937,7 +948,7 @@ fn writePlNodeInnerToHasher( hasher.add(isolatedRefValue(decl_index, type_hint)) else hasher.add(@as(i32, std.math.maxInt(i32))); - writeRefListToHasher(hasher, decl_index, data.items.slice(teg)); + writeRefListToHasher(hasher, decl_index, data.items.slice(hir)); }, else => @compileError("hash not implemented for " ++ @typeName(T)), } @@ -953,29 +964,29 @@ pub const SerializedHeader = extern struct { report_warn_len: u32, }; -pub fn serialize(teg: Teg, target: core.SerializeTarget) !void { +pub fn serialize(hir: Hir, target: core.SerializeTarget) !void { const header: SerializedHeader = .{ - .instruction_len = @intCast(teg.insts.len), - .string_bytes = @intCast(teg.string_bytes.len), - .extra_len = @intCast(teg.extra.list.items.len), - .report_err_len = @intCast(teg.report.errors.len), - .report_warn_len = @intCast(teg.report.warnings.len), + .instruction_len = @intCast(hir.insts.len), + .string_bytes = @intCast(hir.string_bytes.len), + .extra_len = @intCast(hir.extra.list.items.len), + .report_err_len = @intCast(hir.report.errors.len), + .report_warn_len = @intCast(hir.report.warnings.len), }; var iovecs = [_]std.posix.iovec_const{ core.iovecConst(SerializedHeader.version), core.iovecConst(std.mem.asBytes(&header)), - core.iovecConst(std.mem.sliceAsBytes(teg.insts.items(.tag))), - core.iovecConst(std.mem.sliceAsBytes(teg.insts.items(.data))), - core.iovecConst(teg.string_bytes), - core.iovecConst(std.mem.sliceAsBytes(teg.extra.list.items)), - core.iovecConst(std.mem.sliceAsBytes(teg.report.errors)), - core.iovecConst(std.mem.sliceAsBytes(teg.report.warnings)), + core.iovecConst(std.mem.sliceAsBytes(hir.insts.items(.tag))), + core.iovecConst(std.mem.sliceAsBytes(hir.insts.items(.data))), + core.iovecConst(hir.string_bytes), + core.iovecConst(std.mem.sliceAsBytes(hir.extra.list.items)), + core.iovecConst(std.mem.sliceAsBytes(hir.report.errors)), + core.iovecConst(std.mem.sliceAsBytes(hir.report.warnings)), }; try target.writev(&iovecs); } -const Teg = @This(); +const Hir = @This(); const std = @import("std"); const mem = std.mem; diff --git a/src/core/InternPool.zig b/src/core/InternPool.zig index 01aea56e759f7bded40c5df6bb801c5c634ec0ca..5671940652839126f561c7ebdd219e84f02d8073 100644 --- a/src/core/InternPool.zig +++ b/src/core/InternPool.zig @@ -638,7 +638,7 @@ pub const ExtraIndex = ExtraStore.Index; /// This is specified with an integer literal and a corresponding comptime /// assert below to break an unfortunate and arguably incorrect dependency loop /// when compiling. -pub const static_len = Teg.Inst.Index.static_len; +pub const static_len = Hir.Inst.Index.static_len; comptime { // @compileLog(static_len, static_keys.len); assert(static_len == static_keys.len); @@ -805,16 +805,16 @@ pub const NullTerminatedString = enum(u32) { pub const TrackedInst = extern struct { path_digest: Cache.BinDigest, - inst: Teg.Inst.Index, + inst: Hir.Inst.Index, comptime { // The fields should be tightly packed. See also serialization logic in `Compilation.saveState`. - assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Teg.Inst.Index)); + assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Hir.Inst.Index)); } pub const Index = enum(u32) { _, - pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Teg.Inst.Index { + pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Hir.Inst.Index { return i.get(ip).inst; } @@ -1659,7 +1659,7 @@ fn getOrPutTrailingString( } } -pub fn trackInst(ip: *InternPool, gpa: Allocator, file: *Comp.File, inst: Teg.Inst.Index) Allocator.Error!TrackedInst.Index { +pub fn trackInst(ip: *InternPool, gpa: Allocator, file: *Comp.File, inst: Hir.Inst.Index) Allocator.Error!TrackedInst.Index { const t = tracer.trace(@src()); defer t.end(); @@ -1869,7 +1869,7 @@ const assert = std.debug.assert; const core = @import("mod.zig"); const Comp = core.Comp; const Cache = core.Cache; -const Teg = core.Teg; +const Hir = core.Hir; const Air = core.Air; const dod = core.array; const Float = dod.Float; diff --git a/src/core/Report.zig b/src/core/Report.zig index 014f534bbd9cd9075db29f53366b24aacf76f54d..8c485ec5132d66a1bb8cf08aad8be95eecf644fe 100644 --- a/src/core/Report.zig +++ b/src/core/Report.zig @@ -1093,7 +1093,7 @@ pub const MsgContext = struct { pub const LazyNode = struct { // TODO: remove this, it should be inferable off of the analysis unit that belongs to the report decl: Comp.Decl.Index, - inst: Teg.Inst.Index, + inst: Hir.Inst.Index, operand: Operand, pub fn get(lazy: LazyNode, ctx: *MsgContext) !NodeIndex { @@ -1111,15 +1111,15 @@ pub const LazyNode = struct { @panic("TODO: LazyNode.get when the decl is in a nested namespace"); } - const teg = &(ctx.file.?.teg orelse + const hir = &(ctx.file.?.hir orelse // this will be required once incremental compilation hits - @panic("TODO: teg was unloaded")); + @panic("TODO: hir was unloaded")); const decl_inst = decl.teg_decl_index; - const teg_decl = teg.instData(.declaration, decl_inst.resolve(ctx.ip())); + const teg_decl = hir.instData(.declaration, decl_inst.resolve(ctx.ip())); - const node_offset = teg.instNodeOffset(lazy.inst); + const node_offset = hir.instNodeOffset(lazy.inst); const base_node: NodeIndex = @intCast(teg_decl.src_node + node_offset); if (lazy.operand == .main_node) @@ -1129,7 +1129,7 @@ pub const LazyNode = struct { const node_tag = ctx.ast.nodeTag(base_node); - switch (teg.instTag(lazy.inst)) { + switch (hir.instTag(lazy.inst)) { .coercion => switch (node_tag) { .var_decl => switch (lazy.operand) { .lhs => return data.var_decl.type.unwrap().?, @@ -1213,7 +1213,7 @@ pub const LazyNode = struct { } std.debug.print("TODO: operand lookup: .{s} + .{s} + {}\n", .{ - @tagName(teg.instTag(lazy.inst)), + @tagName(hir.instTag(lazy.inst)), @tagName(ctx.ast.nodeTag(base_node)), lazy.operand, }); @@ -1467,7 +1467,7 @@ const TokenIndex = Ast.TokenIndex; const NodeIndex = Ast.NodeIndex; const Location = Ast.Location; -const Teg = core.Teg; +const Hir = core.Hir; const Comp = core.Comp; const File = Comp.File; diff --git a/src/core/Sema.zig b/src/core/Sema.zig index 1366aed00beae7d9b392bff8adddcefe7a381346..ce5efa254618074d6fb1c0b16e30df1372d4bd02 100644 --- a/src/core/Sema.zig +++ b/src/core/Sema.zig @@ -1,13 +1,9 @@ -//! Semantic Analysis converts `Teg` +//! Semantic Analysis converts `Hir` to `Air` by stepping over every instruction +//! and evaluating comptime values or emitting runtime instructions. //! -//! Designed as a nonrecursive state machine which can be paused when an -//! unfinished dependency is encountered, allowing the thread to work -//! on other analysis jobs. -//! -//! Sema's responsibilities include -//! - Operation validation and reporting of most compile errors. -//! - Evaluation of `comptime` code. -//! - Declaring dependencies on other analysis units. +//! Designed as a nonrecursive state machine, `Sema` can be paused when an +//! unfinished dependency is encountered, allowing the thread to work on other +//! analysis jobs. comp: *Comp, ip: *InternPool, @@ -20,13 +16,13 @@ owner: AnalysisUnit, /// The namespace index that is used for declaration lookups ns_index: Namespace.Index, /// Non-owning copy -teg: Teg, -/// The file that .teg is from +hir: Hir, +/// The file that .hir is from file: *File, /// All errors and warnings from this decl report: Report.Builder, -/// Map of `Teg` instructions to their resulting `Air` Ref +/// Map of `Hir` instructions to their resulting `Air` Ref inst_map: InstMap, /// `null` when not analyzing function bodies @@ -63,7 +59,7 @@ pub fn init( s: *Sema, comp: *Comp, file: *File, - teg: Teg, + hir: Hir, owner: AnalysisUnit, ns_index: Namespace.Index, arena_state: std.heap.ArenaAllocator, @@ -82,7 +78,7 @@ pub fn init( .arena_state = arena_state, .owner = owner, .ns_index = ns_index, - .teg = teg, + .hir = hir, .file = file, .report = .init(comp.gpa), @@ -102,12 +98,12 @@ pub fn init( const first_instruction, const count = switch (owner.unwrap()) { .decl => |decl| data: { const decl_inst = s.ip.declPtr(decl).teg_decl_index.resolve(s.ip); - const teg_decl: Teg.Decl = teg.instPayload(.declaration, decl_inst); + const teg_decl: Hir.Decl = hir.instPayload(.declaration, decl_inst); break :data .{ decl_inst, teg_decl.instruction_count }; }, .func => |value| data: { const func_inst = value.toKey(s.ip).func.teg_body_inst.get(s.ip); - const func: Teg.Func = teg.instPayload(.func, func_inst.inst); + const func: Hir.Func = hir.instPayload(.func, func_inst.inst); break :data .{ func.body, func.instruction_count }; }, }; @@ -115,7 +111,7 @@ pub fn init( s.inst_map = try .init(s.arena(), first_instruction, count); const block_index = switch (owner.unwrap()) { - .decl => switch (s.teg.declData(first_instruction).body.decode()) { + .decl => switch (s.hir.declData(first_instruction).body.decode()) { .index => |index| index, .value => unreachable, // Sema must not be created for a static value }, @@ -165,11 +161,11 @@ const AnalysisMode = enum { }; const Frame = struct { - ip: [*]const Teg.Inst.Index, + ip: [*]const Hir.Inst.Index, instructions_left: if (runtime_safety) usize else void, mode: AnalysisMode, - block_index: Teg.Inst.Index, + block_index: Hir.Inst.Index, mark_index: u32, data: Data, @@ -192,15 +188,15 @@ const Frame = struct { argument: u16, }; - fn initFromBlock(s: *Sema, block_index: Teg.Inst.Index, mode: AnalysisMode, data: Data) Frame { - switch (s.teg.instTag(block_index)) { + fn initFromBlock(s: *Sema, block_index: Hir.Inst.Index, mode: AnalysisMode, data: Data) Frame { + switch (s.hir.instTag(block_index)) { else => unreachable, // not a block .block, .@"comptime" => {}, } - const list = s.teg.instEncodedData(block_index) - .decodeUnsafe(Teg.PlNode(Teg.IndexList), s.teg.instTag(block_index)) - .extra_index.get(&s.teg) - .slice(&s.teg); + const list = s.hir.instEncodedData(block_index) + .decodeUnsafe(Hir.PlNode(Hir.IndexList), s.hir.instTag(block_index)) + .extra_index.get(&s.hir) + .slice(&s.hir); return .{ .ip = list[0..].ptr, .instructions_left = if (runtime_safety) list.len, @@ -211,12 +207,12 @@ const Frame = struct { }; } - fn currentIndex(frame: *const Frame) Teg.Inst.Index { + fn currentIndex(frame: *const Frame) Hir.Inst.Index { // validate the pointer is correct if (runtime_safety) { const s: *const Sema = @fieldParentPtr("frame", frame); assert(s.magic == .valid); - const extra = s.teg.extra.list.items; + const extra = s.hir.extra.list.items; assert(@intFromPtr(frame.ip) > @intFromPtr(extra.ptr) and @intFromPtr(frame.ip) <= @intFromPtr(&extra.ptr[extra.len - 1])); } @@ -224,22 +220,22 @@ const Frame = struct { return frame.ip[0]; } - fn currentTag(frame: *const Frame) Teg.Tag { + fn currentTag(frame: *const Frame) Hir.Tag { const s: *const Sema = @fieldParentPtr("frame", frame); assert(s.magic == .valid); - return s.teg.instTag(frame.currentIndex()); + return s.hir.instTag(frame.currentIndex()); } - fn currentData(frame: *const Frame, comptime tag: Teg.Tag) tag.Data() { + fn currentData(frame: *const Frame, comptime tag: Hir.Tag) tag.Data() { const s: *const Sema = @fieldParentPtr("frame", frame); assert(s.magic == .valid); - return s.teg.instData(tag, frame.currentIndex()); + return s.hir.instData(tag, frame.currentIndex()); } - fn currentPayload(frame: *const Frame, comptime tag: Teg.Tag) tag.Data().T { + fn currentPayload(frame: *const Frame, comptime tag: Hir.Tag) tag.Data().T { const s: *const Sema = @fieldParentPtr("frame", frame); assert(s.magic == .valid); - return s.teg.instPayload(tag, frame.currentIndex()); + return s.hir.instPayload(tag, frame.currentIndex()); } fn advance(frame: *Frame) void { @@ -282,10 +278,10 @@ const Function = struct { /// instructions it has. const InstMap = struct { items: []Air.Inst.Ref.Optional, - start: Teg.Inst.Index, + start: Hir.Inst.Index, debug_traces: if (runtime_safety) []StoredTrace else void, - pub fn init(allocator: Allocator, inst_start: Teg.Inst.Index, inst_len: u32) !InstMap { + pub fn init(allocator: Allocator, inst_start: Hir.Inst.Index, inst_len: u32) !InstMap { const insts = try allocator.alloc(Air.Inst.Ref.Optional, inst_len); errdefer allocator.free(insts); @@ -309,7 +305,7 @@ const InstMap = struct { map.* = undefined; } - pub fn getOrNull(map: *const InstMap, teg_code: Teg.Inst.Index) ?Air.Inst.Ref { + pub fn getOrNull(map: *const InstMap, teg_code: Hir.Inst.Index) ?Air.Inst.Ref { const source_i = @intFromEnum(teg_code); const start_i = @intFromEnum(map.start); if (assertFailed(source_i >= start_i and source_i <= start_i + map.items.len)) { @@ -322,7 +318,7 @@ const InstMap = struct { return map.items[source_i - start_i].unwrap(); } - pub fn get(map: *const InstMap, teg_code: Teg.Inst.Index) Air.Inst.Ref { + pub fn get(map: *const InstMap, teg_code: Hir.Inst.Index) Air.Inst.Ref { return map.getOrNull(teg_code) orelse { if (runtime_safety) { std.debug.panic("did not analyze %{d}", .{@intFromEnum(teg_code)}); @@ -331,7 +327,7 @@ const InstMap = struct { }; } - pub fn add(map: *InstMap, from: Teg.Inst.Index, to: Air.Inst.Ref) void { + pub fn add(map: *InstMap, from: Hir.Inst.Index, to: Air.Inst.Ref) void { const source_i = @intFromEnum(from); const start_i = @intFromEnum(map.start); if (assertFailed(source_i >= start_i and source_i <= start_i + map.items.len)) { @@ -371,7 +367,7 @@ const DoMark = enum { marked, }; -fn getRef(s: *Sema, teg_ref: Teg.Inst.Ref, mark: DoMark) Air.Inst.Ref { +fn getRef(s: *Sema, teg_ref: Hir.Inst.Ref, mark: DoMark) Air.Inst.Ref { switch (teg_ref.decode()) { .value => |value| return value.toAir(), .index => |index| { @@ -389,7 +385,7 @@ fn getRef(s: *Sema, teg_ref: Teg.Inst.Ref, mark: DoMark) Air.Inst.Ref { } } -fn getValue(s: *Sema, src: LazyNode, teg_ref: Teg.Inst.Ref) !Value { +fn getValue(s: *Sema, src: LazyNode, teg_ref: Hir.Inst.Ref) !Value { switch (teg_ref.decode()) { .value => |value| return value, .index => |index| { @@ -399,17 +395,17 @@ fn getValue(s: *Sema, src: LazyNode, teg_ref: Teg.Inst.Ref) !Value { } } -fn getCoercedValue(s: *Sema, src: LazyNode, teg_ref: Teg.Inst.Ref, ty: Type) !Value { +fn getCoercedValue(s: *Sema, src: LazyNode, teg_ref: Hir.Inst.Ref, ty: Type) !Value { const any = try s.getValue(src, teg_ref); return try s.coerceValue(src, any, ty); } -fn getCoercedRef(s: *Sema, src: LazyNode, teg_ref: Teg.Inst.Ref, ty: Type, mark: DoMark) !Air.Inst.Ref { +fn getCoercedRef(s: *Sema, src: LazyNode, teg_ref: Hir.Inst.Ref, ty: Type, mark: DoMark) !Air.Inst.Ref { const any = s.getRef(teg_ref, mark); return try s.coerceRef(src, any, ty); } -fn getType(s: *Sema, src: LazyNode, teg_ref: Teg.Inst.Ref) !Type { +fn getType(s: *Sema, src: LazyNode, teg_ref: Hir.Inst.Ref) !Type { return (try s.getCoercedValue(src, teg_ref, .type)).toTypeUnsafe(s.ip); } @@ -491,7 +487,7 @@ const InstructionKind = enum { control_flow, pop_control_flow, - pub inline fn fromTag(tag: Teg.Tag) InstructionKind { + pub inline fn fromTag(tag: Hir.Tag) InstructionKind { return switch (tag) { // these push new frames, and frame end will assign its value .func, @@ -523,7 +519,7 @@ const InstructionKind = enum { const PopControlFlowState = enum { stop, @"continue" }; -fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag).Result() { +fn stepInner(s: *Sema, comptime tag: Hir.Tag) Error!InstructionKind.fromTag(tag).Result() { switch (tag) { .block => unreachable, // frame must already be pushed .declaration, @@ -534,7 +530,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) // TODO: pre-evaluate `.param` nodes, since they are always at the start of a function. // this way we can avoid repeating the non-trivial call into InternPool .param => { - const param: Teg.DataNode = s.frame.currentData(.param); + const param: Hir.DataNode = s.frame.currentData(.param); assert(s.frame.mode == .run_time); // never emitted in a comptime block assert(s.owner.kind == .func); // only emitted in function body const proto = s.owner.unwrap().func.toKey(s.ip).func.ty.toUnresolvedFunctionPrototype(s.ip).?; @@ -550,8 +546,8 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) } }, .string => { - const string: Teg.SlicedString = s.frame.currentPayload(.string); - return s.makeValueAir(.{ .string = string.slice(s.teg.string_bytes) }); + const string: Hir.SlicedString = s.frame.currentPayload(.string); + return s.makeValueAir(.{ .string = string.slice(s.hir.string_bytes) }); }, .number => { const number: store.Float = s.frame.currentPayload(.number); @@ -565,7 +561,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) .gt, .eq, => { - const bin: Teg.Bin = s.frame.currentPayload(tag); + const bin: Hir.Bin = s.frame.currentPayload(tag); const op = @field(BinaryOp, @tagName(tag)); const lhs = s.getRef(bin.lhs, .marked); @@ -600,7 +596,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }); }, .negate => { - const un: Teg.RefNode = s.frame.currentData(.negate); + const un: Hir.RefNode = s.frame.currentData(.negate); const operand = s.getRef(un.operand, .marked); @@ -622,7 +618,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) return s.addRef(.negate, .{ .operand = operand }); }, .bool_not => { - const un: Teg.RefNode = s.frame.currentData(.bool_not); + const un: Hir.RefNode = s.frame.currentData(.bool_not); const operand = try s.getCoercedRef(s.lazyNode(.operand), un.operand, .bool, .marked); @@ -639,7 +635,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) return s.addRef(.bool_not, .{ .operand = operand }); }, .struct_decl => { - const node: Teg.StructDecl = s.frame.currentPayload(.struct_decl); + const node: Hir.StructDecl = s.frame.currentPayload(.struct_decl); const scratch = try s.scratch.reserveMulti( s.arena(), @@ -649,12 +645,12 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) defer scratch.deinit(); // Fill the first half with keys - for (scratch.items(.keys), node.keys(&s.teg)) |*dest, src| { - dest.* = try s.ip.getOrPutString(s.gpa, src.slice(s.teg.string_bytes), .no_embedded_nulls); + for (scratch.items(.keys), node.keys(&s.hir)) |*dest, src| { + dest.* = try s.ip.getOrPutString(s.gpa, src.slice(s.hir.string_bytes), .no_embedded_nulls); } // Fill the second half with coerced values. - for (node.types(&s.teg), 0..) |ty, i| { + for (node.types(&s.hir), 0..) |ty, i| { scratch.at(.types, i).* = try s.getType(s.lazyNode(.argument(@intCast(i))), ty); } @@ -688,7 +684,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) } }); }, .field => { - const field: Teg.Bin = s.frame.currentPayload(.field); + const field: Hir.Bin = s.frame.currentPayload(.field); const lhs = s.getRef(field.lhs, .marked); const lhs_type = s.typeOfRef(lhs); @@ -733,7 +729,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }); }, .call => { - const call: Teg.Call = s.frame.currentPayload(.call); + const call: Hir.Call = s.frame.currentPayload(.call); const base = s.getRef(call.base, .marked); const base_type = s.typeOfRef(base); @@ -759,7 +755,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) } // validate function args - for (proto.param_types, call.args.slice(&s.teg), 0..) |param, arg, i| { + for (proto.param_types, call.args.slice(&s.hir), 0..) |param, arg, i| { const ref = s.getRef(arg, .marked); const coerced = try s.coerceRef( s.lazyNode(.argument(@intCast(i))), @@ -769,7 +765,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) scratch[i] = coerced; } } else { - for (call.args.slice(&s.teg), 0..) |arg, i| { + for (call.args.slice(&s.hir), 0..) |arg, i| { const ref = try s.ensureValueDefinedRepresentation( s.lazyNode(.argument(@intCast(i))), s.getRef(arg, .marked), @@ -792,7 +788,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }); }, .array_init => { - const node: Teg.ArrayInit = s.frame.currentPayload(.array_init); + const node: Hir.ArrayInit = s.frame.currentPayload(.array_init); assert(node.list.len > 0 or node.type_hint.unwrap() != null); @@ -806,7 +802,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) var is_constant = true; - for (node.list.slice(&s.teg), 0..) |item_teg_ref, i| { + for (node.list.slice(&s.hir), 0..) |item_teg_ref, i| { const item = s.getRef(item_teg_ref, .marked); const coerced = if (item_type) |ty| try s.coerceRef(s.lazyNode(.argument(@intCast(i))), item, ty) @@ -862,8 +858,8 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }); }, .store => { - const data: Teg.Store = s.frame.currentPayload(.store); - assert(s.teg.instTag(data.memory) == .memory); // corrupt store instruction + const data: Hir.Store = s.frame.currentPayload(.store); + assert(s.hir.instTag(data.memory) == .memory); // corrupt store instruction try s.ensureAtRuntime(s.lazyNode(.main_node)); // TODO @@ -885,7 +881,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .js_new => { - const call: Teg.JsNew = s.frame.currentPayload(.js_new); + const call: Hir.JsNew = s.frame.currentPayload(.js_new); try s.ensureAtRuntime(s.lazyNode(.main_node)); @@ -893,7 +889,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) const scratch = try s.arena().alloc(Air.Inst.Ref, call.args.len); defer s.arena().free(scratch); - for (call.args.slice(&s.teg), 0..) |arg, i| { + for (call.args.slice(&s.hir), 0..) |arg, i| { const ref = try s.ensureValueDefinedRepresentation( s.lazyNode(.argument(@intCast(i))), s.getRef(arg, .marked), @@ -924,7 +920,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .func => { - const data: Teg.Func = s.frame.currentPayload(.func); + const data: Hir.Func = s.frame.currentPayload(.func); const reserve = try s.scratch.reserveMulti( s.arena(), .{ .params = Type, .captures = Air.Inst.Ref }, @@ -937,7 +933,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) defer handled_reserve.assertUnlocked(); errdefer handled_reserve.unlock(); - for (data.params.slice(&s.teg), 0..) |param, i| { + for (data.params.slice(&s.hir), 0..) |param, i| { const src = s.lazyNode(.argument(@intCast(i))); const known = param.unwrap() orelse @panic("TODO: inferred param sets"); @@ -991,7 +987,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .@"break" => { - const brk: Teg.Break = s.frame.currentPayload(.@"break"); + const brk: Hir.Break = s.frame.currentPayload(.@"break"); const operand = s.getRef(brk.operand, .marked); assert(s.frame.block_index == brk.block); @@ -1036,7 +1032,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) s.frame.advance(); }, .@"if" => { - const if_data: Teg.If = s.frame.currentPayload(.@"if"); + const if_data: Hir.If = s.frame.currentPayload(.@"if"); switch (data.conditional) { .comptime_condition => { @@ -1093,7 +1089,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) s.frame.advance(); }, .func => { - const func_data: Teg.Func = s.frame.currentPayload(.func); + const func_data: Hir.Func = s.frame.currentPayload(.func); const reserve: FunctionReserve = .fromIndex( &s.scratch, @@ -1104,7 +1100,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) const return_type = switch (data.func) { .argument => |arg_num| ret: { for ( - func_data.params.slice(&s.teg)[arg_num + 1 ..], + func_data.params.slice(&s.hir)[arg_num + 1 ..], reserve.items(.params)[arg_num + 1 ..], arg_num + 1.., ) |param, *dst, i| { @@ -1172,10 +1168,10 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .load_decl => { - const request: Teg.StrNode = s.frame.currentData(.load_decl); + const request: Hir.StrNode = s.frame.currentData(.load_decl); const decl_name = try s.ip.getOrPutString( s.gpa, - request.string.slice(s.teg.string_bytes), + request.string.slice(s.hir.string_bytes), .no_embedded_nulls, ); const decl_index = s.lookupDecl(decl_name); @@ -1183,13 +1179,13 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .coercion => { - const as: Teg.Coercion = s.frame.currentPayload(.coercion); + const as: Hir.Coercion = s.frame.currentPayload(.coercion); const coerce_to = try s.getType(s.lazyNode(.operand), as.type); return try s.getCoercedRef(s.lazyNode(.operand), as.operand, coerce_to, .marked); }, .compile_error => { - const node: Teg.RefNode = s.frame.currentData(.compile_error); + const node: Hir.RefNode = s.frame.currentData(.compile_error); const value = try s.getCoercedValue(s.lazyNode(.operand), node.operand, .string); const str = value.asString(s.ip).toSlice(s.ip); return s.fail(.user_compile_error, .{ @@ -1199,7 +1195,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .@"if" => { - const data: Teg.If = s.frame.currentPayload(.@"if"); + const data: Hir.If = s.frame.currentPayload(.@"if"); const condition = try s.getCoercedRef(s.lazyNode(.operand), data.cond, .bool, .marked); switch (condition.decode()) { @@ -1270,7 +1266,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .struct_init => { - const node: Teg.StructInit = s.frame.currentPayload(.struct_init); + const node: Hir.StructInit = s.frame.currentPayload(.struct_init); // Ensure we have a valid struct to operate on const ty = try s.getType(s.lazyNode(.operand), node.base_type); @@ -1295,9 +1291,9 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) // The ordering of `storage` is defined by the struct's type, which // may be different than the instantiation. The fields are visited in // order of the instantiation. - for (node.keys(&s.teg), node.inits(&s.teg), 0..) |init_key, init_value, i| { + for (node.keys(&s.hir), node.inits(&s.hir), 0..) |init_key, init_value, i| { const found_index = index: for (struct_type.field_keys, 0..) |decl_key, j| { - if (decl_key.eqlSlice(init_key.slice(s.teg.string_bytes), s.ip)) + if (decl_key.eqlSlice(init_key.slice(s.hir.string_bytes), s.ip)) break :index j; } else { has_errors = true; @@ -1374,18 +1370,18 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .array_type => { - const un: Teg.RefNode = s.frame.currentData(.array_type); + const un: Hir.RefNode = s.frame.currentData(.array_type); const operand = try s.getType(s.lazyNode(.operand), un.operand); return s.makeValueAir(.{ .array_type = .{ .item_type = operand } }); }, .tuple_type => { - const data: Teg.TupleType = s.frame.currentPayload(.tuple_type); + const data: Hir.TupleType = s.frame.currentPayload(.tuple_type); const scratch = try s.scratch.reserve(s.arena(), Type, data.items.len); defer scratch.deinit(); - for (data.items.slice(&s.teg), scratch.slice(), 0..) |src, *dst, i| { + for (data.items.slice(&s.hir), scratch.slice(), 0..) |src, *dst, i| { dst.* = try s.getType(s.lazyNode(.argument(@intCast(i))), src); } @@ -1393,7 +1389,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .tuple_init => { - const data: Teg.TupleInit = s.frame.currentPayload(.tuple_init); + const data: Hir.TupleInit = s.frame.currentPayload(.tuple_init); _ = data.type_hint; // TODO: use type hint @@ -1401,7 +1397,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) defer scratch.deinit(); var is_const = true; - for (data.items.slice(&s.teg), scratch.slice()) |src, *dst| { + for (data.items.slice(&s.hir), scratch.slice()) |src, *dst| { const result = s.getRef(src, .marked); dst.* = result; if (result.kind == .index) is_const = false; @@ -1447,7 +1443,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .result_type_argument => { - const result: Teg.ResultTypeArgument = s.frame.currentData(.result_type_argument); + const result: Hir.ResultTypeArgument = s.frame.currentData(.result_type_argument); const operand = s.getRef(result.call_base, .no_mark); const ty = s.typeOfRef(operand); @@ -1462,7 +1458,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .result_type_array_value => { - const result: Teg.ResultTypeArrayValue = s.frame.currentData(.result_type_array_value); + const result: Hir.ResultTypeArrayValue = s.frame.currentData(.result_type_array_value); const operand = try s.getValue(s.lazyNode(.main_node), result.type); const ty = operand.toType(s.ip) orelse @@ -1475,7 +1471,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .result_type_tuple_field => { - const result: Teg.ResultTypeTupleField = s.frame.currentData(.result_type_tuple_field); + const result: Hir.ResultTypeTupleField = s.frame.currentData(.result_type_tuple_field); const operand = try s.getValue(s.lazyNode(.main_node), result.type); const ty = operand.toType(s.ip) orelse @@ -1487,7 +1483,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) }, .result_type_struct_field => { - const result: Teg.ResultTypeStructField = s.frame.currentData(.result_type_struct_field); + const result: Hir.ResultTypeStructField = s.frame.currentData(.result_type_struct_field); const operand = try s.getValue(s.lazyNode(.main_node), result.type); const ty = operand.toType(s.ip) orelse @@ -1496,7 +1492,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) const struct_type = ty.toStructType(s.ip) orelse return Value.opaque_type.toAir(); - const to_match = result.field.slice(s.teg.string_bytes); + const to_match = result.field.slice(s.hir.string_bytes); for (struct_type.field_keys, struct_type.field_types) |k, v| { if (k.eqlSlice(to_match, s.ip)) { return v.value().toAir(); @@ -1512,7 +1508,7 @@ fn stepInner(s: *Sema, comptime tag: Teg.Tag) Error!InstructionKind.fromTag(tag) fn emitRuntimeBlock( s: *Sema, - from: Teg.Inst.Index, + from: Hir.Inst.Index, break_operand: Air.Inst.Ref, mark: core.U32Stack.Mark, ) !void { @@ -1553,7 +1549,7 @@ const BinaryOp = enum { eq, }; -fn binTypeResolution(s: *Sema, src: Teg.Inst.Index, op: BinaryOp, lhs: Type, rhs: Type) !Type { +fn binTypeResolution(s: *Sema, src: Hir.Inst.Index, op: BinaryOp, lhs: Type, rhs: Type) !Type { if (lhs == .@"opaque") { return if (rhs == .numeric_literal) .float else rhs; } @@ -2084,7 +2080,7 @@ fn fieldAccessStruct( lhs: Air.Inst.Ref, lhs_type: Type, struct_type: InternPool.Key.StructType, - field: Teg.Inst.Ref, + field: Hir.Inst.Ref, ) !Air.Inst.Ref { const rhs = try s.getCoercedValue(s.lazyNode(.rhs), field, .string); const string = rhs.asString(s.ip); @@ -2125,7 +2121,7 @@ fn fieldAccessStruct( } } -fn fieldAccessArray(s: *Sema, lhs: Air.Inst.Ref, lhs_type: Type, rhs_teg: Teg.Inst.Ref) !Air.Inst.Ref { +fn fieldAccessArray(s: *Sema, lhs: Air.Inst.Ref, lhs_type: Type, rhs_teg: Hir.Inst.Ref) !Air.Inst.Ref { const rhs = s.getRef(rhs_teg, .marked); switch (s.typeOfRef(rhs)) { @@ -2176,7 +2172,7 @@ fn fieldAccessTuple( lhs: Air.Inst.Ref, lhs_type: Type, tuple_type: InternPool.Key.TupleType, - field: Teg.Inst.Ref, + field: Hir.Inst.Ref, ) !Air.Inst.Ref { const index_value = try s.getCoercedValue(s.lazyNode(.rhs), field, .int32); const index_signed = index_value.toInt32(s.ip) orelse unreachable; @@ -2387,7 +2383,7 @@ const File = Comp.File; const Decl = Comp.Decl; const Namespace = Comp.Namespace; -const Teg = core.Teg; +const Hir = core.Hir; const Air = core.Air; const Ast = core.Ast; diff --git a/src/core/StoredTrace.zig b/src/core/StoredTrace.zig index 5508bbf120fd150745b664cacc56077efe169526..0ba9c60c33b5338c851ae15ea6373c4886ba9507 100644 --- a/src/core/StoredTrace.zig +++ b/src/core/StoredTrace.zig @@ -1,6 +1,6 @@ -//! A variant of std.builtin.StackTrace that stores its data within itself -//! instead of being a pointer. This allows capturing the stack trace and -//! saving it for later printing. +//! A variant of `std.builtin.StackTrace` that stores its data within itself +//! instead of being a pointer. This allows storing captured stack traces +//! for later printing. data: [31]usize, index: usize, diff --git a/src/core/Transform.zig b/src/core/Transform.zig index ccead19a922ce962066ccf642886024f01fde15f..a2c2d8b1f9fe7b70ef9f07c5ffec1593ad00791c 100644 --- a/src/core/Transform.zig +++ b/src/core/Transform.zig @@ -1,5 +1,5 @@ -//! Transform pass converts an Ast into a high-level/untyped instruction format. -//! See Teg.zig for more details about the IR. Transforming handles: +//! Transform pass converts an Ast into a Hir. See Hir.zig for more details +//! about the resulting data structure. Transforming handles: //! //! - Flattening nested expressions into instruction sequences. //! - Resolving all local variables into reference or declaration names. @@ -38,7 +38,7 @@ pub const Error = error{ TransformFail, } || Allocator.Error; -pub fn transform(ast: Ast, gpa: Allocator, fail_report: *Report) Error!Teg { +pub fn transform(ast: Ast, gpa: Allocator, fail_report: *Report) Error!Hir { const trace = tracer.trace(@src()); defer trace.end(); @@ -117,16 +117,16 @@ const ResultType = union(enum) { /// The expression will be cast to the type of this ref type_of: Inst.Ref, /// The expression is an argument to a function. - argument: Teg.ResultTypeArgument, + argument: Hir.ResultTypeArgument, /// The expression is a field in a struct initialization - struct_field: Teg.ResultTypeStructField, + struct_field: Hir.ResultTypeStructField, /// The expression is a field in a tuple initialization - tuple_field: Teg.ResultTypeTupleField, + tuple_field: Hir.ResultTypeTupleField, /// The expression is a field in an array initialization array_value: Inst.Ref, // /// The expression is unknown field - // field: Teg.ResultTypeField, + // field: Hir.ResultTypeField, /// This will return an instruction pointing to the the type pub fn consume(result: *ResultType, t: *Transform) !?Inst.Ref { @@ -259,8 +259,8 @@ const Scope = struct { /// Sema requires that function expressions must know their up-front captures, /// so it can classify a function as comptime or runtime. const CaptureScope = struct { - start_index: Teg.Inst.Index, - symbol_uses: std.AutoArrayHashMapUnmanaged(Teg.Inst.Index, void) = .{}, + start_index: Hir.Inst.Index, + symbol_uses: std.AutoArrayHashMapUnmanaged(Hir.Inst.Index, void) = .{}, fn deinit(s: *CaptureScope, t: *Transform) void { s.symbol_uses.deinit(t.gpa); @@ -535,7 +535,7 @@ fn transformDecl(t: *Transform, outer_decl: BlockContext, node: NodeIndex) Alloc var hasher: std.Build.Cache.HashHelper = .{ .hasher = core.Cache.hasher_init }; hasher.addBytes(id); - const temp_teg: Teg = .{ + const temp_teg: Hir = .{ .insts = t.insts.slice(), .extra = t.extra.constant(), .string_bytes = t.string_bytes.items, @@ -547,7 +547,7 @@ fn transformDecl(t: *Transform, outer_decl: BlockContext, node: NodeIndex) Alloc temp_teg.writeToHasher(&hasher, tag_list, data_list, decl_index); - const decl_extra = try t.extra.append(t.gpa, Teg.Decl, .{ + const decl_extra = try t.extra.append(t.gpa, Hir.Decl, .{ .name = name, .hash = hasher.hasher.finalResult(), .instruction_count = inst_count, @@ -579,7 +579,7 @@ fn transformTestDecl(t: *Transform, outer_decl: BlockContext, node: NodeIndex) A var hasher: std.Build.Cache.HashHelper = .{ .hasher = core.Cache.hasher_init }; - const temp_teg: Teg = .{ + const temp_teg: Hir = .{ .insts = t.insts.slice(), .extra = t.extra.constant(), .string_bytes = t.string_bytes.items, @@ -591,7 +591,7 @@ fn transformTestDecl(t: *Transform, outer_decl: BlockContext, node: NodeIndex) A temp_teg.writeToHasher(&hasher, tag_list, data_list, decl_index); - const decl_extra = try t.extra.append(t.gpa, Teg.Decl, .{ + const decl_extra = try t.extra.append(t.gpa, Hir.Decl, .{ .name = .empty, .hash = hasher.hasher.finalResult(), .instruction_count = inst_count, @@ -738,7 +738,7 @@ fn transformToBlock( .none, .used => result, else => try t.addRef(.coercion, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Coercion, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Coercion, .{ .type = try result_type_ptr.consume(t) orelse unreachable, // `.none` already handled .operand = result, @@ -748,7 +748,7 @@ fn transformToBlock( _ = try t.addIndex(.@"break", .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Break, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Break, .{ .block = ret_block, .operand = coerced_result, }), @@ -864,7 +864,7 @@ pub const Builtin = enum { return try t.addRef(.js_new, .{ .src_node = decl.nodeOffset(args[0]), - .extra_index = try t.extra.append(t.gpa, Teg.JsNew, .{ + .extra_index = try t.extra.append(t.gpa, Hir.JsNew, .{ .base = base, .args = args_list, }), @@ -987,7 +987,7 @@ fn transformExpression( return try t.addRef(.coercion, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Coercion, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Coercion, .{ .type = type_ref.?, .operand = data_ref, }), @@ -1075,7 +1075,7 @@ fn transformExpression( // compound compute + assign operation. const is_assign = comptime tag.isAssignBin(); const teg_tag = @field( - Teg.Tag, + Hir.Tag, if (is_assign) @tagName(tag)[0 .. @tagName(tag).len - "_assign".len] else @@ -1096,7 +1096,7 @@ fn transformExpression( const compute_inst = try t.addRef(teg_tag, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Bin, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Bin, .{ .lhs = if (is_assign) try lhs.toRef(t) else lhs, .rhs = rhs, }), @@ -1116,7 +1116,7 @@ fn transformExpression( .assert, => |tag| { const ast_un = t.ast.nodeData(node).un; - const teg_tag = @field(Teg.Tag, @tagName(tag)); + const teg_tag = @field(Hir.Tag, @tagName(tag)); var operand_type: ResultType = switch (tag) { .negate => .none, // any numeric type allowed @@ -1178,7 +1178,7 @@ fn transformExpression( if (inner_expr) |out| { _ = try t.addRef(.@"break", .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Break, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Break, .{ .block = block, .operand = out, }), @@ -1276,7 +1276,7 @@ fn transformExpression( const call_inst = try t.addRef(.call, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Call, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Call, .{ .base = base, .args = args_list, }), @@ -1319,7 +1319,7 @@ fn transformExpression( return try t.addRef(.field, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Bin, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Bin, .{ .lhs = base, .rhs = rhs, }), @@ -1339,7 +1339,7 @@ fn transformExpression( return try t.addRef(.field, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Bin, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Bin, .{ .lhs = lhs, .rhs = rhs, }), @@ -1370,7 +1370,7 @@ fn transformExpression( return try t.addRef(.@"if", .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.If, .{ + .extra_index = try t.extra.append(t.gpa, Hir.If, .{ .cond = cond, .yes = yes, .no = no, @@ -1399,7 +1399,7 @@ fn transformExpression( _ = try t.addIndex(.@"break", .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Break, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Break, .{ .block = target.block_index, .operand = operand, }), @@ -1431,7 +1431,7 @@ fn transformExpression( .none, .used => operand, else => try t.addRef(.coercion, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Coercion, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Coercion, .{ .type = try break_result.consume(t) orelse unreachable, // `.none` already handled .operand = operand, @@ -1441,7 +1441,7 @@ fn transformExpression( _ = try t.addIndex(.@"break", .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Break, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Break, .{ .block = try block.getInst(t), .operand = coerced_operand, }), @@ -1474,7 +1474,7 @@ fn transformExpression( return try t.addRef(.struct_decl, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.StructDecl, .{ + .extra_index = try t.extra.append(t.gpa, Hir.StructDecl, .{ .payload_index = payload_index, .field_len = @intCast(struct_node.fields.len), }), @@ -1524,7 +1524,7 @@ fn transformExpression( return try t.addRef(.struct_init, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.StructInit, .{ + .extra_index = try t.extra.append(t.gpa, Hir.StructInit, .{ .base_type = base_type, .payload_index = payload_index, .field_len = @intCast(struct_node.fields.len), @@ -1549,7 +1549,7 @@ fn transformExpression( return try t.addRef(.array_init, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.ArrayInit, .{ + .extra_index = try t.extra.append(t.gpa, Hir.ArrayInit, .{ .type_hint = if (array_type) |ty| ty.toOptional() else .none, .list = items, }), @@ -1567,7 +1567,7 @@ fn transformExpression( return try t.addRef(.tuple_init, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.TupleInit, .{ + .extra_index = try t.extra.append(t.gpa, Hir.TupleInit, .{ .type_hint = .none, .items = items, }), @@ -1581,7 +1581,7 @@ fn transformExpression( return try t.addRef(.tuple_type, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.TupleType, .{ + .extra_index = try t.extra.append(t.gpa, Hir.TupleType, .{ .items = items, }), }); @@ -1645,7 +1645,7 @@ fn transformExpression( return try t.addRef(.func, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Func, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Func, .{ .params = param_list, .return_type = if (return_type) |ref| ref.toOptional() else .none, .body = body, @@ -1862,7 +1862,7 @@ const AssignmentTarget = union(enum) { }), .field => |field| try t.addRef(.field, .{ .src_node = field.src_node, - .extra_index = try t.extra.append(t.gpa, Teg.Bin, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Bin, .{ .lhs = field.base, .rhs = field.field, }), @@ -1874,21 +1874,21 @@ const AssignmentTarget = union(enum) { return switch (target) { .memory => |memory| try t.addRef(.store, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Store, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Store, .{ .memory = memory, .operand = rhs, }), }), .variable_declaration => |var_decl| try t.addRef(.store_decl, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.StoreVarDecl, .{ + .extra_index = try t.extra.append(t.gpa, Hir.StoreVarDecl, .{ .var_decl = var_decl.string, .operand = rhs, }), }), .field => |field| try t.addRef(.store_field, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.StoreField, .{ + .extra_index = try t.extra.append(t.gpa, Hir.StoreField, .{ .base = field.base, .field = field.field, .operand = rhs, @@ -1998,7 +1998,7 @@ fn transformBlockStatement( if (value_result != .used) { break :coerced try t.addRef(.coercion, .{ .src_node = ctx.nodeOffset(node), - .extra_index = try t.extra.append(t.gpa, Teg.Coercion, .{ + .extra_index = try t.extra.append(t.gpa, Hir.Coercion, .{ .type = ref, .operand = data_ref, }), @@ -2110,7 +2110,7 @@ fn transformBlockStatement( } } -fn addUntracked(t: *Transform, comptime tag: Teg.Tag, data: tag.Data()) !Inst.Index { +fn addUntracked(t: *Transform, comptime tag: Hir.Tag, data: tag.Data()) !Inst.Index { try t.insts.append(t.gpa, .{ .tag = tag, .data = .encode(tag, data), @@ -2118,13 +2118,13 @@ fn addUntracked(t: *Transform, comptime tag: Teg.Tag, data: tag.Data()) !Inst.In return @enumFromInt(t.insts.len - 1); } -fn addIndex(t: *Transform, comptime tag: Teg.Tag, data: tag.Data()) !Inst.Index { +fn addIndex(t: *Transform, comptime tag: Hir.Tag, data: tag.Data()) !Inst.Index { const index = try t.addUntracked(tag, data); try t.scratch.add(t.arena, Inst.Index, index); return index; } -fn addRef(t: *Transform, comptime tag: Teg.Tag, data: tag.Data()) !Inst.Ref { +fn addRef(t: *Transform, comptime tag: Hir.Tag, data: tag.Data()) !Inst.Ref { return (try t.addIndex(tag, data)).toRef(); } @@ -2333,18 +2333,18 @@ const Allocator = mem.Allocator; const assert = std.debug.assert; const core = @import("mod.zig"); -const Teg = core.Teg; -const Inst = Teg.Inst; -const NullTerminatedString = Teg.NullTerminatedString; -const SlicedString = Teg.SlicedString; -const RefList = Teg.RefList; -const IndexList = Teg.IndexList; -const OptionalRefList = Teg.OptionalRefList; -const EncodedData = Teg.EncodedData; -const ExtraIndex = Teg.ExtraIndex; +const Hir = core.Hir; +const Inst = Hir.Inst; +const NullTerminatedString = Hir.NullTerminatedString; +const SlicedString = Hir.SlicedString; +const RefList = Hir.RefList; +const IndexList = Hir.IndexList; +const OptionalRefList = Hir.OptionalRefList; +const EncodedData = Hir.EncodedData; +const ExtraIndex = Hir.ExtraIndex; const array = core.array; -const ExtraStore = array.ExtraStore(.teg, .@"var"); +const ExtraStore = array.ExtraStore(.hir, .@"var"); const Float = array.Float; const Tokenizer = core.Tokenizer; diff --git a/src/core/array.zig b/src/core/array.zig index 2afb7fd636bb3a6a212280b23aaaf5257722b0bb..b307f89555c421e4527f60e0d654f9df52474e7e 100644 --- a/src/core/array.zig +++ b/src/core/array.zig @@ -77,7 +77,7 @@ fn getAsU32(items: []const u32, comptime T: type, index: usize) T { pub const StoreKind = enum { intern_pool, - teg, + hir, air, js_tree, diff --git a/src/core/mod.zig b/src/core/mod.zig index 5329216e139b9bcb06515327656c5a6832e3401e..2967e13ca05552f5d8f70f80d8741cde89ae548f 100644 --- a/src/core/mod.zig +++ b/src/core/mod.zig @@ -17,7 +17,7 @@ pub const U32Stack = Stack(u32); pub const StoredTrace = @import("StoredTrace.zig"); pub const DebugStoredTrace = StoredTrace.DebugStoredTrace; pub const Queue = @import("queue.zig").Queue; -pub const Teg = @import("Teg.zig"); +pub const Hir = @import("Hir.zig"); pub const Tokenizer = @import("Tokenizer.zig"); pub const Transform = @import("Transform.zig"); pub const unicode_props = @import("unicode_props.zig"); diff --git a/src/main.zig b/src/main.zig index 531b4dc0d1a694c3b30fd0b916c6a2ccd97b3144..5a9f96bbfec1d47ce811ad1172159b375c3411e4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -299,7 +299,7 @@ fn cmdBuildOrRun(ctx: Context, comptime mode: enum { build, run }) !void { const main_file = try comp.getFile(file_path); var fail_report: Report = undefined; - const teg = main_file.getTeg(&comp, &fail_report) catch |err| switch (err) { + const hir = main_file.getHir(&comp, &fail_report) catch |err| switch (err) { error.TransformFail => { std.debug.print("Transform failed:\n", .{}); try fail_report.dump(.initComp(&comp, main_file), comp.out); @@ -321,7 +321,7 @@ fn cmdBuildOrRun(ctx: Context, comptime mode: enum { build, run }) !void { if (comp.options.dump_ir) { const stderr = std.io.getStdErr().writer(); - try teg.dumpToWriter(stderr, null); + try hir.dumpToWriter(stderr, null); } const entry_point = comp.enqueueEntryModule(main_file) catch |err| switch (err) { diff --git a/src/wasm/enum_codegen.zig b/src/wasm/enum_codegen.zig index a0e0b1928cf200e63075dd9225cd5e98946693e7..4a8a067c343c5bbeed928819b65cd29c744d2d85 100644 --- a/src/wasm/enum_codegen.zig +++ b/src/wasm/enum_codegen.zig @@ -6,8 +6,8 @@ pub fn main() !void { inline for (.{ .{ "TokenTag", Tokenizer.Token.Tag }, .{ "NodeTag", Ast.Node.Tag }, - .{ "TegInstTag", Teg.Tag }, - .{ "TegInstRef", Teg.Inst.Ref }, + .{ "HirInstTag", Hir.Tag }, + .{ "HirInstRef", Hir.Inst.Ref }, }) |decl| { const name, const enum_type = decl; @@ -24,4 +24,4 @@ const std = @import("std"); const core = @import("core"); const Tokenizer = core.Tokenizer; const Ast = core.Ast; -const Teg = core.Teg; +const Hir = core.Hir; diff --git a/test/compiler_tests.zig b/test/compiler_tests.zig index c38819efb797a6a9ed5d841aea241aaadc634da3..5231041adac86fca5ef0380ae640adc968374f6a 100644 --- a/test/compiler_tests.zig +++ b/test/compiler_tests.zig @@ -98,7 +98,7 @@ fn runTestCase( const main_file = try comp.getFile(file_path); var fail_report: core.Report = undefined; - const teg = main_file.getTeg(&comp, &fail_report) catch |err| switch (err) { + const hir = main_file.getHir(&comp, &fail_report) catch |err| switch (err) { error.TransformFail => { try out.print("Transform failed:\n", .{}); try fail_report.dump(.{ .comp = .{ .comp = &comp, .file = main_file } }, comp.out); @@ -112,7 +112,7 @@ fn runTestCase( }; if (case_options.dump_ir) { - try teg.dumpToWriter(out, .escape_codes); + try hir.dumpToWriter(out, .escape_codes); } const entry_point = try comp.enqueueEntryModule(main_file); @@ -121,8 +121,8 @@ fn runTestCase( if (comp.temp_flag_had_errors) return error.SemaErrors; - if (teg.report.warnings.len > 0) - return error.TegWarnings; + if (hir.report.warnings.len > 0) + return error.HirWarnings; var js_out: std.ArrayListUnmanaged(u8) = .{}; defer js_out.deinit(alloc); @@ -227,7 +227,7 @@ pub fn runTestCaseWrap( const stack = switch (err) { error.TransformFail, error.ParseFail, - error.TegWarnings, + error.HirWarnings, error.SemaErrors, error.AnalysisFail, => core.StoredTrace.empty, -- 2.54.0