| author | |
| committer | |
| log | 7d910b024bd47d005030f9f3351e4923b2e0edc0 |
| tree | 92dd9100c344b237aecda9f6cb0a14964880f161 |
| parent | 20ae15917c5cded10a01b85c2cba77041dacef1c |
| signature | Commit is signed but in an unrecognized format. |
4 files changed, 67 insertions(+), 10 deletions(-)
src/Module.zig+42-7| ... | @@ -75,6 +75,9 @@ global_error_set: std.StringHashMapUnmanaged(u16) = .{}, | ... | @@ -75,6 +75,9 @@ global_error_set: std.StringHashMapUnmanaged(u16) = .{}, |
| 75 | /// previous analysis. | 75 | /// previous analysis. |
| 76 | generation: u32 = 0, | 76 | generation: u32 = 0, |
| 77 | 77 | ||
| 78 | /// Keys are fully qualified paths | ||
| 79 | import_table: std.StringHashMapUnmanaged(*Scope.File) = .{}, | ||
| 80 | |||
| 78 | stage1_flags: packed struct { | 81 | stage1_flags: packed struct { |
| 79 | have_winmain: bool = false, | 82 | have_winmain: bool = false, |
| 80 | have_wwinmain: bool = false, | 83 | have_wwinmain: bool = false, |
| ... | @@ -208,7 +211,7 @@ pub const Decl = struct { | ... | @@ -208,7 +211,7 @@ pub const Decl = struct { |
| 208 | .container => { | 211 | .container => { |
| 209 | const container = @fieldParentPtr(Scope.Container, "base", self.scope); | 212 | const container = @fieldParentPtr(Scope.Container, "base", self.scope); |
| 210 | const tree = container.file_scope.contents.tree; | 213 | const tree = container.file_scope.contents.tree; |
| 211 | // TODO Container should have it's own decls() | 214 | // TODO Container should have its own decls() |
| 212 | const decl_node = tree.root_node.decls()[self.src_index]; | 215 | const decl_node = tree.root_node.decls()[self.src_index]; |
| 213 | return tree.token_locs[decl_node.firstToken()].start; | 216 | return tree.token_locs[decl_node.firstToken()].start; |
| 214 | }, | 217 | }, |
| ... | @@ -532,12 +535,12 @@ pub const Scope = struct { | ... | @@ -532,12 +535,12 @@ pub const Scope = struct { |
| 532 | 535 | ||
| 533 | /// Direct children of the file. | 536 | /// Direct children of the file. |
| 534 | decls: std.AutoArrayHashMapUnmanaged(*Decl, void), | 537 | decls: std.AutoArrayHashMapUnmanaged(*Decl, void), |
| 535 | 538 | ty: Type, | |
| 536 | // TODO implement container types and put this in a status union | ||
| 537 | // ty: Type | ||
| 538 | 539 | ||
| 539 | pub fn deinit(self: *Container, gpa: *Allocator) void { | 540 | pub fn deinit(self: *Container, gpa: *Allocator) void { |
| 540 | self.decls.deinit(gpa); | 541 | self.decls.deinit(gpa); |
| 542 | // TODO either Container of File should have an arena for sub_file_path and ty | ||
| 543 | gpa.destroy(self.ty.cast(Type.Payload.EmptyStruct).?); | ||
| 541 | self.* = undefined; | 544 | self.* = undefined; |
| 542 | } | 545 | } |
| 543 | 546 | ||
| ... | @@ -2381,9 +2384,41 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst, | ... | @@ -2381,9 +2384,41 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst, |
| 2381 | return self.fail(scope, src, "TODO implement analysis of slice", .{}); | 2384 | return self.fail(scope, src, "TODO implement analysis of slice", .{}); |
| 2382 | } | 2385 | } |
| 2383 | 2386 | ||
| 2384 | pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) InnerError!*Inst { | 2387 | pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File { |
| 2385 | // TODO actually try to import | 2388 | // TODO if (package_table.get(target_string)) |pkg| |
| 2386 | return self.constType(scope, src, Type.initTag(.empty_struct)); | 2389 | |
| 2390 | const file_path = try std.fs.path.join(scope.arena(), &[_][]const u8{ self.root_pkg.root_src_dir_path, target_string }); | ||
| 2391 | |||
| 2392 | if (self.import_table.get(file_path)) |some| { | ||
| 2393 | return some; | ||
| 2394 | } | ||
| 2395 | |||
| 2396 | // TODO check for imports outside of pkg path | ||
| 2397 | if (false) return error.ImportOutsidePkgPath; | ||
| 2398 | |||
| 2399 | // TODO Scope.Container arena for ty and sub_file_path | ||
| 2400 | const struct_payload = try self.gpa.create(Type.Payload.EmptyStruct); | ||
| 2401 | const file_scope = try self.gpa.create(Scope.File); | ||
| 2402 | struct_payload.* = .{ .scope = &file_scope.root_container }; | ||
| 2403 | file_scope.* = .{ | ||
| 2404 | .sub_file_path = try self.gpa.dupe(u8, file_path), | ||
| 2405 | .source = .{ .unloaded = {} }, | ||
| 2406 | .contents = .{ .not_available = {} }, | ||
| 2407 | .status = .never_loaded, | ||
| 2408 | .root_container = .{ | ||
| 2409 | .file_scope = file_scope, | ||
| 2410 | .decls = .{}, | ||
| 2411 | .ty = Type.initPayload(&struct_payload.base), | ||
| 2412 | }, | ||
| 2413 | }; | ||
| 2414 | self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) { | ||
| 2415 | error.AnalysisFail => { | ||
| 2416 | assert(self.totalErrorCount() != 0); | ||
| 2417 | }, | ||
| 2418 | else => |e| return e, | ||
| 2419 | }; | ||
| 2420 | try self.import_table.put(self.gpa, file_scope.sub_file_path, file_scope); | ||
| 2421 | return file_scope; | ||
| 2387 | } | 2422 | } |
| 2388 | 2423 | ||
| 2389 | /// Asserts that lhs and rhs types are both numeric. | 2424 | /// Asserts that lhs and rhs types are both numeric. |
src/type.zig+11-2| ... | @@ -354,7 +354,6 @@ pub const Type = extern union { | ... | @@ -354,7 +354,6 @@ pub const Type = extern union { |
| 354 | .enum_literal, | 354 | .enum_literal, |
| 355 | .anyerror_void_error_union, | 355 | .anyerror_void_error_union, |
| 356 | .@"anyframe", | 356 | .@"anyframe", |
| 357 | .empty_struct, | ||
| 358 | => unreachable, | 357 | => unreachable, |
| 359 | 358 | ||
| 360 | .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), | 359 | .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), |
| ... | @@ -442,6 +441,7 @@ pub const Type = extern union { | ... | @@ -442,6 +441,7 @@ pub const Type = extern union { |
| 442 | }, | 441 | }, |
| 443 | .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), | 442 | .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), |
| 444 | .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), | 443 | .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), |
| 444 | .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), | ||
| 445 | } | 445 | } |
| 446 | } | 446 | } |
| 447 | 447 | ||
| ... | @@ -508,6 +508,7 @@ pub const Type = extern union { | ... | @@ -508,6 +508,7 @@ pub const Type = extern union { |
| 508 | .@"null" => return out_stream.writeAll("@Type(.Null)"), | 508 | .@"null" => return out_stream.writeAll("@Type(.Null)"), |
| 509 | .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"), | 509 | .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"), |
| 510 | 510 | ||
| 511 | // TODO this should print the structs name | ||
| 511 | .empty_struct => return out_stream.writeAll("struct {}"), | 512 | .empty_struct => return out_stream.writeAll("struct {}"), |
| 512 | .@"anyframe" => return out_stream.writeAll("anyframe"), | 513 | .@"anyframe" => return out_stream.writeAll("anyframe"), |
| 513 | .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"), | 514 | .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"), |
| ... | @@ -2837,7 +2838,6 @@ pub const Type = extern union { | ... | @@ -2837,7 +2838,6 @@ pub const Type = extern union { |
| 2837 | single_const_pointer_to_comptime_int, | 2838 | single_const_pointer_to_comptime_int, |
| 2838 | anyerror_void_error_union, | 2839 | anyerror_void_error_union, |
| 2839 | @"anyframe", | 2840 | @"anyframe", |
| 2840 | empty_struct, | ||
| 2841 | const_slice_u8, // See last_no_payload_tag below. | 2841 | const_slice_u8, // See last_no_payload_tag below. |
| 2842 | // After this, the tag requires a payload. | 2842 | // After this, the tag requires a payload. |
| 2843 | 2843 | ||
| ... | @@ -2864,6 +2864,7 @@ pub const Type = extern union { | ... | @@ -2864,6 +2864,7 @@ pub const Type = extern union { |
| 2864 | anyframe_T, | 2864 | anyframe_T, |
| 2865 | error_set, | 2865 | error_set, |
| 2866 | error_set_single, | 2866 | error_set_single, |
| 2867 | empty_struct, | ||
| 2867 | 2868 | ||
| 2868 | pub const last_no_payload_tag = Tag.const_slice_u8; | 2869 | pub const last_no_payload_tag = Tag.const_slice_u8; |
| 2869 | pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; | 2870 | pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; |
| ... | @@ -2971,6 +2972,14 @@ pub const Type = extern union { | ... | @@ -2971,6 +2972,14 @@ pub const Type = extern union { |
| 2971 | /// memory is owned by `Module` | 2972 | /// memory is owned by `Module` |
| 2972 | name: []const u8, | 2973 | name: []const u8, |
| 2973 | }; | 2974 | }; |
| 2975 | |||
| 2976 | /// Mostly used for namespace like structs with zero fields. | ||
| 2977 | /// Most commonly used for files. | ||
| 2978 | pub const EmptyStruct = struct { | ||
| 2979 | base: Payload = .{ .tag = .empty_struct }, | ||
| 2980 | |||
| 2981 | scope: *Module.Scope.Container, | ||
| 2982 | }; | ||
| 2974 | }; | 2983 | }; |
| 2975 | }; | 2984 | }; |
| 2976 | 2985 |
src/value.zig+1| ... | @@ -314,6 +314,7 @@ pub const Value = extern union { | ... | @@ -314,6 +314,7 @@ pub const Value = extern union { |
| 314 | .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"), | 314 | .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"), |
| 315 | .anyframe_type => return out_stream.writeAll("anyframe"), | 315 | .anyframe_type => return out_stream.writeAll("anyframe"), |
| 316 | 316 | ||
| 317 | // TODO this should print `NAME{}` | ||
| 317 | .empty_struct_value => return out_stream.writeAll("struct {}{}"), | 318 | .empty_struct_value => return out_stream.writeAll("struct {}{}"), |
| 318 | .null_value => return out_stream.writeAll("null"), | 319 | .null_value => return out_stream.writeAll("null"), |
| 319 | .undef => return out_stream.writeAll("undefined"), | 320 | .undef => return out_stream.writeAll("undefined"), |
src/zir_sema.zig+13-1| ... | @@ -1194,7 +1194,19 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn | ... | @@ -1194,7 +1194,19 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn |
| 1194 | fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { | 1194 | fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 1195 | const operand = try resolveConstString(mod, scope, inst.positionals.operand); | 1195 | const operand = try resolveConstString(mod, scope, inst.positionals.operand); |
| 1196 | 1196 | ||
| 1197 | return mod.analyzeImport(scope, inst.base.src, operand); | 1197 | const file_scope = mod.analyzeImport(scope, inst.base.src, operand) catch |err| switch (err) { |
| 1198 | // error.ImportOutsidePkgPath => { | ||
| 1199 | // return mod.fail(scope, inst.base.src, "import of file outside package path: '{}'", .{operand}); | ||
| 1200 | // }, | ||
| 1201 | error.FileNotFound => { | ||
| 1202 | return mod.fail(scope, inst.base.src, "unable to find '{}'", .{operand}); | ||
| 1203 | }, | ||
| 1204 | else => { | ||
| 1205 | // TODO user friendly error to string | ||
| 1206 | return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{operand, @errorName(err)}); | ||
| 1207 | } | ||
| 1208 | }; | ||
| 1209 | return mod.constType(scope, inst.base.src, file_scope.root_container.ty); | ||
| 1198 | } | 1210 | } |
| 1199 | 1211 | ||
| 1200 | fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { | 1212 | fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |