authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-09 12:34:03-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-09 12:34:03-07:00
log745c325d0f498406f229e532753e5d5712e824d4
treeaf0bd93ca81361b65c54c9da83a0b7cecc8097bd
parent56908dcb9dd7bbfae7c22b6312752eb576a227c2

support variable declarations in structs

See #22

5 files changed, 24 insertions(+), 9 deletions(-)

doc/langref.md+1-1
...@@ -17,7 +17,7 @@ VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expres...@@ -17,7 +17,7 @@ VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expres
1717
18ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"18ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"
1919
20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl)
2121
22StructField = "Symbol" option(":" Expression) ",")22StructField = "Symbol" option(":" Expression) ",")
2323
src/all_types.hpp+1-1
...@@ -604,7 +604,7 @@ struct AstNodeStructDecl {...@@ -604,7 +604,7 @@ struct AstNodeStructDecl {
604 ZigList<AstNode *> generic_params;604 ZigList<AstNode *> generic_params;
605 bool generic_params_is_var_args; // always an error but it can happen from parsing605 bool generic_params_is_var_args; // always an error but it can happen from parsing
606 ZigList<AstNode *> fields;606 ZigList<AstNode *> fields;
607 ZigList<AstNode *> fns;607 ZigList<AstNode *> decls;
608608
609 // populated by semantic analyzer609 // populated by semantic analyzer
610 BlockContext *block_context;610 BlockContext *block_context;
src/analyze.cpp+3-3
...@@ -1580,8 +1580,8 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, BlockContext...@@ -1580,8 +1580,8 @@ static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, BlockContext
1580 node->data.struct_decl.type_entry = container_type;1580 node->data.struct_decl.type_entry = container_type;
15811581
1582 // handle the member function definitions independently1582 // handle the member function definitions independently
1583 for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {1583 for (int i = 0; i < node->data.struct_decl.decls.length; i += 1) {
1584 AstNode *child_node = node->data.struct_decl.fns.at(i);1584 AstNode *child_node = node->data.struct_decl.decls.at(i);
1585 get_as_top_level_decl(child_node)->parent_decl = node;1585 get_as_top_level_decl(child_node)->parent_decl = node;
1586 BlockContext *child_context = get_container_block_context(container_type);1586 BlockContext *child_context = get_container_block_context(container_type);
1587 scan_decls(g, import, child_context, child_node);1587 scan_decls(g, import, child_context, child_node);
...@@ -1669,7 +1669,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)...@@ -1669,7 +1669,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
1669 case NodeTypeVariableDeclaration:1669 case NodeTypeVariableDeclaration:
1670 {1670 {
1671 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;1671 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
1672 VariableTableEntry *var = analyze_variable_declaration_raw(g, import, import->block_context,1672 VariableTableEntry *var = analyze_variable_declaration_raw(g, import, node->block_context,
1673 node, variable_declaration, false, node, false);1673 node, variable_declaration, false, node, false);
16741674
1675 g->global_vars.append(var);1675 g->global_vars.append(var);
src/parser.cpp+11-4
...@@ -2605,7 +2605,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,...@@ -2605,7 +2605,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,
26052605
2606/*2606/*
2607ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"2607ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"
2608StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)2608StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl)
2609StructField : "Symbol" option(":" Expression) ",")2609StructField : "Symbol" option(":" Expression) ",")
2610*/2610*/
2611static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,2611static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
...@@ -2664,7 +2664,14 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,...@@ -2664,7 +2664,14 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
26642664
2665 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directive_list, visib_mod);2665 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directive_list, visib_mod);
2666 if (fn_def_node) {2666 if (fn_def_node) {
2667 node->data.struct_decl.fns.append(fn_def_node);2667 node->data.struct_decl.decls.append(fn_def_node);
2668 continue;
2669 }
2670
2671 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, directive_list, visib_mod);
2672 if (var_decl_node) {
2673 ast_eat_token(pc, token_index, TokenIdSemicolon);
2674 node->data.struct_decl.decls.append(var_decl_node);
2668 continue;2675 continue;
2669 }2676 }
26702677
...@@ -3035,7 +3042,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3035,7 +3042,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3035 break;3042 break;
3036 case NodeTypeStructDecl:3043 case NodeTypeStructDecl:
3037 visit_node_list(&node->data.struct_decl.fields, visit, context);3044 visit_node_list(&node->data.struct_decl.fields, visit, context);
3038 visit_node_list(&node->data.struct_decl.fns, visit, context);3045 visit_node_list(&node->data.struct_decl.decls, visit, context);
3039 visit_node_list(node->data.struct_decl.top_level_decl.directives, visit, context);3046 visit_node_list(node->data.struct_decl.top_level_decl.directives, visit, context);
3040 break;3047 break;
3041 case NodeTypeStructField:3048 case NodeTypeStructField:
...@@ -3278,7 +3285,7 @@ AstNode *ast_clone_subtree(AstNode *old_node, uint32_t *next_node_index) {...@@ -3278,7 +3285,7 @@ AstNode *ast_clone_subtree(AstNode *old_node, uint32_t *next_node_index) {
3278 case NodeTypeStructDecl:3285 case NodeTypeStructDecl:
3279 clone_subtree_list(&new_node->data.struct_decl.fields, &old_node->data.struct_decl.fields,3286 clone_subtree_list(&new_node->data.struct_decl.fields, &old_node->data.struct_decl.fields,
3280 next_node_index);3287 next_node_index);
3281 clone_subtree_list(&new_node->data.struct_decl.fns, &old_node->data.struct_decl.fns,3288 clone_subtree_list(&new_node->data.struct_decl.decls, &old_node->data.struct_decl.decls,
3282 next_node_index);3289 next_node_index);
3283 clone_subtree_list_ptr(&new_node->data.struct_decl.top_level_decl.directives,3290 clone_subtree_list_ptr(&new_node->data.struct_decl.top_level_decl.directives,
3284 old_node->data.struct_decl.top_level_decl.directives, next_node_index);3291 old_node->data.struct_decl.top_level_decl.directives, next_node_index);
test/self_hosted.zig+8
...@@ -1640,3 +1640,11 @@ fn truncate() {...@@ -1640,3 +1640,11 @@ fn truncate() {
1640fn test_truncate(x: u32) -> u8 {1640fn test_truncate(x: u32) -> u8 {
1641 @truncate(u8, x)1641 @truncate(u8, x)
1642}1642}
1643
1644#attribute("test")
1645fn const_decls_in_struct() {
1646 assert(GenericDataThing(3).count_plus_one == 4);
1647}
1648struct GenericDataThing(count: isize) {
1649 const count_plus_one = count + 1;
1650}