mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
stage2: very basic imports
This commit is contained in:
parent
20ae15917c
commit
7d910b024b
@ -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.
|
||||
|
||||
13
src/type.zig
13
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,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -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"),
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user