diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-12-14 22:01:39 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-12-14 22:06:25 -0700 |
| commit | 52e19b4a9b6e6140bae3c20c6f1fef36dca20aa7 (patch) | |
| tree | 7f08300bbaedd657fc46ae816e0302470becfb1a | |
| parent | 304941026013e6310c9362849610c32d98d1332a (diff) | |
| download | zig-52e19b4a9b6e6140bae3c20c6f1fef36dca20aa7.tar.gz zig-52e19b4a9b6e6140bae3c20c6f1fef36dca20aa7.zip | |
analyze: BlockContext has concept of module scope
| -rw-r--r-- | doc/langref.md | 4 | ||||
| -rw-r--r-- | src/analyze.cpp | 51 | ||||
| -rw-r--r-- | src/analyze.hpp | 12 | ||||
| -rw-r--r-- | src/codegen.cpp | 7 | ||||
| -rw-r--r-- | src/parser.cpp | 9 |
5 files changed, 47 insertions, 36 deletions
diff --git a/doc/langref.md b/doc/langref.md index af2d9feed9..15e2f9f5eb 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -32,7 +32,9 @@ zig | C equivalent | Description ``` Root : many(TopLevelDecl) token(EOF) -TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl +TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration + +VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression)) StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructField) token(RBrace) diff --git a/src/analyze.cpp b/src/analyze.cpp index ed6379f389..288fadf42f 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -445,6 +445,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, break; } case NodeTypeUse: + case NodeTypeVariableDeclaration: // nothing to do here break; case NodeTypeDirective: @@ -453,7 +454,6 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, case NodeTypeType: case NodeTypeFnDecl: case NodeTypeReturnExpr: - case NodeTypeVariableDeclaration: case NodeTypeRoot: case NodeTypeBlock: case NodeTypeBinOpExpr: @@ -505,6 +505,7 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) { case NodeTypeFnDef: case NodeTypeRootExportDecl: case NodeTypeUse: + case NodeTypeVariableDeclaration: // nothing to do break; case NodeTypeDirective: @@ -513,7 +514,6 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) { case NodeTypeType: case NodeTypeFnDecl: case NodeTypeReturnExpr: - case NodeTypeVariableDeclaration: case NodeTypeRoot: case NodeTypeBlock: case NodeTypeBinOpExpr: @@ -537,26 +537,20 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) { } } -static TypeTableEntry * get_return_type(BlockContext *context) { - AstNode *fn_def_node = context->root->node; - assert(fn_def_node->type == NodeTypeFnDef); - AstNode *fn_proto_node = fn_def_node->data.fn_def.fn_proto; +static FnTableEntry *get_context_fn_entry(BlockContext *context) { + assert(context->fn_entry); + return context->fn_entry; +} + +static TypeTableEntry *get_return_type(BlockContext *context) { + FnTableEntry *fn_entry = get_context_fn_entry(context); + AstNode *fn_proto_node = fn_entry->proto_node; assert(fn_proto_node->type == NodeTypeFnProto); AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; assert(return_type_node->codegen_node); return return_type_node->codegen_node->data.type_node.entry; } -static FnTableEntry *get_context_fn_entry(BlockContext *context) { - AstNode *fn_def_node = context->root->node; - assert(fn_def_node->type == NodeTypeFnDef); - AstNode *fn_proto_node = fn_def_node->data.fn_def.fn_proto; - assert(fn_proto_node->type == NodeTypeFnProto); - assert(fn_proto_node->codegen_node); - assert(fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry); - return fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry; -} - static void check_type_compatibility(CodeGen *g, AstNode *node, TypeTableEntry *expected_type, TypeTableEntry *actual_type) { @@ -575,21 +569,22 @@ static void check_type_compatibility(CodeGen *g, AstNode *node, buf_ptr(&actual_type->name))); } -static BlockContext *new_block_context(AstNode *node, BlockContext *parent) { +BlockContext *new_block_context(AstNode *node, BlockContext *parent) { BlockContext *context = allocate<BlockContext>(1); context->node = node; context->parent = parent; - if (parent != nullptr) - context->root = parent->root; - else - context->root = context; context->variable_table.init(8); - AstNode *fn_def_node = context->root->node; - assert(fn_def_node->type == NodeTypeFnDef); - assert(fn_def_node->codegen_node); - FnDefNode *fn_def_info = &fn_def_node->codegen_node->data.fn_def_node; - fn_def_info->all_block_contexts.append(context); + if (parent) { + context->fn_entry = parent->fn_entry; + } else if (node && node->type == NodeTypeFnDef) { + AstNode *fn_proto_node = node->data.fn_def.fn_proto; + context->fn_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry; + } + + if (context->fn_entry) { + context->fn_entry->all_block_contexts.append(context); + } return context; } @@ -1509,13 +1504,15 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, case NodeTypeStructDecl: // nothing to do break; + case NodeTypeVariableDeclaration: + analyze_variable_declaration(g, import, import->block_context, nullptr, node); + break; case NodeTypeDirective: case NodeTypeParamDecl: case NodeTypeFnProto: case NodeTypeType: case NodeTypeFnDecl: case NodeTypeReturnExpr: - case NodeTypeVariableDeclaration: case NodeTypeRoot: case NodeTypeBlock: case NodeTypeBinOpExpr: diff --git a/src/analyze.hpp b/src/analyze.hpp index 40a6e5150d..7ad84ba915 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -90,6 +90,7 @@ struct ImportTableEntry { LLVMZigDIFile *di_file; Buf *source_code; ZigList<int> *line_offsets; + BlockContext *block_context; // reminder: hash tables must be initialized before use HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table; @@ -116,6 +117,8 @@ struct FnTableEntry { unsigned calling_convention; ImportTableEntry *import_entry; ZigList<FnAttrId> fn_attr_list; + // Required to be a pre-order traversal of the AST. (parents must come before children) + ZigList<BlockContext *> all_block_contexts; // reminder: hash tables must be initialized before use HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table; @@ -201,9 +204,9 @@ struct LocalVariableTableEntry { }; struct BlockContext { - AstNode *node; // either NodeTypeFnDef or NodeTypeBlock - BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef - BlockContext *parent; // nullptr when this is the root + AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or null for module scope + FnTableEntry *fn_entry; // null at the module scope + BlockContext *parent; // null when this is the root HashMap<Buf *, LocalVariableTableEntry *, buf_hash, buf_eql_buf> variable_table; ZigList<AstNode *> cast_expr_alloca_list; LLVMZigDIScope *di_scope; @@ -221,8 +224,6 @@ struct FnDefNode { TypeTableEntry *implicit_return_type; BlockContext *block_context; bool skip; - // Required to be a pre-order traversal of the AST. (parents must come before children) - ZigList<BlockContext *> all_block_contexts; }; struct ExprNode { @@ -295,5 +296,6 @@ void add_node_error(CodeGen *g, AstNode *node, Buf *msg); TypeTableEntry *new_type_table_entry(TypeTableEntryId id); TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const); LocalVariableTableEntry *find_local_variable(BlockContext *context, Buf *name); +BlockContext *new_block_context(AstNode *node, BlockContext *parent); #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index 47f64541a5..5593a689eb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1132,8 +1132,8 @@ static void do_code_gen(CodeGen *g) { // Set up debug info for blocks and variables and // allocate all local variables - for (int bc_i = 0; bc_i < codegen_fn_def->all_block_contexts.length; bc_i += 1) { - BlockContext *block_context = codegen_fn_def->all_block_contexts.at(bc_i); + for (int bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) { + BlockContext *block_context = fn_table_entry->all_block_contexts.at(bc_i); if (block_context->parent) { LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder, @@ -1530,6 +1530,9 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); g->import_table.put(full_path, import_entry); + import_entry->block_context = new_block_context(nullptr, nullptr); + import_entry->block_context->di_scope = LLVMZigFileToScope(import_entry->di_file); + assert(import_entry->root->type == NodeTypeRoot); for (int decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) { diff --git a/src/parser.cpp b/src/parser.cpp index bb75a0da6e..280f8da4d7 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2266,7 +2266,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { } /* -TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl +TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration */ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigList<AstNode *> *top_level_decls) { for (;;) { @@ -2310,6 +2310,13 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis } pc->directive_list = nullptr; + AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false); + if (var_decl_node) { + ast_eat_token(pc, token_index, TokenIdSemicolon); + top_level_decls->append(var_decl_node); + continue; + } + return; } zig_unreachable(); |
