diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-28 20:26:40 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-28 20:26:40 -0700 |
| commit | a5c2de5fee67e35c8173b7051675d49648086cbb (patch) | |
| tree | e6ee63d6daca6d6456e58f866d47e2c426cd9315 /src/parser.cpp | |
| parent | 2bb2e61ee288a02e184e5b8422859a4afcbb4813 (diff) | |
| download | zig-a5c2de5fee67e35c8173b7051675d49648086cbb.tar.gz zig-a5c2de5fee67e35c8173b7051675d49648086cbb.zip | |
ability to specify function type
closes #14
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index e717a18941..b9755f3123 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -503,6 +503,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool mandatory); static AstNode *ast_parse_unwrap_expr(ParseContext *pc, int *token_index, bool mandatory); static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, bool mandatory); +static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory, + ZigList<AstNode*> *directives, VisibMod visib_mod); static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { if (token->id == token_id) { @@ -671,7 +673,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, int *token_index, bool Token *l_paren = &pc->tokens->at(*token_index); if (l_paren->id != TokenIdLParen) { if (mandatory) { - ast_invalid_token_error(pc, l_paren); + ast_expect_token(pc, l_paren, TokenIdLParen); } else { return nullptr; } @@ -695,7 +697,7 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, int *token_index, bo Token *l_bracket = &pc->tokens->at(*token_index); if (l_bracket->id != TokenIdLBracket) { if (mandatory) { - ast_invalid_token_error(pc, l_bracket); + ast_expect_token(pc, l_bracket, TokenIdLBracket); } else { return nullptr; } @@ -865,7 +867,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand if (asm_token->id != TokenIdKeywordAsm) { if (mandatory) { - ast_invalid_token_error(pc, asm_token); + ast_expect_token(pc, asm_token, TokenIdKeywordAsm); } else { return nullptr; } @@ -905,7 +907,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand } /* -PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol") +PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol") KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" */ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { @@ -956,6 +958,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool AstNode *node = ast_create_node(pc, NodeTypeErrorType, token); *token_index += 1; return node; + } else if (token->id == TokenIdKeywordExtern) { + *token_index += 1; + AstNode *node = ast_parse_fn_proto(pc, token_index, true, nullptr, VisibModPrivate); + node->data.fn_proto.is_extern = true; + return node; } else if (token->id == TokenIdAtSign) { *token_index += 1; Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); @@ -1002,6 +1009,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool return array_type_node; } + AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, nullptr, VisibModPrivate); + if (fn_proto_node) { + return fn_proto_node; + } + AstNode *asm_expr = ast_parse_asm_expr(pc, token_index, false); if (asm_expr) { return asm_expr; @@ -1055,7 +1067,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index, token = &pc->tokens->at(*token_index); continue; } else if (comma_tok->id != TokenIdRBrace) { - ast_invalid_token_error(pc, comma_tok); + ast_expect_token(pc, comma_tok, TokenIdRBrace); } else { *token_index += 1; break; @@ -1084,7 +1096,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index, token = &pc->tokens->at(*token_index); continue; } else if (comma_tok->id != TokenIdRBrace) { - ast_invalid_token_error(pc, comma_tok); + ast_expect_token(pc, comma_tok, TokenIdRBrace); } else { *token_index += 1; break; @@ -1555,7 +1567,7 @@ static AstNode *ast_parse_else(ParseContext *pc, int *token_index, bool mandator if (else_token->id != TokenIdKeywordElse) { if (mandatory) { - ast_invalid_token_error(pc, else_token); + ast_expect_token(pc, else_token, TokenIdKeywordElse); } else { return nullptr; } @@ -1574,7 +1586,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda Token *if_tok = &pc->tokens->at(*token_index); if (if_tok->id != TokenIdKeywordIf) { if (mandatory) { - ast_invalid_token_error(pc, if_tok); + ast_expect_token(pc, if_tok, TokenIdKeywordIf); } else { return nullptr; } @@ -1637,7 +1649,8 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m kind = ReturnKindError; *token_index += 2; } else if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, next_token, TokenIdKeywordReturn); + zig_unreachable(); } else { return nullptr; } @@ -1647,7 +1660,8 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m kind = ReturnKindMaybe; *token_index += 2; } else if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, next_token, TokenIdKeywordReturn); + zig_unreachable(); } else { return nullptr; } @@ -1655,7 +1669,8 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m kind = ReturnKindUnconditional; *token_index += 1; } else if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, token, TokenIdKeywordReturn); + zig_unreachable(); } else { return nullptr; } @@ -1756,7 +1771,7 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool ma if (token->id != TokenIdKeywordWhile) { if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, token, TokenIdKeywordWhile); } else { return nullptr; } @@ -1791,7 +1806,7 @@ static AstNode *ast_parse_for_expr(ParseContext *pc, int *token_index, bool mand if (token->id != TokenIdKeywordFor) { if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, token, TokenIdKeywordFor); } else { return nullptr; } @@ -1829,7 +1844,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m if (token->id != TokenIdKeywordSwitch) { if (mandatory) { - ast_invalid_token_error(pc, token); + ast_expect_token(pc, token, TokenIdKeywordSwitch); } else { return nullptr; } @@ -2082,7 +2097,7 @@ static AstNode *ast_parse_label(ParseContext *pc, int *token_index, bool mandato Token *symbol_token = &pc->tokens->at(*token_index); if (symbol_token->id != TokenIdSymbol) { if (mandatory) { - ast_invalid_token_error(pc, symbol_token); + ast_expect_token(pc, symbol_token, TokenIdSymbol); } else { return nullptr; } @@ -2091,7 +2106,7 @@ static AstNode *ast_parse_label(ParseContext *pc, int *token_index, bool mandato Token *colon_token = &pc->tokens->at(*token_index + 1); if (colon_token->id != TokenIdColon) { if (mandatory) { - ast_invalid_token_error(pc, colon_token); + ast_expect_token(pc, colon_token, TokenIdColon); } else { return nullptr; } @@ -2122,7 +2137,7 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato if (last_token->id != TokenIdLBrace) { if (mandatory) { - ast_invalid_token_error(pc, last_token); + ast_expect_token(pc, last_token, TokenIdLBrace); } else { return nullptr; } @@ -2245,7 +2260,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool m Token *extern_kw = &pc->tokens->at(*token_index); if (extern_kw->id != TokenIdKeywordExtern) { if (mandatory) { - ast_invalid_token_error(pc, extern_kw); + ast_expect_token(pc, extern_kw, TokenIdKeywordExtern); } else { return nullptr; } @@ -2591,7 +2606,9 @@ void normalize_parent_ptrs(AstNode *node) { break; case NodeTypeFnProto: set_field(&node->data.fn_proto.return_type); - set_list_fields(node->data.fn_proto.directives); + if (node->data.fn_proto.directives) { + set_list_fields(node->data.fn_proto.directives); + } set_list_fields(&node->data.fn_proto.params); break; case NodeTypeFnDef: |
