Skip to content

Commit ec7941b

Browse files
feat(wheel_parser): add parse_variable_declaration function for variable declarations
1 parent db9cedc commit ec7941b

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "wheel_parser/error.hxx"
2+
#if !defined(PARSER_VARIABLES_DECLARATION_HXX)
3+
#define PARSER_VARIABLES_DECLARATION_HXX
4+
5+
#include "wheel_parser/config.hxx"
6+
#include "wheel_parser/ast/nodes.hxx"
7+
#include "wheel_parser/parser_utils.hxx"
8+
#include "wheel_parser/ast/keywords.hxx"
9+
#include "wheel_parser/ast/builtins.hxx"
10+
#include "contracts_declaration.hxx"
11+
#include "emit_error.hxx"
12+
13+
using wheel_parser::ast::StatementNode;
14+
using wheel_parser::ast::VariableDeclaration;
15+
using wheel_parser::functions::ParserFuncContract;
16+
using wheel_parser::functions::EmitErrorConfig;
17+
using wheel_parser::ast::Keyword;
18+
using wheel_parser::ast::LiteralExpression;
19+
using wheel_parser::ast::BuiltinRegistry;
20+
21+
WHEEL_PARSER_FUNCTIONS_BEGIN_NAMESPACE
22+
PARSE_BEGIN(parse_variable_declaration, StatementNode, BuiltinRegistry registry)
23+
consume(contract.lexer, contract.state.current_token);
24+
if (!keyword_matches(contract.state.current_token, Keyword::Var)) {
25+
return nullptr;
26+
}
27+
28+
const auto start_token = copy_token(contract.arena, contract.state.current_token);
29+
30+
skip_spaces(contract.lexer, contract.state.current_token);
31+
32+
if (!token_matches(contract.state.current_token.kind, TokenKind::IDENT)) {
33+
return emit_error(ERROR_CONTEXT(ParseErrorCode::ExpectedIdentifier));
34+
}
35+
const auto var_name = contract.interner.intern(contract.state.current_token.str);
36+
37+
skip_spaces(contract.lexer, contract.state.current_token);
38+
if (!token_matches(contract.state.current_token.kind, TokenKind::COLON)) {
39+
return emit_error(ERROR_CONTEXT(ParseErrorCode::ExpectedColon));
40+
}
41+
42+
skip_spaces(contract.lexer, contract.state.current_token);
43+
if (!token_matches(contract.state.current_token.kind, TokenKind::IDENT)) {
44+
return emit_error(ERROR_CONTEXT(ParseErrorCode::ExpectedTypeKeyword));
45+
}
46+
47+
BuiltinType builtin_type;
48+
if (!type_keyword_matches(contract.state.current_token, builtin_type)) {
49+
builtin_type = BuiltinType::ManualDeclaration;
50+
}
51+
52+
const auto var_type = registry.type_symbol(builtin_type);
53+
54+
skip_spaces(contract.lexer, contract.state.current_token);
55+
if (!token_matches(contract.state.current_token.kind, TokenKind::EQUAL)) {
56+
return emit_error(ERROR_CONTEXT(ParseErrorCode::ExpectedEqual));
57+
}
58+
59+
skip_spaces(contract.lexer, contract.state.current_token);
60+
switch (contract.state.current_token.kind) {
61+
case TokenKind::INT_LITERAL:
62+
case TokenKind::FLOAT_LITERAL:
63+
case TokenKind::STRING_LITERAL:
64+
case TokenKind::RAW_STRING_LITERAL:
65+
break;
66+
67+
default:
68+
/* In this case, we'll ignore for semantic phase
69+
for handling this case:
70+
71+
var x: int = -1
72+
*/
73+
IGNORE;
74+
}
75+
76+
const auto literal_token = copy_token(contract.arena, contract.state.current_token);
77+
const auto literal = contract.arena.allocate<LiteralExpression>(
78+
literal_token
79+
);
80+
81+
return contract.arena.allocate<VariableDeclaration>(
82+
start_token,
83+
var_type, var_name, literal
84+
);
85+
86+
PARSE_END
87+
88+
WHEEL_PARSER_FUNCTIONS_END_NAMESPACE
89+
90+
#endif // PARSER_VARIABLES_DECLARATION_HXX

0 commit comments

Comments
 (0)