-
-
Notifications
You must be signed in to change notification settings - Fork 322
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rough implementations of IRs for all stages
- Loading branch information
Showing
33 changed files
with
3,668 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
const region = @import("base/region.zig"); | ||
const symbol = @import("base/symbol.zig"); | ||
const module = @import("base/module.zig"); | ||
const package = @import("base/package.zig"); | ||
const primitive = @import("base/primitive.zig"); | ||
const env = @import("base/env.zig"); | ||
|
||
pub const Region = region.Region; | ||
pub const Position = region.Position; | ||
pub const LineAndColumn = region.LineAndColumn; | ||
|
||
pub const Ident = symbol.Ident; | ||
pub const IdentAttributes = symbol.IdentAttributes; | ||
pub const IdentProblems = symbol.IdentProblems; | ||
pub const IdentId = symbol.IdentId; | ||
pub const IdentStore = symbol.IdentStore; | ||
pub const Symbol = symbol.Symbol; | ||
pub const SymbolStore = symbol.SymbolStore; | ||
|
||
pub const Module = module.Module; | ||
pub const ModuleId = module.ModuleId; | ||
pub const ModuleStore = module.ModuleStore; | ||
|
||
pub const Package = package.Package; | ||
pub const PackageId = package.PackageId; | ||
pub const PackageStore = package.PackageStore; | ||
|
||
pub const Primitive = primitive.Primitive; | ||
pub const Literal = primitive.Literal; | ||
|
||
pub const ModuleEnv = env.ModuleEnv; | ||
pub const GlobalEnv = env.GlobalEnv; | ||
|
||
pub const Recursive = enum { | ||
NotRecursive, | ||
Recursive, | ||
TailRecursive, | ||
}; | ||
|
||
// TODO: can this be smaller than u32? | ||
/// Source of crash, and its runtime representation to roc_panic. | ||
pub const CrashOrigin = enum(u32) { | ||
/// The crash is due to Roc, either via a builtin or type error. | ||
Roc = 0, | ||
/// The crash is user-defined. | ||
User = 1, | ||
}; | ||
|
||
pub const LowLevel = .{}; | ||
|
||
// TODO: move to relevant stages | ||
pub const TypeVar = struct { id: u32 }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
const std = @import("std"); | ||
const base = @import("../base.zig"); | ||
const cols = @import("../collections.zig"); | ||
const problem = @import("../problem.zig"); | ||
|
||
pub const ModuleEnv = struct { | ||
symbols: base.SymbolStore, | ||
modules: base.ModuleStore, | ||
strings: cols.LargeStringInterner, | ||
tag_names: cols.TagNameInterner, | ||
tag_ids_for_slicing: cols.SafeList(cols.TagNameId), | ||
field_names: cols.FieldNameInterner, | ||
field_ids_for_slicing: cols.SafeList(cols.FieldNameId), | ||
problems: cols.SafeList(problem.Problem), | ||
// TODO: where are these used, and how do we manage them? | ||
// pub tuple_elem_indices: Vec<usize>, | ||
// pub record_fields: Vec<RecordField<()>>, | ||
|
||
pub fn init(allocator: std.mem.Allocator) ModuleEnv { | ||
return ModuleEnv{ | ||
.symbols = base.SymbolStore.init(allocator), | ||
.modules = base.ModuleStore.init(allocator), | ||
.strings = cols.LargeStringInterner.init(allocator), | ||
.tag_names = cols.TagNameInterner.init(allocator), | ||
.tag_ids_for_slicing = cols.SafeList(cols.TagNameId).init(allocator), | ||
.field_names = cols.FieldNameInterner.init(allocator), | ||
.field_ids_for_slicing = cols.SafeList(cols.FieldNameId).init(allocator), | ||
.problems = cols.SafeList(problem.Problem).init(allocator), | ||
}; | ||
} | ||
|
||
pub fn deinit(self: *ModuleEnv) void { | ||
self.symbols.deinit(); | ||
self.modules.deinit(); | ||
self.strings.deinit(); | ||
self.tag_names.deinit(); | ||
self.tag_ids_for_slicing.deinit(); | ||
self.field_names.deinit(); | ||
self.field_ids_for_slicing.deinit(); | ||
self.problems.deinit(); | ||
} | ||
|
||
pub fn addTagNameSlice( | ||
self: *ModuleEnv, | ||
name_ids: []cols.TagNameId, | ||
) cols.SafeList(cols.TagNameId).Slice { | ||
return self.tag_ids_for_slicing.appendSlice(name_ids); | ||
} | ||
|
||
pub fn addFieldNameSlice( | ||
self: *ModuleEnv, | ||
name_ids: []cols.FieldNameId, | ||
) cols.SafeList(cols.FieldNameId).Slice { | ||
return self.field_ids_for_slicing.appendSlice(name_ids); | ||
} | ||
}; | ||
|
||
pub const GlobalEnv = struct { | ||
// TODO: do we need this if each module manages this? | ||
modules: base.ModuleStore, | ||
packages: base.PackageStore, | ||
|
||
pub fn init(allocator: std.mem.Allocator) GlobalEnv { | ||
return GlobalEnv{ | ||
.modules = base.ModuleStore.init(allocator), | ||
.packages = base.PackageStore.init(allocator), | ||
}; | ||
} | ||
|
||
pub fn deinit(self: *GlobalEnv) void { | ||
self.modules.deinit(); | ||
self.packages.deinit(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
const std = @import("std"); | ||
const cols = @import("../collections.zig"); | ||
|
||
pub const ModuleId = struct { id: u32 }; | ||
|
||
pub const Module = struct { | ||
name: []u8, | ||
package_shorthand: ?[]u8, | ||
is_builtin: bool, | ||
}; | ||
|
||
pub const ModuleStore = struct { | ||
modules: cols.SafeMultiList(Module), | ||
|
||
pub fn init(allocator: std.mem.Allocator) ModuleStore { | ||
const modules = cols.SafeMultiList(Module).init(allocator); | ||
modules.append(Module{ | ||
.id = 0, | ||
.name = &.{}, | ||
.base_name = &.{}, | ||
.package_shorthand = null, | ||
.is_builtin = false, | ||
}); | ||
|
||
// TODO: insert builtins automatically? | ||
|
||
return ModuleStore{ .modules = modules }; | ||
} | ||
|
||
pub fn deinit(self: *ModuleStore) void { | ||
self.modules.deinit(); | ||
} | ||
|
||
pub fn lookup(self: *ModuleStore, name: []const u8, package_shorthand: ?[]const u8) ?ModuleId { | ||
const items = self.modules.items; | ||
|
||
for (0..self.modules.len()) |index| { | ||
const other_name = items.items(.name_segments)[index]; | ||
if (name == other_name) { | ||
const other_package_shorthand = items.items(.package_shorthand)[index]; | ||
if (other_package_shorthand == package_shorthand) { | ||
return ModuleId{ .id = @as(u32, index) }; | ||
} | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
pub fn getOrInsert( | ||
self: *ModuleStore, | ||
name: []const u8, | ||
package_shorthand: ?[]const u8, | ||
) ModuleId { | ||
if (self.lookup(name, package_shorthand)) |id| { | ||
return id; | ||
} else { | ||
const new_id = self.modules.insert(Module{ | ||
.name = name, | ||
.package_shorthand = package_shorthand, | ||
.is_builtin = false, | ||
}); | ||
|
||
return ModuleId{ .id = new_id.id }; | ||
} | ||
} | ||
|
||
pub fn getName(self: *ModuleStore, id: ModuleId) []u8 { | ||
return self.modules.items.items(.name)[@as(usize, id.id)]; | ||
} | ||
|
||
pub fn getPackageShorthand(self: *ModuleStore, id: ModuleId) ?[]u8 { | ||
return self.modules.items.items(.package_shorthand)[@as(usize, id.id)]; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const std = @import("std"); | ||
|
||
pub const PackageId = struct { id: u32 }; | ||
|
||
pub const Package = struct { | ||
id: PackageId, | ||
/// The BLAKE3 hash of the tarball's contents. Also the .tar filename on disk. | ||
content_hash: []u8, | ||
/// On disk, this will be the subfolder inside the cache dir where the package lives | ||
cache_subdir: []u8, | ||
/// Other code will default this to main.roc, but this module isn't concerned with that default. | ||
root_module_filename: ?[]u8, | ||
}; | ||
|
||
pub const PackageStore = struct { | ||
allocator: std.mem.Allocator, | ||
packages: std.MultiArrayList(Package), | ||
|
||
pub fn init(allocator: std.mem.Allocator) PackageStore { | ||
return PackageStore{ | ||
.allocator = allocator, | ||
.packages = std.MultiArrayList(Package), | ||
}; | ||
} | ||
|
||
pub fn deinit(self: *PackageStore) void { | ||
self.packages.deinit(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const cols = @import("../collections.zig"); | ||
|
||
// TODO: figure out how to combine enums and union(enum)s at comptime | ||
// to avoid them being multilevel | ||
|
||
pub const Primitive = union(enum) { | ||
Int: Int, | ||
Float: Float, | ||
Bool, | ||
Str, | ||
Crash, | ||
|
||
pub const Int = enum { | ||
U8, | ||
I8, | ||
U16, | ||
I16, | ||
U32, | ||
I32, | ||
U64, | ||
I64, | ||
U128, | ||
I128, | ||
}; | ||
|
||
pub const Float = enum { | ||
F32, | ||
F64, | ||
Dec, | ||
}; | ||
|
||
pub const Num = union(enum) { | ||
Int: Int, | ||
Float: Float, | ||
}; | ||
}; | ||
|
||
pub const Literal = union(enum) { | ||
Int: Int, | ||
Float: Float, | ||
Bool: bool, | ||
Str: cols.LargeStringId, | ||
Crash: cols.LargeStringId, | ||
|
||
pub const Int = union(enum) { | ||
I8: i8, | ||
U8: u8, | ||
I16: i16, | ||
U16: u16, | ||
I32: i32, | ||
U32: u32, | ||
I64: i64, | ||
U64: u64, | ||
I128: i128, | ||
U128: u128, | ||
}; | ||
|
||
pub const Float = union(enum) { | ||
F32: f32, | ||
F64: f64, | ||
// We represent Dec as a large int divided by 10^18, which is the maximum | ||
// number of decimal places that allows lossless conversion of U64 to Dec | ||
Dec: u128, | ||
}; | ||
|
||
pub const Num = union(enum) { | ||
Int: Int, | ||
Float: Float, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
const std = @import("std"); | ||
|
||
pub const Region = struct { | ||
start: Position, | ||
end: Position, | ||
|
||
pub fn format(self: *const Region, comptime fmt: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { | ||
if (fmt.len != 0) { | ||
std.fmt.invalidFmtError(fmt, self); | ||
} | ||
|
||
if ((self.start == Position.zero()) and (self.end == Position.zero())) { | ||
// In tests, it's super common to set all Located values to 0. | ||
// Also in tests, we don't want to bother printing the locations | ||
// because it makes failed assertions much harder to read. | ||
return writer.print("…", .{}); | ||
} else { | ||
return writer.print("@{}-{}", .{ self.start.offset, self.end.offset }); | ||
} | ||
} | ||
}; | ||
|
||
pub const Position = struct { | ||
offset: u32, | ||
|
||
pub fn zero() Position { | ||
return Position{ .offset = 0 }; | ||
} | ||
}; | ||
|
||
pub const LineAndColumn = packed struct(u32) { | ||
line: u20, | ||
column: u12, | ||
}; |
Oops, something went wrong.