Files

201 lines
5.0 KiB
C

#include <bshell/command/command.h>
#include <bshell/command/function.h>
#include <bshell/runtime/pipeline.h>
#include <bshell/runtime/runtime.h>
#include <bshell/runtime/scope.h>
#include <bshell/runtime/script-block.h>
#include <bshell/status.h>
#include <fx/collections/array.h>
#include <fx/reflection/function.h>
#include <fx/string.h>
#include <fx/vector.h>
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,
enum bshell_command_position position)
{
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, &param);
const fx_value *arg = bshell_command_get_arg(cmd, i);
if (!arg) {
break;
}
bshell_variable *var = bshell_runtime_scope_define_variable(
bshell_runtime_get_current_scope(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)