parse: implement parsing of function definitions

This commit is contained in:
2026-05-12 22:57:42 +01:00
parent 7d2e45edcb
commit 227e73853c
2 changed files with 106 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
#include "../syntax.h"
bool parse_func(struct parse_ctx *ctx, struct ast_node **out)
{
if (!parse_keyword(ctx, KW_FUNC)) {
return false;
}
struct lex_token *name = NULL;
if (!parse_word(ctx, &name)) {
report_error(ctx, "expected function identifier");
return false;
}
struct func_ast_node *func
= (struct func_ast_node *)ast_node_create(AST_FUNC);
if (!func) {
ctx->p_status = BSHELL_ERR_NO_MEMORY;
lex_token_destroy(name);
return false;
}
func->n_name = name;
if (!parse_symbol(ctx, SYM_LEFT_PAREN)) {
report_error(ctx, "expected `(` after function identifier");
ast_node_destroy((struct ast_node *)func);
return false;
}
size_t nr_args = 0;
bool ok = true;
while (1) {
if (parse_symbol(ctx, SYM_RIGHT_PAREN)) {
break;
}
if (nr_args > 0 && !parse_symbol(ctx, SYM_COMMA)) {
report_error(
ctx,
"expected `,` or `)` after parameter name");
ok = false;
break;
}
struct lex_token *param_token = NULL;
struct var_ast_node *param_node = NULL;
if (!parse_var(ctx, &param_token)) {
report_error(ctx, "expected parameter variable");
ok = false;
break;
}
param_node = (struct var_ast_node *)ast_node_create(AST_VAR);
if (!param_node) {
ok = false;
ctx->p_status = BSHELL_ERR_NO_MEMORY;
lex_token_destroy(param_token);
break;
}
param_node->n_ident = param_token;
fx_queue_push_back(
&func->n_params,
&param_node->n_base.n_entry);
}
if (!ok) {
if (ctx->p_status == BSHELL_SUCCESS) {
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
}
ast_node_destroy((struct ast_node *)func);
return false;
}
if (!parse_block(ctx, &func->n_body)) {
report_error(ctx, "failed to parse function body");
ast_node_destroy((struct ast_node *)func);
return false;
}
*out = (struct ast_node *)func;
return true;
}
+21
View File
@@ -0,0 +1,21 @@
#include "../syntax.h"
bool peek_keyword_expr(struct parse_ctx *ctx)
{
return peek_unknown_keyword(ctx) != KW_NONE;
}
bool parse_keyword_expr(struct parse_ctx *ctx, struct ast_node **out)
{
switch (peek_unknown_keyword(ctx)) {
case KW_NONE:
return false;
case KW_IF:
return parse_if(ctx, out);
case KW_FUNC:
return parse_func(ctx, out);
default:
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
return false;
}
}