From af74ddb119e3c5167a10bf5468af3960c8db42c0 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 2 Mar 2019 21:48:30 +0100 Subject: Use 'fn' to define closure to make parsing/reading the language easier It caused issues when you have parentheses to surround math expression, for example: ((func() + 34) * 54) is easier to parse if closure has to begin with 'fn'. Also removed requirement for semicolons. Semicolons can't even be used optionally yet. --- src/parser.c | 48 ++++++++++++++++++++++++++---------------------- src/tokenizer.c | 10 ++++++++++ 2 files changed, 36 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/parser.c b/src/parser.c index 539ebd3..babb2d9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -94,20 +94,24 @@ static CHECK_RESULT int parser_parse_lhs(Parser *self, LhsExpr **result) { } /* -CLOSURE = '(' PARAM* ')' '{' BODY_LOOP '}' +CLOSURE = 'fn' ('(' PARAM* ')')? '{' BODY_LOOP '}' */ static CHECK_RESULT int parser_parse_function_decl(Parser *self, FunctionDecl **func_decl) { - bool result; + bool match; *func_decl = NULL; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_PAREN, &result)); - if(!result) + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_FN, &match)); + if(!match) return PARSER_OK; - /* TODO: Parse parameters */ - return_if_error(tokenizer_accept(&self->tokenizer, TOK_CLOSING_PAREN)); - /* TODO: Parse return types */ - return_if_error(tokenizer_accept(&self->tokenizer, TOK_OPEN_BRACE)); + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_BRACE, &match)); + if(!match) { + return_if_error(tokenizer_accept(&self->tokenizer, TOK_OPEN_PAREN)); + /* TODO: Parse parameters */ + return_if_error(tokenizer_accept(&self->tokenizer, TOK_CLOSING_PAREN)); + /* TODO: Parse return types */ + return_if_error(tokenizer_accept(&self->tokenizer, TOK_OPEN_BRACE)); + } return_if_error(scoped_allocator_alloc(self->allocator, sizeof(FunctionDecl), (void**)func_decl)); return_if_error(funcdecl_init(*func_decl, self->allocator)); @@ -147,17 +151,17 @@ VARIABLE = IDENTIFIER FUNC_CALL_OR_VARIABLE = VARIABLE '(' FUNC_ARGS ')' */ static CHECK_RESULT int parser_parse_function_call_or_variable(Parser *self, Ast *expr) { - bool result; + bool match; BufferView identifier; FunctionCall *func_call; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IDENTIFIER, &result)); - if(!result) + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IDENTIFIER, &match)); + if(!match) return PARSER_OK; identifier = self->tokenizer.value.identifier; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_PAREN, &result)); - if(!result) { + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_OPEN_PAREN, &match)); + if(!match) { Variable *variable; return_if_error(scoped_allocator_alloc(self->allocator, sizeof(Variable), (void**)&variable)); variable->name = identifier; @@ -177,11 +181,11 @@ static CHECK_RESULT int parser_parse_function_call_or_variable(Parser *self, Ast IMPORT = IMPORT_SYMBOL */ static CHECK_RESULT int parser_parse_import(Parser *self, Import **import) { - bool result; + bool match; *import = NULL; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IMPORT, &result)); - if(!result) + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_IMPORT, &match)); + if(!match) return PARSER_OK; return_if_error(scoped_allocator_alloc(self->allocator, sizeof(Import), (void**)import)); @@ -190,11 +194,11 @@ static CHECK_RESULT int parser_parse_import(Parser *self, Import **import) { } static CHECK_RESULT int parser_parse_number(Parser *self, Ast *rhs_expr) { - bool result; + bool match; Number *number; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_NUMBER, &result)); - if(!result) + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_NUMBER, &match)); + if(!match) return PARSER_OK; return_if_error(scoped_allocator_alloc(self->allocator, sizeof(Number), (void**)&number)); @@ -208,10 +212,10 @@ static CHECK_RESULT int parser_parse_number(Parser *self, Ast *rhs_expr) { RHS = STRING | NUMBER | FUNC_CALL_OR_VARIABLE */ static CHECK_RESULT int parser_parse_rhs(Parser *self, Ast *rhs_expr) { - bool result; + bool match; - return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_STRING, &result)); - if(result) { + return_if_error(tokenizer_consume_if(&self->tokenizer, TOK_STRING, &match)); + if(match) { String *string; return_if_error(scoped_allocator_alloc(self->allocator, sizeof(String), (void**)&string)); return_if_error(string_init(string, self->tokenizer.value.string)); diff --git a/src/tokenizer.c b/src/tokenizer.c index 41d46fb..b996354 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -146,6 +146,13 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { self->value.identifier = create_buffer_view(self->code.data + identifier_start, self->index - identifier_start); switch(self->value.identifier.size) { + case 2: { + if(am_memeql(self->value.identifier.data, "fn", 2)) { + *token = TOK_FN; + return TOKENIZER_OK; + } + break; + } case 3: { if(am_memeql(self->value.identifier.data, "var", 3)) { *token = TOK_VAR; @@ -324,6 +331,9 @@ static BufferView tokenizer_expected_token_as_string(Token token) { case TOK_STRING: str = "string"; break; + case TOK_FN: + str = "fn"; + break; case TOK_EQUALS: str = "="; break; -- cgit v1.2.3