Skip to content

Commit 94eaaac

Browse files
committed
BROKEN: CanIR re-design rough draft
1 parent f492e8b commit 94eaaac

File tree

1 file changed

+225
-41
lines changed

1 file changed

+225
-41
lines changed

src/check/canonicalize/IR.zig

Lines changed: 225 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,7 @@ const TypeVar = types.Var;
1414
const Problem = problem.Problem;
1515
const Self = @This();
1616

17-
env: *base.ModuleEnv,
18-
aliases: Alias.List,
19-
imports: ModuleImport.Store,
20-
defs: Def.List,
21-
exprs: Expr.List,
22-
exprs_at_regions: ExprAtRegion.List,
23-
typed_exprs_at_regions: TypedExprAtRegion.List,
24-
if_branches: IfBranch.List,
25-
when_branches: WhenBranch.List,
26-
patterns: Pattern.List,
27-
patterns_at_regions: PatternAtRegion.List,
28-
typed_patterns_at_regions: TypedPatternAtRegion.List,
29-
type_indices: collections.SafeList(TypeVar),
30-
// type_var_names: Ident.Store,
17+
store: NodeStore,
3118
ingested_files: IngestedFile.List,
3219

3320
/// Initialize the IR for a module's canonicalization info.
@@ -40,40 +27,17 @@ ingested_files: IngestedFile.List,
4027
///
4128
/// Since the can IR holds indices into the `ModuleEnv`, we need
4229
/// the `ModuleEnv` to also be owned by the can IR to cache it.
43-
pub fn init(env: *base.ModuleEnv) Self {
30+
pub fn init(gpa: std.mem.Allocator) Self {
4431
return Self{
45-
.env = env,
46-
.aliases = .{},
47-
.imports = ModuleImport.Store.init(&.{}, &env.idents, env.gpa),
48-
.defs = .{},
49-
.exprs = .{},
50-
.exprs_at_regions = .{},
51-
.typed_exprs_at_regions = .{},
52-
.if_branches = .{},
53-
.when_branches = .{},
54-
.patterns = .{},
55-
.patterns_at_regions = .{},
56-
.typed_patterns_at_regions = .{},
57-
.type_indices = .{},
32+
.store = NodeStore.init(gpa),
5833
// .type_var_names = Ident.Store.init(gpa),
5934
.ingested_files = .{},
6035
};
6136
}
6237

6338
/// Deinit the IR's memory.
64-
pub fn deinit(self: *Self) void {
65-
self.aliases.deinit(self.env.gpa);
66-
self.imports.deinit(self.env.gpa);
67-
self.defs.deinit(self.env.gpa);
68-
self.exprs.deinit(self.env.gpa);
69-
self.exprs_at_regions.deinit(self.env.gpa);
70-
self.typed_exprs_at_regions.deinit(self.env.gpa);
71-
self.if_branches.deinit(self.env.gpa);
72-
self.when_branches.deinit(self.env.gpa);
73-
self.patterns.deinit(self.env.gpa);
74-
self.patterns_at_regions.deinit(self.env.gpa);
75-
self.typed_patterns_at_regions.deinit(self.env.gpa);
76-
self.type_indices.deinit(self.env.gpa);
39+
pub fn deinit(self: *Self, gpa: std.mem.Allocator) void {
40+
self.store.deinit(gpa);
7741
// self.type_var_names.deinit(self.env.gpa);
7842
self.ingested_files.deinit(self.env.gpa);
7943
}
@@ -93,6 +57,226 @@ fn appendIdentChild(node: *sexpr.Expr, gpa: std.mem.Allocator, env: *const base.
9357
node.appendNodeChild(gpa, &ident_node);
9458
}
9559

60+
test {
61+
const testing = std.testing;
62+
try testing.expectEqual(24, @sizeOf(Node));
63+
}
64+
65+
/// A single meaningful node in the Abstract Syntax Tree.
66+
/// Should always be inserted and fetched from a Node Store.
67+
///
68+
/// The Tag represents what type of Node it is, and
69+
/// therefore how it's data and main_token fields should
70+
/// be interpreted.
71+
pub const Node = struct {
72+
data_1: u32,
73+
data_2: u32,
74+
data_3: u32,
75+
region: Region,
76+
tag: Tag,
77+
78+
pub const List = collections.SafeMultiList(Node);
79+
80+
/// Internal representation for where a node is stored
81+
/// in the tree.
82+
pub const Idx = List.Idx;
83+
84+
/// This is the tag associated with a raw Node in the list
85+
pub const Tag = enum {
86+
// Statements
87+
statement_expr,
88+
statement_decl,
89+
statement_var,
90+
statement_for,
91+
statement_expect,
92+
statement_return,
93+
statement_import,
94+
statement_type_decl,
95+
statement_type_anno,
96+
statement_crash,
97+
// Expressions
98+
expr_var,
99+
expr_tuple,
100+
expr_list,
101+
expr_record,
102+
expr_field_access,
103+
expr_static_dispatch,
104+
expr_apply,
105+
expr_string,
106+
expr_string_part,
107+
expr_int,
108+
expr_float,
109+
expr_tag,
110+
expr_lambda,
111+
expr_record_update,
112+
expr_bin_op,
113+
expr_unary,
114+
expr_suffix_single_question,
115+
expr_if_then_else,
116+
expr_match,
117+
expr_dbg,
118+
expr_block,
119+
expr_ellipsis,
120+
expr_record_builder,
121+
// Type Header
122+
type_decl_header,
123+
// Type Annotation
124+
type_anno_apply,
125+
type_anno_var,
126+
type_anno_ty,
127+
type_anno_underscore,
128+
type_anno_mod_ty,
129+
type_anno_union,
130+
type_anno_tuple,
131+
type_anno_record,
132+
type_anno_fn,
133+
type_anno_parens,
134+
};
135+
};
136+
137+
pub const NodeStore = struct {
138+
gpa: std.mem.Allocator,
139+
nodes: Node.List,
140+
extra_data: std.ArrayListUnmanaged(u32),
141+
scratch_statements: Scratch(Statement.Idx),
142+
scratch_exprs: Scratch(Expr.Idx),
143+
scratch_record_fields: Scratch(RecordField.Idx),
144+
scratch_when_branches: Scratch(WhenBranch.Idx),
145+
scratch_where_clauses: Scratch(WhereClause.Idx),
146+
scratch_patterns: Scratch(Pattern.Idx),
147+
scratch_pattern_record_fields: Scratch(PatternRecordField.Idx),
148+
scratch_type_annos: Scratch(TypeAnno.Idx),
149+
scratch_anno_record_fields: Scratch(AnnoRecordField.Idx),
150+
scratch_exposed_items: Scratch(ExposedItem.Idx),
151+
152+
pub fn initCapacity(gpa: std.mem.Allocator) NodeStore {
153+
return .{
154+
.gpa = gpa,
155+
.nodes = Node.List.initCapacity(gpa, capacity),
156+
.extra_data = std.ArrayListUnmanaged(u32).initCapacity(gpa, capacity / 2) catch |err| exitOnOom(err),
157+
.scratch_statements = Scratch(StatementIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
158+
.scratch_exprs = Scratch(ExprIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
159+
.scratch_patterns = Scratch(PatternIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
160+
.scratch_record_fields = Scratch(RecordFieldIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
161+
.scratch_pattern_record_fields = Scratch(PatternRecordFieldIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
162+
.scratch_when_branches = Scratch(WhenBranchIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
163+
.scratch_type_annos = Scratch(TypeAnnoIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
164+
.scratch_anno_record_fields = Scratch(AnnoRecordFieldIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
165+
.scratch_exposed_items = Scratch(ExposedItemIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
166+
.scratch_where_clauses = Scratch(WhereClauseIdx).initCapacity(gpa, scratch_90th_percentile_capacity) catch |err| exitOnOom(err),
167+
};
168+
}
169+
170+
pub fn deinit(store: *NodeStore) void {
171+
self.nodes.deinit(store.gpa);
172+
self.extra_data.deinit(store.gpa);
173+
self.scratch_statements.deinit(store.gpa);
174+
self.scratch_exprs.deinit(store.gpa);
175+
self.scratch_patterns.deinit(store.gpa);
176+
self.scratch_record_fields.deinit(store.gpa);
177+
self.scratch_pattern_record_fields.deinit(store.gpa);
178+
self.scratch_when_branches.deinit(store.gpa);
179+
self.scratch_type_annos.deinit(store.gpa);
180+
self.scratch_anno_record_fields.deinit(store.gpa);
181+
self.scratch_exposed_items.deinit(store.gpa);
182+
self.scratch_where_clauses.deinit(store.gpa);
183+
}
184+
185+
pub fn addStatement(store: *NodeStore, statement: Statement) Statement.Idx {}
186+
pub fn addExpr(store: *NodeStore, expr: Expr) Expr.Idx {}
187+
pub fn addRecordField(store: *NodeStore, recordField: RecordField) RecordField.Idx {}
188+
pub fn addWhenBranch(store: *NodeStore, whenBranch: WhenBranch) WhenBranch.Idx {}
189+
pub fn addWhereClause(store: *NodeStore, whereClause: WhereClause) WhereClause.Idx {}
190+
pub fn addPattern(store: *NodeStore, pattern: Pattern) Pattern.Idx {}
191+
pub fn addPatternRecordField(store: *NodeStore, patternRecordField: PatternRecordField) PatternRecordField.Idx {}
192+
pub fn addTypeAnno(store: *NodeStore, typeAnno: TypeAnno) TypeAnno.Idx {}
193+
pub fn addAnnoRecordField(store: *NodeStore, annoRecordField: AnnoRecordField) AnnoRecordFiled.Idx {}
194+
pub fn addExposedItem(store: *NodeStore, exposedItem: ExposedItem) ExposedItem.Idx {}
195+
196+
pub fn getStatement(store: *NodeStore, statement: Statement.Idx) Statement {}
197+
pub fn getExpr(store: *NodeStore, expr: Expr.Idx) Expr {}
198+
pub fn getRecordField(store: *NodeStore, recordField: RecordField.Idx) RecordField {}
199+
pub fn getWhenBranch(store: *NodeStore, whenBranch: WhenBranch.Idx) WhenBranch {}
200+
pub fn getWhereClause(store: *NodeStore, whereClause: WhereClause.Idx) WhereClause {}
201+
pub fn getPattern(store: *NodeStore, pattern: Pattern.Idx) Pattern {}
202+
pub fn getPatternRecordField(store: *NodeStore, patternRecordField: PatternRecordField.Idx) PatternRecordField {}
203+
pub fn getTypeAnno(store: *NodeStore, typeAnno: TypeAnno.Idx) TypeAnno {}
204+
pub fn getAnnoRecordField(store: *NodeStore, annoRecordField: AnnoRecordField.Idx) AnnoRecordFiled {}
205+
pub fn getExposedItem(store: *NodeStore, exposedItem: ExposedItem.Idx) ExposedItem {}
206+
207+
pub const DataSpan = struct {
208+
start: u32,
209+
len: u32,
210+
};
211+
212+
pub const ExprSpan = struct { span: DataSpan };
213+
pub const StatementSpan = struct { span: DataSpan };
214+
pub const PatternSpan = struct { span: DataSpan };
215+
pub const PatternRecordFieldSpan = struct { span: DataSpan };
216+
pub const RecordFieldSpan = struct { span: DataSpan };
217+
pub const WhenBranchSpan = struct { span: DataSpan };
218+
pub const TypeAnnoSpan = struct { span: DataSpan };
219+
pub const AnnoRecordFieldSpan = struct { span: DataSpan };
220+
pub const ExposedItemSpan = struct { span: DataSpan };
221+
pub const WhereClauseSpan = struct { span: DataSpan };
222+
223+
pub fn sliceFromSpan(store: *NodeStore, comptime T: type, span: anytype) []T {
224+
return @as([]T, @ptrCast(store.extra_data.items[span.span.start..(span.span.start + span.span.len)]));
225+
}
226+
227+
pub fn Scratch(comptime T: type) type {
228+
return struct {
229+
items: std.ArrayListUnmanaged(T),
230+
231+
fn init(gpa: std.mem.Allocator, capacity: usize) Self {
232+
return .{
233+
.items = std.ArrayListUnmanaged(T).initCapacity(gpa, std.math.ceilPowerOfTwoAssert(usize, 64)),
234+
};
235+
}
236+
237+
const Self = @This();
238+
239+
/// Returns the start position for a new Span of whereClauseIdxs in scratch
240+
pub fn top(self: *Self) u32 {
241+
return @as(u32, @intCast(store.scratch_where_clauses.items.len));
242+
}
243+
244+
/// Places a new WhereClauseIdx in the scratch. Will panic on OOM.
245+
pub fn append(self: *Self, idx: WhereClauseIdx) void {
246+
store.scratch_where_clauses.append(store.gpa, idx) catch |err| exitOnOom(err);
247+
}
248+
249+
/// Creates a new span starting at start. Moves the items from scratch
250+
/// to extra_data as appropriate.
251+
pub fn spanFromStart(self: *Self, start: u32, gpa: Allocator, data: *std.ArrayListUnmanaged(u32)) WhereClauseSpan {
252+
const end = self.items.len;
253+
defer self.items.shrinkRetainingCapacity(start);
254+
var i = @as(usize, @intCast(start));
255+
const data_start = @as(u32, @intCast(data.items.len));
256+
while (i < end) {
257+
data.append(gpa, self.items[i].id) catch |err| exitOnOom(err);
258+
i += 1;
259+
}
260+
return .{ .span = .{ .start = data_start, .len = @as(u32, @intCast(end)) - start } };
261+
}
262+
263+
/// Clears any WhereClauseIds added to scratch from start until the end.
264+
/// Should be used wherever the scratch items will not be used,
265+
/// as in when parsing fails.
266+
pub fn clearFrom(self: *Self, start: u32) void {
267+
store.scratch_where_clauses.shrinkRetainingCapacity(start);
268+
}
269+
};
270+
}
271+
};
272+
273+
pub const Statement = union(enum) {
274+
decl: Decl,
275+
276+
pub const Decl = struct {};
277+
pub const Idx = enum(u32) { _ };
278+
};
279+
96280
/// Type variables that have been explicitly named, e.g. `a` in `items : List a`.
97281
pub const RigidVariables = struct {
98282
named: std.AutoHashMap(TypeVar, Ident.Idx),

0 commit comments

Comments
 (0)