From a65c02b752722c873036a9246753f2e40c24305f Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 1 Jun 2025 04:50:51 +0200 Subject: Function literal expressions Signed-off-by: Mel --- boot/parse.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'boot/parse.c') diff --git a/boot/parse.c b/boot/parse.c index ed00f94..3870e6c 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -225,6 +225,7 @@ parser_node_type(struct Parser* p, struct Parser_Error* error) // for now, we only support a single type name. // in the future, we might want to support more complex types. return (struct Type_Node){ + .type = TYPE_NAME, .name = type_name, .span = token.span, .location = token.location, @@ -286,6 +287,42 @@ parser_expression_primary_group(struct Parser* p, struct Parser_Error* error) return expression_new(EXPRESSION_GROUP, value, span, start_token.location); } +struct Expression* +parser_expression_function(struct Parser* p, struct Parser_Error* error) +{ + struct Token fun_token = CHECK(parser_need(p, TOKEN_WORD_FUN, error)); + CHECK(parser_need(p, TOKEN_ROUND_OPEN, error)); + + struct Expression_Function fun = { 0 }; + while (!parser_probe(p, TOKEN_ROUND_CLOSE)) { + struct Token name_token = CHECK(parser_need(p, TOKEN_NAME, error)); + struct String name = name_token.value.name; + + struct Type_Node type = { 0 }; + + struct Token next = parser_peek(p); + if (!token_is(&next, TOKEN_ROUND_CLOSE) && !token_is(&next, TOKEN_COMMA)) + type = CHECK(parser_node_type(p, error)); + + if (parser_probe(p, TOKEN_COMMA)) parser_next(p); + + check(fun.parameter_count < EXPRESSION_FUNCTION_MAX_PARAMS, "too many function parameters"); + fun.parameters[fun.parameter_count++] = (struct Expression_Function_Parameter){ + .name = name, + .type = type, + }; + } + parser_next(p); + + if (!parser_probe(p, TOKEN_CURLY_OPEN)) fun.return_type = CHECK(parser_node_type(p, error)); + + fun.body = CHECK(parser_block_node(p, error)); + + return expression_new( + EXPRESSION_FUNCTION, (union Expression_Value){ .function = fun }, + span_merge(fun_token.span, fun.body.span), fun_token.location); +} + struct Expression* parser_expression_primary(struct Parser* p, struct Parser_Error* error) { @@ -304,6 +341,8 @@ parser_expression_primary(struct Parser* p, struct Parser_Error* error) return parser_expression_primary_boolean(p, error); case TOKEN_ROUND_OPEN: return parser_expression_primary_group(p, error); + case TOKEN_WORD_FUN: + return parser_expression_function(p, error); default: *error = parser_error(PARSER_ERROR_EXPECTED_PRIMARY_EXPRESSION); return nil; @@ -522,7 +561,6 @@ parser_statement_declaration(struct Parser* p, struct Parser_Error* error) union Statement_Value value = { .declaration = { .names = names, - .has_type = true, .type = type, .initializer = initializer, }, -- cgit 1.4.1