From 4c5ffb35d50d514e3df4788e7cf38245c0127883 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 2 Mar 2019 23:01:51 +0100 Subject: Add variable declaration without assignment --- src/parser.c | 37 ++++++++++++++++++++++--------------- tests/main.amal | 4 +++- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/parser.c b/src/parser.c index 7588bda..6ea8d1d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -72,8 +72,9 @@ static CHECK_RESULT int parser_parse_body_loop(Parser *self, Buffer *body_list, /* LHS = 'const'|'var' IDENTIFIER */ -static CHECK_RESULT int parser_parse_lhs(Parser *self, LhsExpr **result) { +static CHECK_RESULT int parser_parse_lhs(Parser *self, LhsExpr **result, bool *assignment) { bool isConst; + bool match; BufferView var_name; *result = NULL; @@ -90,6 +91,23 @@ static CHECK_RESULT int parser_parse_lhs(Parser *self, LhsExpr **result) { amal_log_debug("var name: %.*s", (int)var_name.size, var_name.data); return_if_error(scoped_allocator_alloc(self->allocator, sizeof(LhsExpr), (void**)result)); lhsexpr_init(*result, isConst, var_name); + + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EQUALS, &match)); + if(match) { + *assignment = bool_true; + return PARSER_OK; + } + + *assignment = bool_false; + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match)); + if(match && isConst) { + self->error = tokenizer_create_error(&self->tokenizer, "const variable declaration requires assignment (expected '=', got ';')"); + return PARSER_UNEXPECTED_TOKEN; + } + if(!match) { + self->error = tokenizer_create_error(&self->tokenizer, "Expected '=' or ';'"); + return PARSER_UNEXPECTED_TOKEN; + } return PARSER_OK; } @@ -273,29 +291,18 @@ BODY = LHS ';' | Note: Semicolon is not required for closures, structs and tables */ int parser_parse_body(Parser *self, Ast *ast) { - bool match; + bool assignment; LhsExpr *lhs_expr; Ast rhs_expr; rhs_expr = ast_none(); - return_if_error(parser_parse_lhs(self, &lhs_expr)); - if(lhs_expr) { - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_EQUALS, &match)); - if(match) - goto rhs; - - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_SEMICOLON, &match)); - if(!match) { - self->error = tokenizer_create_error(&self->tokenizer, "Expected '=' or ';'"); - return PARSER_UNEXPECTED_TOKEN; - } - + return_if_error(parser_parse_lhs(self, &lhs_expr, &assignment)); + if(!assignment) { ast->type = AST_LHS; ast->value.lhs_expr = lhs_expr; return PARSER_OK; } - rhs: return_if_error(parser_parse_rhs_start(self, &rhs_expr)); if(lhs_expr) { lhs_expr->rhs_expr = rhs_expr; diff --git a/tests/main.amal b/tests/main.amal index 26da7d6..71e962e 100644 --- a/tests/main.amal +++ b/tests/main.amal @@ -5,7 +5,9 @@ const main = fn { } const value = "hello"; - print(value, "world", 356); + print(value, "world", 356, 13.37); + var num1; + const num2 = 23232; } const print = fn { -- cgit v1.2.3