| ... | ... | @@ -12,6 +12,7 @@ arena: std.mem.Allocator, |
| 12 | 12 | types: std.ArrayListUnmanaged(DocData.Type) = .{}, |
| 13 | 13 | decls: std.ArrayListUnmanaged(DocData.Decl) = .{}, |
| 14 | 14 | ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{}, |
| 15 | comptimeExprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{}, |
| 15 | 16 | |
| 16 | 17 | var arena_allocator: std.heap.ArenaAllocator = undefined; |
| 17 | 18 | pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc { |
| ... | ... | @@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 48 | 49 | |
| 49 | 50 | // append all the types in Zir.Inst.Ref |
| 50 | 51 | { |
| 51 | | |
| 52 | | // TODO: we don't want to add .none, but the index math has to check out |
| 53 | | var i: u32 = 0; |
| 52 | try self.types.append(self.arena, .{ |
| 53 | .ComptimeExpr = .{ .name = "ComptimeExpr" }, |
| 54 | }); |
| 55 | // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr |
| 56 | var i: u32 = 1; |
| 54 | 57 | while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) { |
| 55 | 58 | var tmpbuf = std.ArrayList(u8).init(self.arena); |
| 56 | 59 | try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer()); |
| ... | ... | @@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 128 | 131 | .types = self.types.items, |
| 129 | 132 | .decls = self.decls.items, |
| 130 | 133 | .astNodes = self.ast_nodes.items, |
| 134 | .comptimeExprs = self.comptimeExprs.items, |
| 131 | 135 | }; |
| 132 | 136 | |
| 133 | 137 | data.packages[0].main = main_type_index.type; |
| ... | ... | @@ -196,7 +200,7 @@ const Scope = struct { |
| 196 | 200 | }; |
| 197 | 201 | |
| 198 | 202 | const DocData = struct { |
| 199 | | typeKinds: []const []const u8 = std.meta.fieldNames(std.builtin.TypeId), |
| 203 | typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds), |
| 200 | 204 | rootPkg: u32 = 0, |
| 201 | 205 | params: struct { |
| 202 | 206 | zigId: []const u8 = "arst", |
| ... | ... | @@ -208,7 +212,6 @@ const DocData = struct { |
| 208 | 212 | }, |
| 209 | 213 | } = .{}, |
| 210 | 214 | packages: [1]Package = .{.{}}, |
| 211 | | fns: []struct {} = &.{}, |
| 212 | 215 | errors: []struct {} = &.{}, |
| 213 | 216 | calls: []struct {} = &.{}, |
| 214 | 217 | |
| ... | ... | @@ -217,11 +220,27 @@ const DocData = struct { |
| 217 | 220 | files: []const []const u8, |
| 218 | 221 | types: []Type, |
| 219 | 222 | decls: []Decl, |
| 223 | comptimeExprs: []ComptimeExpr, |
| 224 | |
| 225 | const DocTypeKinds = blk: { |
| 226 | var info = @typeInfo(std.builtin.TypeId); |
| 227 | info.Enum.fields = info.Enum.fields ++ [1]std.builtin.TypeInfo.EnumField{ |
| 228 | .{ |
| 229 | .name = "ComptimeExpr", |
| 230 | .value = info.Enum.fields.len, |
| 231 | }, |
| 232 | }; |
| 233 | break :blk @Type(info); |
| 234 | }; |
| 220 | 235 | |
| 236 | const ComptimeExpr = struct { |
| 237 | code: []const u8, |
| 238 | typeRef: TypeRef, |
| 239 | }; |
| 221 | 240 | const Package = struct { |
| 222 | 241 | name: []const u8 = "root", |
| 223 | | file: usize = 0, // index into files |
| 224 | | main: usize = 0, // index into decls |
| 242 | file: usize = 0, // index into `files` |
| 243 | main: usize = 0, // index into `decls` |
| 225 | 244 | table: struct { root: usize } = .{ |
| 226 | 245 | .root = 0, |
| 227 | 246 | }, |
| ... | ... | @@ -244,7 +263,7 @@ const DocData = struct { |
| 244 | 263 | fields: ?[]usize = null, // index into astNodes |
| 245 | 264 | }; |
| 246 | 265 | |
| 247 | | const Type = union(std.builtin.TypeId) { |
| 266 | const Type = union(DocTypeKinds) { |
| 248 | 267 | Type: struct { name: []const u8 }, |
| 249 | 268 | Void: struct { name: []const u8 }, |
| 250 | 269 | Bool: struct { name: []const u8 }, |
| ... | ... | @@ -260,6 +279,7 @@ const DocData = struct { |
| 260 | 279 | pubDecls: ?[]usize = null, // index into decls |
| 261 | 280 | fields: ?[]TypeRef = null, // (use src->fields to find names) |
| 262 | 281 | }, |
| 282 | ComptimeExpr: struct { name: []const u8 }, |
| 263 | 283 | ComptimeFloat: struct { name: []const u8 }, |
| 264 | 284 | ComptimeInt: struct { name: []const u8 }, |
| 265 | 285 | Undefined: struct { name: []const u8 }, |
| ... | ... | @@ -309,6 +329,7 @@ const DocData = struct { |
| 309 | 329 | .Array => |v| try printTypeBody(v, options, w), |
| 310 | 330 | .Bool => |v| try printTypeBody(v, options, w), |
| 311 | 331 | .Void => |v| try printTypeBody(v, options, w), |
| 332 | .ComptimeExpr => |v| try printTypeBody(v, options, w), |
| 312 | 333 | .ComptimeInt => |v| try printTypeBody(v, options, w), |
| 313 | 334 | .ComptimeFloat => |v| try printTypeBody(v, options, w), |
| 314 | 335 | .Null => |v| try printTypeBody(v, options, w), |
| ... | ... | @@ -355,6 +376,7 @@ const DocData = struct { |
| 355 | 376 | unspecified, |
| 356 | 377 | declRef: usize, // index in `decls` |
| 357 | 378 | type: usize, // index in `types` |
| 379 | comptimeExpr: usize, // index in `comptimeExprs` |
| 358 | 380 | |
| 359 | 381 | pub fn fromWalkResult(wr: WalkResult) TypeRef { |
| 360 | 382 | return switch (wr) { |
| ... | ... | @@ -376,7 +398,7 @@ const DocData = struct { |
| 376 | 398 | , .{}); |
| 377 | 399 | }, |
| 378 | 400 | |
| 379 | | .declRef, .type => |v| { |
| 401 | .declRef, .type, .comptimeExpr => |v| { |
| 380 | 402 | try w.print( |
| 381 | 403 | \\{{ "{s}":{} }} |
| 382 | 404 | , .{ @tagName(self), v }); |
| ... | ... | @@ -386,6 +408,7 @@ const DocData = struct { |
| 386 | 408 | }; |
| 387 | 409 | |
| 388 | 410 | const WalkResult = union(enum) { |
| 411 | comptimeExpr: usize, // index in `comptimeExprs` |
| 389 | 412 | void, |
| 390 | 413 | @"unreachable", |
| 391 | 414 | @"null": TypeRef, |
| ... | ... | @@ -421,7 +444,7 @@ const DocData = struct { |
| 421 | 444 | \\{{ "{s}":{{}} }} |
| 422 | 445 | , .{@tagName(self)}); |
| 423 | 446 | }, |
| 424 | | .type, .declRef => |v| { |
| 447 | .type, .declRef, .comptimeExpr => |v| { |
| 425 | 448 | try w.print( |
| 426 | 449 | \\{{ "{s}":{} }} |
| 427 | 450 | , .{ @tagName(self), v }); |
| ... | ... | @@ -493,6 +516,14 @@ fn walkInstruction( |
| 493 | 516 | var new_scope = Scope{ .parent = null }; |
| 494 | 517 | return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst); |
| 495 | 518 | }, |
| 519 | .block => { |
| 520 | const res = DocData.WalkResult{ .comptimeExpr = self.comptimeExprs.items.len }; |
| 521 | try self.comptimeExprs.append(self.arena, .{ |
| 522 | .code = "if(banana) 1 else 0", |
| 523 | .typeRef = .{ .type = 0 }, |
| 524 | }); |
| 525 | return res; |
| 526 | }, |
| 496 | 527 | .int => { |
| 497 | 528 | const int = data[inst_index].int; |
| 498 | 529 | return DocData.WalkResult{ |
| ... | ... | @@ -545,7 +576,9 @@ fn walkInstruction( |
| 545 | 576 | // and we don't want to toss away the |
| 546 | 577 | // decl_val information (eg by replacing it with |
| 547 | 578 | // a WalkResult.type). |
| 548 | | |
| 579 | .comptimeExpr => { |
| 580 | self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref; |
| 581 | }, |
| 549 | 582 | .int => operand.int.typeRef = dest_type_ref, |
| 550 | 583 | .@"struct" => operand.@"struct".typeRef = dest_type_ref, |
| 551 | 584 | .@"undefined" => operand.@"undefined" = dest_type_ref, |