aboutsummaryrefslogtreecommitdiff
path: root/src/parse/parse.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-25 00:49:29 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-25 00:49:29 -0400
commit1f93e82303f19029394c3e1d2c375c23d56a6498 (patch)
tree3d7fa048d36cb903f2f9af5827c720a586125f26 /src/parse/parse.c
parentc6014873d83889e4bf598f6073c771480da20b7b (diff)
Split out function parsing.
Diffstat (limited to 'src/parse/parse.c')
-rw-r--r--src/parse/parse.c143
1 files changed, 1 insertions, 142 deletions
diff --git a/src/parse/parse.c b/src/parse/parse.c
index 53365ee7..a3f30c64 100644
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -16,6 +16,7 @@
#include "context.h"
#include "errors.h"
#include "files.h"
+#include "functions.h"
#include "numbers.h"
#include "parse.h"
#include "utils.h"
@@ -880,22 +881,6 @@ ast_t *parse_return(parse_ctx_t *ctx, const char *pos) {
return ret;
}
-ast_t *parse_lambda(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- if (!match_word(&pos, "func")) return NULL;
- spaces(&pos);
- if (!match(&pos, "(")) return NULL;
- arg_ast_t *args = parse_args(ctx, &pos);
- spaces(&pos);
- type_ast_t *ret = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
- spaces(&pos);
- expect_closing(ctx, &pos, ")", "I was expecting a ')' to finish this anonymous function's arguments");
- ast_t *body = optional(ctx, &pos, parse_block);
- if (!body) body = NewAST(ctx->file, pos, pos, Block, .statements = NULL);
- return NewAST(ctx->file, start, pos, Lambda, .id = ctx->next_lambda_id++, .args = args, .ret_type = ret,
- .body = body);
-}
-
ast_t *parse_none(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match_word(&pos, "none")) return NULL;
@@ -1499,132 +1484,6 @@ ast_t *parse_extend(parse_ctx_t *ctx, const char *pos) {
return NewAST(ctx->file, start, pos, Extend, .name = name, .body = body);
}
-arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos) {
- arg_ast_t *args = NULL;
- for (;;) {
- const char *batch_start = *pos;
- ast_t *default_val = NULL;
- type_ast_t *type = NULL;
-
- typedef struct name_list_s {
- const char *name;
- struct name_list_s *next;
- } name_list_t;
-
- name_list_t *names = NULL;
- for (;;) {
- whitespace(pos);
- const char *name = get_id(pos);
- if (!name) break;
- whitespace(pos);
-
- if (match(pos, ":")) {
- type = expect(ctx, *pos - 1, pos, parse_type, "I expected a type here");
- names = new (name_list_t, .name = name, .next = names);
- whitespace(pos);
- if (match(pos, "="))
- default_val = expect(ctx, *pos - 1, pos, parse_term, "I expected a value after this '='");
- break;
- } else if (strncmp(*pos, "==", 2) != 0 && match(pos, "=")) {
- default_val = expect(ctx, *pos - 1, pos, parse_term, "I expected a value after this '='");
- names = new (name_list_t, .name = name, .next = names);
- break;
- } else if (name) {
- names = new (name_list_t, .name = name, .next = names);
- spaces(pos);
- if (!match(pos, ",")) break;
- } else {
- break;
- }
- }
- if (!names) break;
- if (!default_val && !type)
- parser_err(ctx, batch_start, *pos,
- "I expected a ':' and type, or '=' and a default value after this parameter (", names->name,
- ")");
-
- REVERSE_LIST(names);
- for (; names; names = names->next)
- args = new (arg_ast_t, .name = names->name, .type = type, .value = default_val, .next = args);
-
- if (!match_separator(pos)) break;
- }
-
- REVERSE_LIST(args);
- return args;
-}
-
-ast_t *parse_func_def(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- if (!match_word(&pos, "func")) return NULL;
-
- ast_t *name = optional(ctx, &pos, parse_var);
- if (!name) return NULL;
-
- spaces(&pos);
-
- expect_str(ctx, start, &pos, "(", "I expected a parenthesis for this function's arguments");
-
- arg_ast_t *args = parse_args(ctx, &pos);
- spaces(&pos);
- type_ast_t *ret_type = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
- whitespace(&pos);
- bool is_inline = false;
- ast_t *cache_ast = NULL;
- for (bool specials = match(&pos, ";"); specials; specials = match_separator(&pos)) {
- const char *flag_start = pos;
- if (match_word(&pos, "inline")) {
- is_inline = true;
- } else if (match_word(&pos, "cached")) {
- if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .str = "-1");
- } else if (match_word(&pos, "cache_size")) {
- whitespace(&pos);
- if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
- whitespace(&pos);
- cache_ast = expect(ctx, start, &pos, parse_expr, "I expected a maximum size for the cache");
- }
- }
- expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition");
-
- ast_t *body = expect(ctx, start, &pos, parse_block, "This function needs a body block");
- return NewAST(ctx->file, start, pos, FunctionDef, .name = name, .args = args, .ret_type = ret_type, .body = body,
- .cache = cache_ast, .is_inline = is_inline);
-}
-
-ast_t *parse_convert_def(parse_ctx_t *ctx, const char *pos) {
- const char *start = pos;
- if (!match_word(&pos, "convert")) return NULL;
-
- spaces(&pos);
-
- if (!match(&pos, "(")) return NULL;
-
- arg_ast_t *args = parse_args(ctx, &pos);
- spaces(&pos);
- type_ast_t *ret_type = match(&pos, "->") ? optional(ctx, &pos, parse_type) : NULL;
- whitespace(&pos);
- bool is_inline = false;
- ast_t *cache_ast = NULL;
- for (bool specials = match(&pos, ";"); specials; specials = match_separator(&pos)) {
- const char *flag_start = pos;
- if (match_word(&pos, "inline")) {
- is_inline = true;
- } else if (match_word(&pos, "cached")) {
- if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Int, .str = "-1");
- } else if (match_word(&pos, "cache_size")) {
- whitespace(&pos);
- if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'");
- whitespace(&pos);
- cache_ast = expect(ctx, start, &pos, parse_expr, "I expected a maximum size for the cache");
- }
- }
- expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition");
-
- ast_t *body = expect(ctx, start, &pos, parse_block, "This function needs a body block");
- return NewAST(ctx->file, start, pos, ConvertDef, .args = args, .ret_type = ret_type, .body = body,
- .cache = cache_ast, .is_inline = is_inline);
-}
-
ast_t *parse_extern(parse_ctx_t *ctx, const char *pos) {
const char *start = pos;
if (!match_word(&pos, "extern")) return NULL;