@@ -14,20 +14,7 @@ const TypeVar = types.Var;
14
14
const Problem = problem .Problem ;
15
15
const Self = @This ();
16
16
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 ,
31
18
ingested_files : IngestedFile.List ,
32
19
33
20
/// Initialize the IR for a module's canonicalization info.
@@ -40,40 +27,17 @@ ingested_files: IngestedFile.List,
40
27
///
41
28
/// Since the can IR holds indices into the `ModuleEnv`, we need
42
29
/// 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 {
44
31
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 ),
58
33
// .type_var_names = Ident.Store.init(gpa),
59
34
.ingested_files = .{},
60
35
};
61
36
}
62
37
63
38
/// 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 );
77
41
// self.type_var_names.deinit(self.env.gpa);
78
42
self .ingested_files .deinit (self .env .gpa );
79
43
}
@@ -93,6 +57,226 @@ fn appendIdentChild(node: *sexpr.Expr, gpa: std.mem.Allocator, env: *const base.
93
57
node .appendNodeChild (gpa , & ident_node );
94
58
}
95
59
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
+
96
280
/// Type variables that have been explicitly named, e.g. `a` in `items : List a`.
97
281
pub const RigidVariables = struct {
98
282
named : std .AutoHashMap (TypeVar , Ident .Idx ),
0 commit comments