diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 49 | ||||
| -rw-r--r-- | src/type.zig | 13 | ||||
| -rw-r--r-- | src/value.zig | 1 | ||||
| -rw-r--r-- | src/zir_sema.zig | 14 |
4 files changed, 67 insertions, 10 deletions
diff --git a/src/Module.zig b/src/Module.zig index 9d6510fe7f..69097f4aba 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -75,6 +75,9 @@ global_error_set: std.StringHashMapUnmanaged(u16) = .{}, /// previous analysis. generation: u32 = 0, +/// Keys are fully qualified paths +import_table: std.StringHashMapUnmanaged(*Scope.File) = .{}, + stage1_flags: packed struct { have_winmain: bool = false, have_wwinmain: bool = false, @@ -208,7 +211,7 @@ pub const Decl = struct { .container => { const container = @fieldParentPtr(Scope.Container, "base", self.scope); const tree = container.file_scope.contents.tree; - // TODO Container should have it's own decls() + // TODO Container should have its own decls() const decl_node = tree.root_node.decls()[self.src_index]; return tree.token_locs[decl_node.firstToken()].start; }, @@ -532,12 +535,12 @@ pub const Scope = struct { /// Direct children of the file. decls: std.AutoArrayHashMapUnmanaged(*Decl, void), - - // TODO implement container types and put this in a status union - // ty: Type + ty: Type, pub fn deinit(self: *Container, gpa: *Allocator) void { self.decls.deinit(gpa); + // TODO either Container of File should have an arena for sub_file_path and ty + gpa.destroy(self.ty.cast(Type.Payload.EmptyStruct).?); self.* = undefined; } @@ -2381,9 +2384,41 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst, return self.fail(scope, src, "TODO implement analysis of slice", .{}); } -pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) InnerError!*Inst { - // TODO actually try to import - return self.constType(scope, src, Type.initTag(.empty_struct)); +pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File { + // TODO if (package_table.get(target_string)) |pkg| + + const file_path = try std.fs.path.join(scope.arena(), &[_][]const u8{ self.root_pkg.root_src_dir_path, target_string }); + + if (self.import_table.get(file_path)) |some| { + return some; + } + + // TODO check for imports outside of pkg path + if (false) return error.ImportOutsidePkgPath; + + // TODO Scope.Container arena for ty and sub_file_path + const struct_payload = try self.gpa.create(Type.Payload.EmptyStruct); + const file_scope = try self.gpa.create(Scope.File); + struct_payload.* = .{ .scope = &file_scope.root_container }; + file_scope.* = .{ + .sub_file_path = try self.gpa.dupe(u8, file_path), + .source = .{ .unloaded = {} }, + .contents = .{ .not_available = {} }, + .status = .never_loaded, + .root_container = .{ + .file_scope = file_scope, + .decls = .{}, + .ty = Type.initPayload(&struct_payload.base), + }, + }; + self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) { + error.AnalysisFail => { + assert(self.totalErrorCount() != 0); + }, + else => |e| return e, + }; + try self.import_table.put(self.gpa, file_scope.sub_file_path, file_scope); + return file_scope; } /// Asserts that lhs and rhs types are both numeric. diff --git a/src/type.zig b/src/type.zig index 8f9096fb94..bcce9d6edd 100644 --- a/src/type.zig +++ b/src/type.zig @@ -354,7 +354,6 @@ pub const Type = extern union { .enum_literal, .anyerror_void_error_union, .@"anyframe", - .empty_struct, => unreachable, .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), @@ -442,6 +441,7 @@ pub const Type = extern union { }, .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), + .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), } } @@ -508,6 +508,7 @@ pub const Type = extern union { .@"null" => return out_stream.writeAll("@Type(.Null)"), .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"), + // TODO this should print the structs name .empty_struct => return out_stream.writeAll("struct {}"), .@"anyframe" => return out_stream.writeAll("anyframe"), .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"), @@ -2837,7 +2838,6 @@ pub const Type = extern union { single_const_pointer_to_comptime_int, anyerror_void_error_union, @"anyframe", - empty_struct, const_slice_u8, // See last_no_payload_tag below. // After this, the tag requires a payload. @@ -2864,6 +2864,7 @@ pub const Type = extern union { anyframe_T, error_set, error_set_single, + empty_struct, pub const last_no_payload_tag = Tag.const_slice_u8; pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; @@ -2971,6 +2972,14 @@ pub const Type = extern union { /// memory is owned by `Module` name: []const u8, }; + + /// Mostly used for namespace like structs with zero fields. + /// Most commonly used for files. + pub const EmptyStruct = struct { + base: Payload = .{ .tag = .empty_struct }, + + scope: *Module.Scope.Container, + }; }; }; diff --git a/src/value.zig b/src/value.zig index cdb99ce490..6e38b1bed4 100644 --- a/src/value.zig +++ b/src/value.zig @@ -314,6 +314,7 @@ pub const Value = extern union { .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"), .anyframe_type => return out_stream.writeAll("anyframe"), + // TODO this should print `NAME{}` .empty_struct_value => return out_stream.writeAll("struct {}{}"), .null_value => return out_stream.writeAll("null"), .undef => return out_stream.writeAll("undefined"), diff --git a/src/zir_sema.zig b/src/zir_sema.zig index 63db1a4551..4ba8d1e431 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -1194,7 +1194,19 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { const operand = try resolveConstString(mod, scope, inst.positionals.operand); - return mod.analyzeImport(scope, inst.base.src, operand); + const file_scope = mod.analyzeImport(scope, inst.base.src, operand) catch |err| switch (err) { + // error.ImportOutsidePkgPath => { + // return mod.fail(scope, inst.base.src, "import of file outside package path: '{}'", .{operand}); + // }, + error.FileNotFound => { + return mod.fail(scope, inst.base.src, "unable to find '{}'", .{operand}); + }, + else => { + // TODO user friendly error to string + return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{operand, @errorName(err)}); + } + }; + return mod.constType(scope, inst.base.src, file_scope.root_container.ty); } fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |
