diff options
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index b1b9e122a8..bd4c959608 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -75,6 +75,8 @@ const char *node_type_str(NodeType node_type) { return "Directive"; case NodeTypeReturnExpr: return "ReturnExpr"; + case NodeTypeVariableDeclaration: + return "VariableDeclaration"; case NodeTypeCastExpr: return "CastExpr"; case NodeTypeNumberLiteral: @@ -178,6 +180,16 @@ void ast_print(AstNode *node, int indent) { if (node->data.return_expr.expr) ast_print(node->data.return_expr.expr, indent + 2); break; + case NodeTypeVariableDeclaration: + { + Buf *name_buf = &node->data.variable_declaration.symbol; + fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); + if (node->data.variable_declaration.type) + ast_print(node->data.variable_declaration.type, indent + 2); + if (node->data.variable_declaration.expr) + ast_print(node->data.variable_declaration.expr, indent + 2); + break; + } case NodeTypeExternBlock: { fprintf(stderr, "%s\n", node_type_str(node->type)); @@ -1043,6 +1055,45 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m } /* +VariableDeclaration : token(Let) token(Symbole) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression)) +*/ +static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) { + Token *let_tok = &pc->tokens->at(*token_index); + if (let_tok->id == TokenIdKeywordLet) { + *token_index += 1; + AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, let_tok); + + Token *name_token = &pc->tokens->at(*token_index); + *token_index += 1; + ast_expect_token(pc, name_token, TokenIdSymbol); + ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol); + + Token *eq_or_colon = &pc->tokens->at(*token_index); + *token_index += 1; + if (eq_or_colon->id == TokenIdEq) { + node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true); + return node; + } else if (eq_or_colon->id == TokenIdColon) { + node->data.variable_declaration.type = ast_parse_type(pc, *token_index, token_index); + + Token *eq_token = &pc->tokens->at(*token_index); + if (eq_token->id == TokenIdEq) { + *token_index += 1; + + node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true); + } + return node; + } else { + ast_invalid_token_error(pc, eq_or_colon); + } + } else if (mandatory) { + ast_invalid_token_error(pc, let_tok); + } else { + return nullptr; + } +} + +/* BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression */ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool mandatory) { @@ -1086,19 +1137,23 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, int *token_index, bool ma } /* -NonBlockExpression : BoolOrExpression | ReturnExpression +NonBlockExpression : ReturnExpression | VariableDeclaration | BoolOrExpression */ static AstNode *ast_parse_non_block_expr(ParseContext *pc, int *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); - AstNode *bool_or_expr = ast_parse_bool_or_expr(pc, token_index, false); - if (bool_or_expr) - return bool_or_expr; - AstNode *return_expr = ast_parse_return_expr(pc, token_index, false); if (return_expr) return return_expr; + AstNode *variable_declaration_expr = ast_parse_variable_declaration_expr(pc, token_index, false); + if (variable_declaration_expr) + return variable_declaration_expr; + + AstNode *bool_or_expr = ast_parse_bool_or_expr(pc, token_index, false); + if (bool_or_expr) + return bool_or_expr; + if (mandatory) ast_invalid_token_error(pc, token); |
