Commit bace1181b2

Vexu <git@vexu.eu>
2020-11-17 20:33:26
stage2: handle opaque containers
1 parent c1e19f4
Changed files (3)
src/astgen.zig
@@ -913,7 +913,19 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
             };
             break :blk Type.initPayload(&union_type.base);
         },
-        .Keyword_opaque => return mod.fail(scope, src, "TODO opaque containers", .{}),
+        .Keyword_opaque => blk: {
+            if (fields.items.len > 0) {
+                return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{});
+            }
+            const opaque_type = try arena.create(Type.Payload.Opaque);
+            opaque_type.* = .{
+                .scope = .{
+                    .file_scope = scope.getFileScope(),
+                    .ty = Type.initPayload(&opaque_type.base),
+                },
+            };
+            break :blk Type.initPayload(&opaque_type.base);
+        },
         else => unreachable,
     };
     const type_payload = try arena.create(Value.Payload.Ty);
src/Module.zig
@@ -1515,7 +1515,6 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void
     // an incremental update. This code handles both cases.
     const tree = try self.getAstTree(container_scope);
     const decls = tree.root_node.decls();
-    // const decls = container_scope.root_node.decls();
 
     try self.comp.work_queue.ensureUnusedCapacity(decls.len);
     try container_scope.decls.ensureCapacity(self.gpa, decls.len);
@@ -2302,6 +2301,7 @@ pub fn createContainerDecl(
 }
 
 fn getAnonTypeName(self: *Module, scope: *Scope, base_token: std.zig.ast.TokenIndex) ![]u8 {
+    // TODO add namespaces, generic function signatrues
     const tree = scope.tree();
     const base_name = switch (tree.token_ids[base_token]) {
         .Keyword_struct => "struct",
src/type.zig
@@ -49,7 +49,7 @@ pub const Type = extern union {
             .f128,
             => return .Float,
 
-            .c_void => return .Opaque,
+            .c_void, .@"opaque" => return .Opaque,
             .bool => return .Bool,
             .void => return .Void,
             .type => return .Type,
@@ -449,6 +449,7 @@ pub const Type = extern union {
             .@"enum" => return self,
             .@"struct" => return self,
             .@"union" => return self,
+            .@"opaque" => return self,
         }
     }
 
@@ -680,10 +681,11 @@ pub const Type = extern union {
                     const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);
                     return out_stream.print("error{{{}}}", .{payload.name});
                 },
-                // TODO improve
+                // TODO use declaration name
                 .@"enum" => return out_stream.writeAll("enum {}"),
                 .@"struct" => return out_stream.writeAll("struct {}"),
                 .@"union" => return out_stream.writeAll("union {}"),
+                .@"opaque" => return out_stream.writeAll("opaque {}"),
             }
             unreachable;
         }
@@ -809,6 +811,7 @@ pub const Type = extern union {
             .@"undefined",
             .enum_literal,
             .empty_struct,
+            .@"opaque",
             => false,
         };
     }
@@ -937,6 +940,7 @@ pub const Type = extern union {
             .@"undefined",
             .enum_literal,
             .empty_struct,
+            .@"opaque",
             => unreachable,
         };
     }
@@ -960,6 +964,7 @@ pub const Type = extern union {
             .enum_literal => unreachable,
             .single_const_pointer_to_comptime_int => unreachable,
             .empty_struct => unreachable,
+            .@"opaque" => unreachable,
 
             .u8,
             .i8,
@@ -1143,6 +1148,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .single_const_pointer,
@@ -1221,6 +1227,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .const_slice,
@@ -1296,6 +1303,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .single_const_pointer,
@@ -1380,6 +1388,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .pointer => {
@@ -1459,6 +1468,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .pointer => {
@@ -1580,6 +1590,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
 
             .array => self.cast(Payload.Array).?.elem_type,
@@ -1711,6 +1722,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
 
             .array => self.cast(Payload.Array).?.len,
@@ -1780,6 +1792,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
 
             .single_const_pointer,
@@ -1866,6 +1879,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .int_signed,
@@ -1944,6 +1958,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .int_unsigned,
@@ -2012,6 +2027,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
 
             .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits },
@@ -2098,6 +2114,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
 
             .usize,
@@ -2213,6 +2230,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         };
     }
@@ -2294,6 +2312,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         }
     }
@@ -2374,6 +2393,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         }
     }
@@ -2454,6 +2474,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         };
     }
@@ -2531,6 +2552,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         };
     }
@@ -2608,6 +2630,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => unreachable,
         };
     }
@@ -2685,6 +2708,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => false,
         };
     }
@@ -2742,6 +2766,7 @@ pub const Type = extern union {
             .error_union,
             .error_set,
             .error_set_single,
+            .@"opaque",
             => return null,
 
             .@"enum" => @panic("TODO onePossibleValue enum"),
@@ -2860,6 +2885,7 @@ pub const Type = extern union {
             .@"enum",
             .@"struct",
             .@"union",
+            .@"opaque",
             => return false,
 
             .c_const_pointer,
@@ -2951,6 +2977,7 @@ pub const Type = extern union {
             .@"enum" => &self.cast(Type.Payload.Enum).?.scope,
             .@"struct" => &self.cast(Type.Payload.Struct).?.scope,
             .@"union" => &self.cast(Type.Payload.Union).?.scope,
+            .@"opaque" => &self.cast(Type.Payload.Union).?.scope,
         };
     }
 
@@ -3105,6 +3132,7 @@ pub const Type = extern union {
         @"enum",
         @"struct",
         @"union",
+        @"opaque",
 
         pub const last_no_payload_tag = Tag.const_slice_u8;
         pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
@@ -3221,6 +3249,12 @@ pub const Type = extern union {
             scope: *Module.Scope.Container,
         };
 
+        pub const Opaque = struct {
+            base: Payload = .{ .tag = .@"opaque" },
+
+            scope: Module.Scope.Container,
+        };
+
         pub const Enum = @import("type/Enum.zig");
         pub const Struct = @import("type/Struct.zig");
         pub const Union = @import("type/Union.zig");