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 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'src') 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; -- cgit v1.2.3