aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-28 20:26:40 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-28 20:26:40 -0700
commita5c2de5fee67e35c8173b7051675d49648086cbb (patch)
treee6ee63d6daca6d6456e58f866d47e2c426cd9315 /src/parser.cpp
parent2bb2e61ee288a02e184e5b8422859a4afcbb4813 (diff)
downloadzig-a5c2de5fee67e35c8173b7051675d49648086cbb.tar.gz
zig-a5c2de5fee67e35c8173b7051675d49648086cbb.zip
ability to specify function type
closes #14
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp55
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: