Commit 20ae15917c

Vexu <git@vexu.eu>
2020-09-04 22:34:44
stage2: add import builtin stub
1 parent fe117d9
src/astgen.zig
@@ -1973,6 +1973,15 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa
     }
 }
 
+fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
+    try ensureBuiltinParamCount(mod, scope, call, 1);
+    const tree = scope.tree();
+    const src = tree.token_locs[call.builtin_token].start;
+    const params = call.params();
+    const target = try expr(mod, scope, .none, params[0]);
+    return addZIRUnOp(mod, scope, src, .import, target);
+}
+
 fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {
     const tree = scope.tree();
     const builtin_name = tree.tokenSlice(call.builtin_token);
@@ -1995,6 +2004,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
     } else if (mem.eql(u8, builtin_name, "@breakpoint")) {
         const src = tree.token_locs[call.builtin_token].start;
         return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint));
+    } else if (mem.eql(u8, builtin_name, "@import")) {
+        return rlWrap(mod, scope, rl, try import(mod, scope, call));
     } else {
         return mod.failTok(scope, call.builtin_token, "invalid builtin function: '{}'", .{builtin_name});
     }
src/Module.zig
@@ -2381,6 +2381,11 @@ 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));
+}
+
 /// Asserts that lhs and rhs types are both numeric.
 pub fn cmpNumeric(
     self: *Module,
src/type.zig
@@ -89,6 +89,8 @@ pub const Type = extern union {
             .anyerror_void_error_union, .error_union => return .ErrorUnion,
 
             .anyframe_T, .@"anyframe" => return .AnyFrame,
+
+            .empty_struct => return .Struct,
         }
     }
 
@@ -352,6 +354,7 @@ 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),
@@ -505,6 +508,7 @@ pub const Type = extern union {
                 .@"null" => return out_stream.writeAll("@Type(.Null)"),
                 .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"),
 
+                .empty_struct => return out_stream.writeAll("struct {}"),
                 .@"anyframe" => return out_stream.writeAll("anyframe"),
                 .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"),
                 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
@@ -788,6 +792,7 @@ pub const Type = extern union {
             .@"null",
             .@"undefined",
             .enum_literal,
+            .empty_struct,
             => false,
         };
     }
@@ -910,6 +915,7 @@ pub const Type = extern union {
             .@"null",
             .@"undefined",
             .enum_literal,
+            .empty_struct,
             => unreachable,
         };
     }
@@ -932,6 +938,7 @@ pub const Type = extern union {
             .@"undefined" => unreachable,
             .enum_literal => unreachable,
             .single_const_pointer_to_comptime_int => unreachable,
+            .empty_struct => unreachable,
 
             .u8,
             .i8,
@@ -1107,6 +1114,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .single_const_pointer,
@@ -1181,6 +1189,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .const_slice,
@@ -1252,6 +1261,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .single_const_pointer,
@@ -1332,6 +1342,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .pointer => {
@@ -1407,6 +1418,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .pointer => {
@@ -1524,6 +1536,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
 
             .array => self.cast(Payload.Array).?.elem_type,
@@ -1651,6 +1664,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
 
             .array => self.cast(Payload.Array).?.len,
@@ -1716,6 +1730,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
 
             .single_const_pointer,
@@ -1798,6 +1813,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .int_signed,
@@ -1872,6 +1888,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .int_unsigned,
@@ -1936,6 +1953,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
 
             .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
@@ -2018,6 +2036,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
 
             .usize,
@@ -2129,6 +2148,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         };
     }
@@ -2206,6 +2226,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         }
     }
@@ -2282,6 +2303,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         }
     }
@@ -2358,6 +2380,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         };
     }
@@ -2431,6 +2454,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         };
     }
@@ -2504,6 +2528,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => unreachable,
         };
     }
@@ -2577,6 +2602,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => false,
         };
     }
@@ -2636,6 +2662,7 @@ pub const Type = extern union {
             .error_set_single,
             => return null,
 
+            .empty_struct => return Value.initTag(.empty_struct_value),
             .void => return Value.initTag(.void_value),
             .noreturn => return Value.initTag(.unreachable_value),
             .@"null" => return Value.initTag(.null_value),
@@ -2743,6 +2770,7 @@ pub const Type = extern union {
             .anyerror_void_error_union,
             .error_set,
             .error_set_single,
+            .empty_struct,
             => return false,
 
             .c_const_pointer,
@@ -2809,6 +2837,7 @@ 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.
 
src/value.zig
@@ -68,6 +68,7 @@ pub const Value = extern union {
         one,
         void_value,
         unreachable_value,
+        empty_struct_value,
         empty_array,
         null_value,
         bool_true,
@@ -182,6 +183,7 @@ pub const Value = extern union {
             .null_value,
             .bool_true,
             .bool_false,
+            .empty_struct_value,
             => unreachable,
 
             .ty => {
@@ -312,6 +314,7 @@ pub const Value = extern union {
             .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"),
             .anyframe_type => return out_stream.writeAll("anyframe"),
 
+            .empty_struct_value => return out_stream.writeAll("struct {}{}"),
             .null_value => return out_stream.writeAll("null"),
             .undef => return out_stream.writeAll("undefined"),
             .zero => return out_stream.writeAll("0"),
@@ -475,6 +478,7 @@ pub const Value = extern union {
             .float_128,
             .enum_literal,
             .@"error",
+            .empty_struct_value,
             => unreachable,
         };
     }
@@ -543,6 +547,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .undef => unreachable,
@@ -626,6 +631,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .undef => unreachable,
@@ -709,6 +715,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .undef => unreachable,
@@ -820,6 +827,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .zero,
@@ -907,6 +915,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .zero,
@@ -1078,6 +1087,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .zero,
@@ -1152,6 +1162,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .zero,
@@ -1300,6 +1311,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .ref_val => self.cast(Payload.RefVal).?.val,
@@ -1383,6 +1395,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => unreachable,
 
             .empty_array => unreachable, // out of bounds array index
@@ -1483,6 +1496,7 @@ pub const Value = extern union {
             .enum_literal,
             .error_set,
             .@"error",
+            .empty_struct_value,
             => false,
 
             .undef => unreachable,
src/zir.zig
@@ -161,6 +161,8 @@ pub const Inst = struct {
         @"fn",
         /// Returns a function type.
         fntype,
+        /// @import(operand)
+        import,
         /// Integer literal.
         int,
         /// Convert an integer value to another integer type, asserting that the destination type
@@ -315,6 +317,7 @@ pub const Inst = struct {
                 .ensure_err_payload_void,
                 .anyframe_type,
                 .bitnot,
+                .import,
                 => UnOp,
 
                 .add,
@@ -489,6 +492,7 @@ pub const Inst = struct {
                 .error_set,
                 .slice,
                 .slice_start,
+                .import,
                 => false,
 
                 .@"break",
src/zir_sema.zig
@@ -134,6 +134,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
         .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),
         .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?),
         .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
+        .import => return analyzeInstImport(mod, scope, old_inst.castTag(.import).?),
     }
 }
 
@@ -1190,6 +1191,12 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn
     return mod.analyzeSlice(scope, inst.base.src, array_ptr, start, null, null);
 }
 
+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);
+}
+
 fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
     return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShl", .{});
 }