From 1710f705e9c633144990f53371d79dfecefb157f Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sat, 30 May 2026 19:52:50 +0100 Subject: [PATCH] command: implement callable bytecode functions --- bshell.runtime/command/command.c | 6 + bshell.runtime/command/function.c | 197 ++++++++++++++++++ .../include/bshell/command/function.h | 10 + 3 files changed, 213 insertions(+) diff --git a/bshell.runtime/command/command.c b/bshell.runtime/command/command.c index 48bf6d7..e373ab2 100644 --- a/bshell.runtime/command/command.c +++ b/bshell.runtime/command/command.c @@ -17,6 +17,11 @@ static void init(fx_object *obj, void *priv) { } +static void fini(fx_object *obj, void *priv) +{ + struct bshell_command_p *cmd = priv; +} + static void command_set_args( struct bshell_command_p *cmd, fx_value *args, @@ -283,5 +288,6 @@ FX_TYPE_DEFINITION_BEGIN(bshell_command) FX_TYPE_NAME("bshell.runtime.command"); FX_TYPE_CLASS(bshell_command_class); FX_TYPE_INSTANCE_INIT(init); + FX_TYPE_INSTANCE_FINI(fini); FX_TYPE_INSTANCE_PRIVATE(struct bshell_command_p); FX_TYPE_DEFINITION_END(bshell_command) diff --git a/bshell.runtime/command/function.c b/bshell.runtime/command/function.c index e69de29..0d5fa5b 100644 --- a/bshell.runtime/command/function.c +++ b/bshell.runtime/command/function.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct bshell_function_p { + char *func_name; + fx_array *func_positional_params; + bshell_scriptblock *func_body; +}; + +static void init(fx_object *obj, void *priv) +{ + struct bshell_function_p *func_p = priv; + func_p->func_positional_params = fx_array_create(); + func_p->func_body = bshell_scriptblock_create(); +} + +static void fini(fx_object *obj, void *priv) +{ + struct bshell_function_p *func_p = priv; + if (func_p->func_name) { + free(func_p->func_name); + } + + fx_array_unref(func_p->func_positional_params); + bshell_scriptblock_unref(func_p->func_body); +} + +static enum bshell_status get_callable_name( + const bshell_function *func, + fx_string *out) +{ + struct bshell_function_p *func_p + = fx_object_get_private(func, BSHELL_TYPE_FUNCTION); + fx_string_append_cstrf(out, "%s", func_p->func_name); + return BSHELL_SUCCESS; +} + +static enum bshell_status begin_processing(bshell_command *cmd) +{ + return BSHELL_SUCCESS; +} + +static enum bshell_status process_record( + bshell_command *cmd, + bshell_pipeline *pipeline, + struct bshell_runtime *rt) +{ + struct bshell_function_p *func_p + = fx_object_get_private(cmd, BSHELL_TYPE_FUNCTION); + bshell_runtime_push_scope(rt, func_p->func_body); + + const fx_iterator *param_it + = fx_iterator_begin(func_p->func_positional_params); + size_t i = 1; + fx_foreach(v, param_it) + { + fx_string *param = NULL; + fx_value_get_object(v, ¶m); + + const fx_value *arg = bshell_command_get_arg(cmd, i); + if (!arg) { + break; + } + + bshell_variable *var = bshell_runtime_define_var( + rt, + fx_string_get_cstr(param)); + bshell_variable_set_value(var, *arg); + } + fx_iterator_unref(param_it); +#if 0 + bshell_variable *item = bshell_runtime_define_var(rt, "_"); + bshell_variable_set_value(item, &in); +#endif + + fx_value out = bshell_runtime_eval(rt); + bshell_runtime_pop_scope(rt); + if (fx_value_is_set(&out)) { + bshell_pipeline_write_value(pipeline, out, false); + fx_value_unset(&out); + } + + return BSHELL_SUCCESS; +} + +static enum bshell_status end_processing(bshell_command *cmd) +{ + return BSHELL_SUCCESS; +} + +bshell_function *bshell_function_create(const char *name) +{ + bshell_function *out = fx_object_create(BSHELL_TYPE_FUNCTION); + if (!out) { + return NULL; + } + + struct bshell_function_p *func + = fx_object_get_private(out, BSHELL_TYPE_FUNCTION); + func->func_name = fx_strdup(name); + if (!func->func_name) { + bshell_function_unref(out); + return NULL; + } + + return out; +} + +void bshell_function_add_positional_parameter( + bshell_function *func, + const char *name) +{ + fx_string *str = fx_string_create_from_cstr(name); + if (!str) { + return; + } + + struct bshell_function_p *func_p + = fx_object_get_private(func, BSHELL_TYPE_FUNCTION); + fx_array_push_back( + func_p->func_positional_params, + FX_VALUE_OBJECT(str)); + fx_string_unref(str); +} + +static const char *function_get_name(const struct bshell_function_p *func) +{ + return func->func_name; +} + +static const fx_array *function_get_positional_parameters( + const struct bshell_function_p *func) +{ + return func->func_positional_params; +} + +static bshell_scriptblock *function_get_body(struct bshell_function_p *func) +{ + return func->func_body; +} + +const char *bshell_function_get_name(const bshell_function *func) +{ + FX_CLASS_DISPATCH_STATIC_0( + BSHELL_TYPE_FUNCTION, + function_get_name, + func); +} + +const fx_array *bshell_function_get_positional_parameters( + const bshell_function *func) +{ + FX_CLASS_DISPATCH_STATIC_0( + BSHELL_TYPE_FUNCTION, + function_get_positional_parameters, + func); +} + +bshell_scriptblock *bshell_function_get_body(bshell_function *func) +{ + FX_CLASS_DISPATCH_STATIC_0( + BSHELL_TYPE_FUNCTION, + function_get_body, + func); +} + +FX_TYPE_CLASS_BEGIN(bshell_function) + FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) + FX_INTERFACE_ENTRY(to_string) = NULL; + FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT) + + FX_TYPE_VTABLE_INTERFACE_BEGIN(bshell_command, BSHELL_TYPE_COMMAND) + FX_INTERFACE_ENTRY(c_command_type) = "Function"; + FX_INTERFACE_ENTRY(c_get_callable_name) = get_callable_name; + FX_INTERFACE_ENTRY(c_begin_processing) = begin_processing; + FX_INTERFACE_ENTRY(c_process_record) = process_record; + FX_INTERFACE_ENTRY(c_end_processing) = end_processing; + FX_TYPE_VTABLE_INTERFACE_END(bshell_command, BSHELL_TYPE_COMMAND) +FX_TYPE_CLASS_END(bshell_function) + +FX_TYPE_DEFINITION_BEGIN(bshell_function) + FX_TYPE_ID(0x041f1918, 0x6155, 0x4cee, 0xbb01, 0xfef2d6aa1bcf); + FX_TYPE_NAME("bshell.runtime.function"); + FX_TYPE_EXTENDS(BSHELL_TYPE_COMMAND); + FX_TYPE_CLASS(bshell_function_class); + FX_TYPE_INSTANCE_INIT(init); + FX_TYPE_INSTANCE_FINI(fini); + FX_TYPE_INSTANCE_PRIVATE(struct bshell_function_p); +FX_TYPE_DEFINITION_END(bshell_function) diff --git a/bshell.runtime/include/bshell/command/function.h b/bshell.runtime/include/bshell/command/function.h index 05d58dc..a5d1da0 100644 --- a/bshell.runtime/include/bshell/command/function.h +++ b/bshell.runtime/include/bshell/command/function.h @@ -1,6 +1,8 @@ #ifndef BSHELL_COMMAND_FUNCTION_H_ #define BSHELL_COMMAND_FUNCTION_H_ +#include +#include #include FX_DECLS_BEGIN; @@ -17,6 +19,14 @@ FX_TYPE_CLASS_DECLARATION_END(bshell_function) extern fx_type_id bshell_function_get_type(void); extern bshell_function *bshell_function_create(const char *name); +extern void bshell_function_add_positional_parameter( + bshell_function *func, + const char *name); + +extern const char *bshell_function_get_name(const bshell_function *func); +extern const fx_array *bshell_function_get_positional_parameters( + const bshell_function *func); +extern bshell_scriptblock *bshell_function_get_body(bshell_function *func); FX_DECLS_END;