From 9375ad0d3b5e97fa2889622862dbc4724b9e9243 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 16 Apr 2021 17:57:51 -0700 Subject: [PATCH] AstGen: implement global var decls And fix bug with using `ensureCapacity` when I wanted `ensureUnusedCapacity`. --- src/AstGen.zig | 28 +++++++++++++--------------- src/Sema.zig | 2 +- src/Zir.zig | 4 ++++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index a9422a0472..283f2a6fbd 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1281,6 +1281,7 @@ fn blockExprStmts( .bit_or, .block, .block_inline, + .block_inline_var, .loop, .bool_br_and, .bool_br_or, @@ -2020,7 +2021,7 @@ fn fnDecl( // Iterate over the parameters. We put the param names as the first N // items inside `extra` so that debug info later can refer to the parameter names // even while the respective source code is unloaded. - try astgen.extra.ensureCapacity(gpa, param_count); + try astgen.extra.ensureUnusedCapacity(gpa, param_count); { var params_scope = &fn_gz.base; @@ -2080,7 +2081,7 @@ fn fnDecl( }; const fn_name_token = fn_proto.name_token orelse { - @panic("TODO handle missing function names in the parser"); + return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{}); }; const fn_name_str_index = try gz.identAsString(fn_name_token); @@ -2173,16 +2174,13 @@ fn globalVarDecl( var_decl.ast.init_node, ); - if (!is_mutable) { - // const globals are just their instruction. mutable globals have - // a special ZIR form. - const block_inst = try gz.addBlock(.block_inline, node); - _ = try block_scope.addBreak(.break_inline, block_inst, init_inst); - try block_scope.setBlockBody(block_inst); - break :vi block_inst; - } - - @panic("TODO astgen global variable"); + const tag: Zir.Inst.Tag = if (is_mutable) .block_inline_var else .block_inline; + // const globals are just their instruction. mutable globals have + // a special ZIR form. + const block_inst = try gz.addBlock(tag, node); + _ = try block_scope.addBreak(.break_inline, block_inst, init_inst); + try block_scope.setBlockBody(block_inst); + break :vi block_inst; } else if (!is_extern) { return astgen.failNode(node, "variables must be initialized", .{}); } else if (var_decl.ast.type_node != 0) { @@ -2190,7 +2188,7 @@ fn globalVarDecl( const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); - @panic("TODO AstGen extern global variable"); + return astgen.failNode(node, "TODO AstGen extern global variable", .{}); } else { return astgen.failNode(node, "unable to infer variable type", .{}); }; @@ -2588,7 +2586,7 @@ fn containerDecl( ); } if (counts.values == 0 and counts.decls == 0 and arg_inst == .none) { - @panic("AstGen simple enum"); + return astgen.failNode(node, "TODO AstGen simple enums", .{}); } // In this case we must generate ZIR code for the tag values, similar to // how structs are handled above. @@ -2698,7 +2696,7 @@ fn errorSetDecl( const main_tokens = tree.nodes.items(.main_token); const token_tags = tree.tokens.items(.tag); - @panic("TODO AstGen errorSetDecl"); + return astgen.failNode(node, "TODO AstGen errorSetDecl", .{}); } fn orelseCatchExpr( diff --git a/src/Sema.zig b/src/Sema.zig index 142d39f192..0d9a3edd55 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -367,7 +367,7 @@ pub fn analyzeBody( i = 0; continue; }, - .block_inline => blk: { + .block_inline, .block_inline_var => blk: { // Directly analyze the block body without introducing a new block. const inst_data = datas[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); diff --git a/src/Zir.zig b/src/Zir.zig index 4a7322d4c6..423add0ab9 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -208,6 +208,8 @@ pub const Inst = struct { /// a noreturn instruction. /// Uses the `pl_node` union field. Payload is `Block`. block_inline, + /// Same as `block_inline` but it additionally marks a decl as being a variable. + block_inline_var, /// Boolean AND. See also `bit_and`. /// Uses the `pl_node` union field. Payload is `Bin`. bool_and, @@ -753,6 +755,7 @@ pub const Inst = struct { .bit_or, .block, .block_inline, + .block_inline_var, .loop, .bool_br_and, .bool_br_or, @@ -1830,6 +1833,7 @@ const Writer = struct { .block, .block_inline, + .block_inline_var, .loop, .validate_struct_init_ptr, => try self.writePlNodeBlock(stream, inst),