From 58dfde37752f87e5df850ebe3a324dcb825fdb35 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 30 Oct 2021 09:02:55 +0200 Subject: Add parsing for fun expressions --- src/lexer.c | 2 ++ src/lexer.h | 1 + src/parser.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) (limited to 'src') diff --git a/src/lexer.c b/src/lexer.c index 704ee66..09c8f6c 100755 --- a/src/lexer.c +++ b/src/lexer.c @@ -15,6 +15,7 @@ static const char* token_str[] = { [TOKEN_IF] = "TOKEN_IF", [TOKEN_DEF] = "TOKEN_DEF", [TOKEN_SET] = "TOKEN_SET", + [TOKEN_FUN] = "TOKEN_FUN", [TOKEN_EOF] = "TOKEN_EOF", }; @@ -132,6 +133,7 @@ find_primitive_type(const StringView value) { if (TOKEN_IS_KEYWORD(value, "if")) { return TOKEN_IF; } if (TOKEN_IS_KEYWORD(value, "def")) { return TOKEN_DEF; } if (TOKEN_IS_KEYWORD(value, "set!")) { return TOKEN_SET; } + if (TOKEN_IS_KEYWORD(value, "fun")) { return TOKEN_FUN; } return TOKEN_SYMBOL; } diff --git a/src/lexer.h b/src/lexer.h index f187526..c477fbd 100755 --- a/src/lexer.h +++ b/src/lexer.h @@ -23,6 +23,7 @@ typedef enum TokenType { TOKEN_IF, TOKEN_DEF, TOKEN_SET, + TOKEN_FUN, // End of file. TOKEN_EOF, diff --git a/src/parser.c b/src/parser.c index f831e50..e32a571 100644 --- a/src/parser.c +++ b/src/parser.c @@ -116,6 +116,15 @@ parse_lambda(Parser *parser, Errors *errors) { Object *expr = parse_tree(parser, errors); array_push(lambda->body, expr); } + if (array_size(lambda->body) == 0) { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = start.line, + .col = start.col, + }); + return NULL; + } return lambda; } @@ -226,6 +235,39 @@ parse_var(Parser *parser, Errors *errors) { return ret; } +Object * +parse_fun(Parser *parser, Errors *errors) { + Token start = next_token(parser); + Object *ret = object_alloc(start, OBJ_TYPE_DEF); + + // Variable name. + Token tok = peek_token(parser); + if (tok.type == TOKEN_RPAREN) { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = tok.line, + .col = tok.col, + }); + return NULL; + } + if (tok.type != TOKEN_SYMBOL) { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_WRONG_ARG_TYPE, + .line = tok.line, + .col = tok.col, + }); + return NULL; + } + ret->var_name = parse_tree(parser, errors); + + // Variable value (expression). + rewind_token(parser); + ret->var_expr = parse_lambda(parser, errors); + return ret; +} + Object * parse_list(Parser *parser, Errors *errors) { if (errors->n != 0) { @@ -247,6 +289,7 @@ parse_list(Parser *parser, Errors *errors) { case TOKEN_IF: { return parse_if(parser, errors); } break; case TOKEN_DEF: { return parse_var(parser, errors); } break; case TOKEN_SET: { return parse_var(parser, errors); } break; + case TOKEN_FUN: { return parse_fun(parser, errors); } break; default: break; } -- cgit v1.2.1