aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp59
1 files changed, 20 insertions, 39 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 2f4824ad39..0ee984d7fa 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -216,6 +216,7 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod);
static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index);
static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory);
+static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
if (token->id == token_id) {
@@ -618,7 +619,7 @@ static AstNode *ast_parse_goto_expr(ParseContext *pc, size_t *token_index, bool
return node;
}
/*
-PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
+PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
*/
static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
@@ -737,6 +738,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
return asm_expr;
}
+ AstNode *container_decl = ast_parse_container_decl(pc, token_index, false);
+ if (container_decl)
+ return container_decl;
+
if (!mandatory)
return nullptr;
@@ -2219,43 +2224,31 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi
}
/*
-ContainerDecl = ("struct" | "enum" | "union") Symbol option(ParamDeclList) "{" many(StructMember) "}"
-StructMember = (StructField | FnDef | GlobalVarDecl | ContainerDecl)
+ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}"
+StructMember = (StructField | FnDef | GlobalVarDecl)
StructField = Symbol option(":" Expression) ",")
*/
-static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
+static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *first_token = &pc->tokens->at(*token_index);
ContainerKind kind;
-
if (first_token->id == TokenIdKeywordStruct) {
kind = ContainerKindStruct;
} else if (first_token->id == TokenIdKeywordEnum) {
kind = ContainerKindEnum;
} else if (first_token->id == TokenIdKeywordUnion) {
kind = ContainerKindUnion;
+ } else if (mandatory) {
+ ast_invalid_token_error(pc, first_token);
} else {
return nullptr;
}
*token_index += 1;
- Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol);
-
AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token);
- node->data.struct_decl.kind = kind;
- node->data.struct_decl.name = token_buf(struct_name);
- node->data.struct_decl.visib_mod = visib_mod;
-
- Token *paren_or_brace = &pc->tokens->at(*token_index);
- if (paren_or_brace->id == TokenIdLParen) {
- ast_parse_param_decl_list(pc, token_index, &node->data.struct_decl.generic_params,
- &node->data.struct_decl.generic_params_is_var_args);
- ast_eat_token(pc, token_index, TokenIdLBrace);
- } else if (paren_or_brace->id == TokenIdLBrace) {
- *token_index += 1;
- } else {
- ast_invalid_token_error(pc, paren_or_brace);
- }
+ node->data.container_decl.kind = kind;
+
+ ast_eat_token(pc, token_index, TokenIdLBrace);
for (;;) {
Token *visib_tok = &pc->tokens->at(*token_index);
@@ -2272,20 +2265,14 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, visib_mod);
if (fn_def_node) {
- node->data.struct_decl.decls.append(fn_def_node);
+ node->data.container_decl.decls.append(fn_def_node);
continue;
}
AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
if (var_decl_node) {
ast_eat_token(pc, token_index, TokenIdSemicolon);
- node->data.struct_decl.decls.append(var_decl_node);
- continue;
- }
-
- AstNode *container_decl_node = ast_parse_container_decl(pc, token_index, visib_mod);
- if (container_decl_node) {
- node->data.struct_decl.decls.append(container_decl_node);
+ node->data.container_decl.decls.append(var_decl_node);
continue;
}
@@ -2311,7 +2298,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
ast_eat_token(pc, token_index, TokenIdComma);
}
- node->data.struct_decl.fields.append(field_node);
+ node->data.container_decl.fields.append(field_node);
} else {
ast_invalid_token_error(pc, token);
}
@@ -2368,7 +2355,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib
/*
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
-TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | TypeDecl | UseDecl)
+TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
*/
static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
for (;;) {
@@ -2402,12 +2389,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
continue;
}
- AstNode *struct_node = ast_parse_container_decl(pc, token_index, visib_mod);
- if (struct_node) {
- top_level_decls->append(struct_node);
- continue;
- }
-
AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
if (var_decl_node) {
ast_eat_token(pc, token_index, TokenIdSemicolon);
@@ -2630,8 +2611,8 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
}
break;
case NodeTypeContainerDecl:
- visit_node_list(&node->data.struct_decl.fields, visit, context);
- visit_node_list(&node->data.struct_decl.decls, visit, context);
+ visit_node_list(&node->data.container_decl.fields, visit, context);
+ visit_node_list(&node->data.container_decl.decls, visit, context);
break;
case NodeTypeStructField:
visit_field(&node->data.struct_field.type, visit, context);