authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-09 17:41:51+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-30 16:59:08+03:00
log7d910b024bd47d005030f9f3351e4923b2e0edc0
tree92dd9100c344b237aecda9f6cb0a14964880f161
parent20ae15917c5cded10a01b85c2cba77041dacef1c
signature Commit is signed but in an unrecognized format.

stage2: very basic imports


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.
76generation: u32 = 0,76generation: u32 = 0,
7777
78/// Keys are fully qualified paths
79import_table: std.StringHashMapUnmanaged(*Scope.File) = .{},
80
78stage1_flags: packed struct {81stage1_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 {
532535
533 /// Direct children of the file.536 /// Direct children of the file.
534 decls: std.AutoArrayHashMapUnmanaged(*Decl, void),537 decls: std.AutoArrayHashMapUnmanaged(*Decl, void),
535538 ty: Type,
536 // TODO implement container types and put this in a status union
537 // ty: Type
538539
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 }
543546
...@@ -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}
23832386
2384pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) InnerError!*Inst {2387pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File {
2385 // TODO actually try to import2388 // 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}
23882423
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,
359358
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 }
447447
...@@ -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)"),
510510
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.
28432843
...@@ -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,
28672868
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};
29762985
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"),
316316
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
1194fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {1194fn 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);
11961196
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}
11991211
1200fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {1212fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {