Compare commits

..

9 Commits

Author SHA1 Message Date
wash 1710f705e9 command: implement callable bytecode functions 2026-05-30 19:52:50 +01:00
wash 96bf76aabc runtime: fix memory leaks 2026-05-30 19:52:36 +01:00
wash 26b368a512 compile: fix memory leaks 2026-05-30 19:52:24 +01:00
wash a30e76e525 scriptblock: fix memory leaks 2026-05-30 19:51:52 +01:00
wash 3b39f794f9 verb: fix memory leaks 2026-05-30 19:51:29 +01:00
wash 5d6f2a5ce8 parse: lex: fix memory leaks 2026-05-30 19:50:38 +01:00
wash fec3be2140 ast: implement cleanup callbacks 2026-05-30 19:50:13 +01:00
wash f2e1d89313 runtime: update iterator usage 2026-05-25 19:14:52 +01:00
wash 6bfe3f0a6e core: update iterator usage 2026-05-25 19:14:45 +01:00
35 changed files with 520 additions and 129 deletions
+11 -10
View File
@@ -40,13 +40,13 @@ static enum bshell_status process_record(
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
fx_iterator *aliases = fx_iterator_begin(rt->rt_aliases); const fx_iterator *aliases = fx_iterator_begin(rt->rt_aliases);
fx_foreach(item_v, aliases) fx_foreach(item_v, aliases)
{ {
fx_hashtable_item *item; fx_hashtable_item *item;
fx_value_get_object(&item_v, &item); fx_value_get_object(item_v, &item);
fx_value alias_v = fx_hashtable_item_get_value(item); const fx_value *alias_v = fx_hashtable_item_get_value(item);
bshell_pipeline_write_value(pipeline, alias_v, false); bshell_pipeline_write_value(pipeline, *alias_v, false);
} }
fx_iterator_unref(aliases); fx_iterator_unref(aliases);
@@ -55,13 +55,14 @@ static enum bshell_status process_record(
while (scope) { while (scope) {
fx_hashtable *function_map fx_hashtable *function_map
= bshell_runtime_scope_get_functions(scope); = bshell_runtime_scope_get_functions(scope);
fx_iterator *functions = fx_iterator_begin(function_map); const fx_iterator *functions = fx_iterator_begin(function_map);
fx_foreach(item_v, functions) fx_foreach(item_v, functions)
{ {
fx_hashtable_item *item; fx_hashtable_item *item;
fx_value_get_object(&item_v, &item); fx_value_get_object(item_v, &item);
fx_value func_v = fx_hashtable_item_get_value(item); const fx_value *func_v
bshell_pipeline_write_value(pipeline, func_v, false); = fx_hashtable_item_get_value(item);
bshell_pipeline_write_value(pipeline, *func_v, false);
} }
fx_iterator_unref(functions); fx_iterator_unref(functions);
@@ -72,12 +73,12 @@ static enum bshell_status process_record(
fx_foreach(asm_v, assemblies) fx_foreach(asm_v, assemblies)
{ {
fx_assembly *assembly = NULL; fx_assembly *assembly = NULL;
fx_value_get_object(&asm_v, &assembly); fx_value_get_object(asm_v, &assembly);
fx_iterator *types = fx_assembly_get_types(assembly); fx_iterator *types = fx_assembly_get_types(assembly);
fx_foreach(v, types) fx_foreach(v, types)
{ {
fx_type *ty = NULL; fx_type *ty = NULL;
fx_value_get_object(&v, &ty); fx_value_get_object(v, &ty);
fx_type_flags ty_flags = fx_type_get_flags(ty); fx_type_flags ty_flags = fx_type_get_flags(ty);
bool is_abstract = (ty_flags & FX_TYPE_F_ABSTRACT) != 0; bool is_abstract = (ty_flags & FX_TYPE_F_ABSTRACT) != 0;
if (is_abstract) { if (is_abstract) {
+6 -6
View File
@@ -17,7 +17,7 @@ FX_TYPE_CLASS_DECLARATION_END(bshell_get_verb)
struct bshell_get_verb_p { struct bshell_get_verb_p {
fx_hashtable *c_verbs; fx_hashtable *c_verbs;
fx_iterator *c_it; const fx_iterator *c_it;
}; };
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet) static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
@@ -38,18 +38,18 @@ static enum bshell_status process_record(
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_VERB); = fx_object_get_private(cmdlet, BSHELL_TYPE_GET_VERB);
do { do {
fx_value v = fx_iterator_get_value(p->c_it); const fx_value *v = fx_iterator_get_value(p->c_it);
if (!v.v_type) { if (!v) {
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
fx_hashtable_item *item = NULL; fx_hashtable_item *item = NULL;
fx_value_get_object(&v, &item); fx_value_get_object(v, &item);
v = fx_hashtable_item_get_value(item); v = fx_hashtable_item_get_value(item);
bshell_verb *verb = NULL; bshell_verb *verb = NULL;
fx_value_get_object(&v, &verb); fx_value_get_object(v, &verb);
fx_iterator_move_next(p->c_it); fx_iterator_move_next(p->c_it);
if (bshell_verb_is_reserved(verb)) { if (bshell_verb_is_reserved(verb)) {
@@ -59,7 +59,7 @@ static enum bshell_status process_record(
bshell_verb_ref(verb); bshell_verb_ref(verb);
bshell_pipeline_write_value( bshell_pipeline_write_value(
pipeline, pipeline,
fx_value_copy_return(fx_hashtable_item_get_value(item)), fx_value_ref_copy_return(v),
false); false);
break; break;
} while (1); } while (1);
+8 -18
View File
@@ -154,10 +154,8 @@ struct bshell_ast_node *bshell_ast_iterator_dequeue(
return NULL; return NULL;
} }
struct bshell_ast_node *node = fx_unbox( struct bshell_ast_node *node
struct bshell_ast_node, = fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
cur,
n_it.e_entry);
const struct bshell_ast_node_definition *def const struct bshell_ast_node_definition *def
= bshell_ast_node_definitions[node->n_type]; = bshell_ast_node_definitions[node->n_type];
@@ -178,10 +176,8 @@ void bshell_ast_iterator_enqueue(
fx_queue_entry *cur = fx_queue_first(&it->it_queue); fx_queue_entry *cur = fx_queue_first(&it->it_queue);
if (cur) { if (cur) {
struct bshell_ast_node *cur_node = fx_unbox( struct bshell_ast_node *cur_node
struct bshell_ast_node, = fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
cur,
n_it.e_entry);
new_depth = cur_node->n_it.e_depth + 1; new_depth = cur_node->n_it.e_depth + 1;
} }
@@ -222,11 +218,8 @@ enum bshell_status bshell_ast_node_iterate(
return BSHELL_ERR_INTERNAL_FAILURE; return BSHELL_ERR_INTERNAL_FAILURE;
} }
struct bshell_ast_iterate_result result = callback( struct bshell_ast_iterate_result result
node, = callback(node, BSHELL_AST_ITERATION_PRE, it, arg);
BSHELL_AST_ITERATION_PRE,
it,
arg);
if (result.r_status != BSHELL_SUCCESS if (result.r_status != BSHELL_SUCCESS
|| result.r_flags & BSHELL_AST_ITERATE_STOP) { || result.r_flags & BSHELL_AST_ITERATE_STOP) {
return result.r_status; return result.r_status;
@@ -258,11 +251,8 @@ enum bshell_status bshell_ast_node_iterate(
return BSHELL_ERR_INTERNAL_FAILURE; return BSHELL_ERR_INTERNAL_FAILURE;
} }
struct bshell_ast_iterate_result result = callback( struct bshell_ast_iterate_result result
node, = callback(node, BSHELL_AST_ITERATION_POST, it, arg);
BSHELL_AST_ITERATION_POST,
it,
arg);
if (result.r_status != BSHELL_SUCCESS if (result.r_status != BSHELL_SUCCESS
|| result.r_flags & BSHELL_AST_ITERATE_STOP) { || result.r_flags & BSHELL_AST_ITERATE_STOP) {
return result.r_status; return result.r_status;
+11 -2
View File
@@ -4,13 +4,22 @@
static void to_string(const struct bshell_ast_node *node, fx_bstr *out) static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{ {
struct bshell_double_ast_node *i = (struct bshell_double_ast_node *) struct bshell_double_ast_node *i
node; = (struct bshell_double_ast_node *)node;
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL); fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_double_ast_node *d
= (struct bshell_double_ast_node *)node;
bshell_lex_token_destroy(d->n_value);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition double_bshell_ast_node = { struct bshell_ast_node_definition double_bshell_ast_node = {
.def_id = BSHELL_AST_DOUBLE, .def_id = BSHELL_AST_DOUBLE,
.def_node_size = sizeof(struct bshell_double_ast_node), .def_node_size = sizeof(struct bshell_double_ast_node),
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+12 -6
View File
@@ -9,10 +9,8 @@ static enum bshell_status collect_children(
fx_queue_entry *cur = fx_queue_first(&func->n_params); fx_queue_entry *cur = fx_queue_first(&func->n_params);
while (cur) { while (cur) {
struct bshell_ast_node *child = fx_unbox( struct bshell_ast_node *child
struct bshell_ast_node, = fx_unbox(struct bshell_ast_node, cur, n_entry);
cur,
n_entry);
bshell_ast_iterator_enqueue(it, child); bshell_ast_iterator_enqueue(it, child);
cur = fx_queue_next(cur); cur = fx_queue_next(cur);
} }
@@ -26,14 +24,22 @@ static enum bshell_status collect_children(
static void to_string(const struct bshell_ast_node *node, fx_bstr *out) static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{ {
const struct bshell_func_ast_node *func = (const struct const struct bshell_func_ast_node *func
bshell_func_ast_node *)node; = (const struct bshell_func_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", func->n_name->tok_str); fx_bstr_write_fmt(out, NULL, "%s", func->n_name->tok_str);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_func_ast_node *d = (struct bshell_func_ast_node *)node;
bshell_lex_token_destroy(d->n_name);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition func_bshell_ast_node = { struct bshell_ast_node_definition func_bshell_ast_node = {
.def_id = BSHELL_AST_FUNC, .def_id = BSHELL_AST_FUNC,
.def_node_size = sizeof(struct bshell_func_ast_node), .def_node_size = sizeof(struct bshell_func_ast_node),
.def_collect_children = collect_children, .def_collect_children = collect_children,
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+8
View File
@@ -8,8 +8,16 @@ static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL); fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_int_ast_node *i = (struct bshell_int_ast_node *)node;
bshell_lex_token_destroy(i->n_value);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition int_bshell_ast_node = { struct bshell_ast_node_definition int_bshell_ast_node = {
.def_id = BSHELL_AST_INT, .def_id = BSHELL_AST_INT,
.def_node_size = sizeof(struct bshell_int_ast_node), .def_node_size = sizeof(struct bshell_int_ast_node),
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+12
View File
@@ -1,4 +1,5 @@
#include <bshell/ast.h> #include <bshell/ast.h>
#include <bshell/parse/lex.h>
static enum bshell_status collect_children( static enum bshell_status collect_children(
struct bshell_ast_node *node, struct bshell_ast_node *node,
@@ -41,9 +42,20 @@ static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
} }
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_redirection_ast_node *v
= (struct bshell_redirection_ast_node *)node;
if (v->n_out_tok) {
bshell_lex_token_destroy(v->n_out_tok);
}
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition redirection_bshell_ast_node = { struct bshell_ast_node_definition redirection_bshell_ast_node = {
.def_id = BSHELL_AST_REDIRECTION, .def_id = BSHELL_AST_REDIRECTION,
.def_node_size = sizeof(struct bshell_redirection_ast_node), .def_node_size = sizeof(struct bshell_redirection_ast_node),
.def_collect_children = collect_children, .def_collect_children = collect_children,
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+11 -3
View File
@@ -3,14 +3,22 @@
static void to_string(const struct bshell_ast_node *node, fx_bstr *out) static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{ {
const struct bshell_string_ast_node *string = (const struct const struct bshell_string_ast_node *string
bshell_string_ast_node *) = (const struct bshell_string_ast_node *)node;
node;
fx_bstr_write_fmt(out, NULL, "%s", string->n_value->tok_str); fx_bstr_write_fmt(out, NULL, "%s", string->n_value->tok_str);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_string_ast_node *string
= (struct bshell_string_ast_node *)node;
bshell_lex_token_destroy(string->n_value);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition string_bshell_ast_node = { struct bshell_ast_node_definition string_bshell_ast_node = {
.def_id = BSHELL_AST_STRING, .def_id = BSHELL_AST_STRING,
.def_node_size = sizeof(struct bshell_string_ast_node), .def_node_size = sizeof(struct bshell_string_ast_node),
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+10 -2
View File
@@ -3,13 +3,21 @@
static void to_string(const struct bshell_ast_node *node, fx_bstr *out) static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{ {
const struct bshell_var_ast_node *var = (const struct const struct bshell_var_ast_node *var
bshell_var_ast_node *)node; = (const struct bshell_var_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", var->n_ident->tok_str); fx_bstr_write_fmt(out, NULL, "%s", var->n_ident->tok_str);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_var_ast_node *v = (struct bshell_var_ast_node *)node;
bshell_lex_token_destroy(v->n_ident);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition var_bshell_ast_node = { struct bshell_ast_node_definition var_bshell_ast_node = {
.def_id = BSHELL_AST_VAR, .def_id = BSHELL_AST_VAR,
.def_node_size = sizeof(struct bshell_var_ast_node), .def_node_size = sizeof(struct bshell_var_ast_node),
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+10 -2
View File
@@ -3,13 +3,21 @@
static void to_string(const struct bshell_ast_node *node, fx_bstr *out) static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
{ {
const struct bshell_word_ast_node *word = (const struct const struct bshell_word_ast_node *word
bshell_word_ast_node *)node; = (const struct bshell_word_ast_node *)node;
fx_bstr_write_fmt(out, NULL, "%s", word->n_value->tok_str); fx_bstr_write_fmt(out, NULL, "%s", word->n_value->tok_str);
} }
static enum bshell_status cleanup(struct bshell_ast_node *node)
{
struct bshell_word_ast_node *w = (struct bshell_word_ast_node *)node;
bshell_lex_token_destroy(w->n_value);
return BSHELL_SUCCESS;
}
struct bshell_ast_node_definition word_bshell_ast_node = { struct bshell_ast_node_definition word_bshell_ast_node = {
.def_id = BSHELL_AST_WORD, .def_id = BSHELL_AST_WORD,
.def_node_size = sizeof(struct bshell_word_ast_node), .def_node_size = sizeof(struct bshell_word_ast_node),
.def_to_string = to_string, .def_to_string = to_string,
.def_cleanup = cleanup,
}; };
+8 -2
View File
@@ -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( static void command_set_args(
struct bshell_command_p *cmd, struct bshell_command_p *cmd,
fx_value *args, fx_value *args,
@@ -156,12 +161,12 @@ bshell_command *bshell_command_find_static(const char *name)
fx_foreach(asm_v, assemblies) fx_foreach(asm_v, assemblies)
{ {
fx_assembly *assembly = NULL; fx_assembly *assembly = NULL;
fx_value_get_object(&asm_v, &assembly); fx_value_get_object(asm_v, &assembly);
fx_iterator *types = fx_assembly_get_types(assembly); fx_iterator *types = fx_assembly_get_types(assembly);
fx_foreach(v, types) fx_foreach(v, types)
{ {
fx_type *ty = NULL; fx_type *ty = NULL;
fx_value_get_object(&v, &ty); fx_value_get_object(v, &ty);
if (fx_type_id_compare( if (fx_type_id_compare(
fx_type_get_id(ty), fx_type_get_id(ty),
BSHELL_TYPE_COMMAND) BSHELL_TYPE_COMMAND)
@@ -283,5 +288,6 @@ FX_TYPE_DEFINITION_BEGIN(bshell_command)
FX_TYPE_NAME("bshell.runtime.command"); FX_TYPE_NAME("bshell.runtime.command");
FX_TYPE_CLASS(bshell_command_class); FX_TYPE_CLASS(bshell_command_class);
FX_TYPE_INSTANCE_INIT(init); FX_TYPE_INSTANCE_INIT(init);
FX_TYPE_INSTANCE_FINI(fini);
FX_TYPE_INSTANCE_PRIVATE(struct bshell_command_p); FX_TYPE_INSTANCE_PRIVATE(struct bshell_command_p);
FX_TYPE_DEFINITION_END(bshell_command) FX_TYPE_DEFINITION_END(bshell_command)
+197
View File
@@ -0,0 +1,197 @@
#include <bshell/command/command.h>
#include <bshell/command/function.h>
#include <bshell/runtime/pipeline.h>
#include <bshell/runtime/runtime.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)
{
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_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)
+10
View File
@@ -32,6 +32,16 @@ enum bshell_status bshell_compile(
} }
status = compile_resolve_labels(&ctx); status = compile_resolve_labels(&ctx);
while (!fx_queue_empty(&ctx.c_state)) {
compile_pop_state(&ctx);
}
while (!fx_queue_empty(&ctx.c_stack)) {
struct compile_value *value = compile_pop_value(&ctx);
compile_value_destroy(value);
}
if (status != BSHELL_SUCCESS) { if (status != BSHELL_SUCCESS) {
return status; return status;
} }
+1
View File
@@ -72,5 +72,6 @@ enum bshell_status compile_expression(
compile_value_destroy(result); compile_value_destroy(result);
} }
compile_pop_state(ctx);
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
+39
View File
@@ -0,0 +1,39 @@
#include <bshell/ast.h>
#include <bshell/compile.h>
#include <bshell/parse/token.h>
#include <bshell/status.h>
enum bshell_status bshell_compile_function(
struct bshell_ast_node *src,
bshell_function **out)
{
struct bshell_func_ast_node *func_ast
= (struct bshell_func_ast_node *)src;
bshell_function *func
= bshell_function_create(func_ast->n_name->tok_str);
if (!func) {
return BSHELL_ERR_NO_MEMORY;
}
fx_queue_entry *cur = fx_queue_first(&func_ast->n_params);
while (cur) {
struct bshell_var_ast_node *var_ast = fx_unbox(
struct bshell_var_ast_node,
cur,
n_base.n_entry);
bshell_function_add_positional_parameter(
func,
var_ast->n_ident->tok_str);
cur = fx_queue_next(cur);
}
bshell_scriptblock *body = bshell_function_get_body(func);
enum bshell_status status = bshell_compile(func_ast->n_body, body);
if (status != BSHELL_SUCCESS) {
bshell_function_unref(func);
return status;
}
*out = func;
return BSHELL_SUCCESS;
}
+2 -6
View File
@@ -14,8 +14,8 @@ struct compile_state *compile_push_state(
return NULL; return NULL;
} }
const struct compile_state_type *state_type = state_types const struct compile_state_type *state_type
[state_type_id]; = state_types[state_type_id];
if (!state_type) { if (!state_type) {
return NULL; return NULL;
} }
@@ -43,10 +43,6 @@ void compile_pop_state(struct compile_ctx *ctx)
return; return;
} }
if (!fx_queue_prev(&state->s_entry)) {
return;
}
if (state->s_type->s_compile_end) { if (state->s_type->s_compile_end) {
state->s_type->s_compile_end(ctx); state->s_type->s_compile_end(ctx);
} }
+6 -6
View File
@@ -59,7 +59,7 @@ enum bshell_status format_object_table(fx_object *object, fx_stream *dest)
struct bshell_table_ctx ctx; struct bshell_table_ctx ctx;
bshell_table_ctx_init(&ctx, dest); bshell_table_ctx_init(&ctx, dest);
fx_iterator *it = fx_iterator_begin(object); const fx_iterator *it = fx_iterator_begin(object);
if (!it) { if (!it) {
bshell_table_ctx_prepare_columns_from_format( bshell_table_ctx_prepare_columns_from_format(
&ctx, &ctx,
@@ -68,17 +68,17 @@ enum bshell_status format_object_table(fx_object *object, fx_stream *dest)
bshell_table_ctx_print_headers(&ctx); bshell_table_ctx_print_headers(&ctx);
bshell_table_ctx_print_record(&ctx, &FX_VALUE_OBJECT(object)); bshell_table_ctx_print_record(&ctx, &FX_VALUE_OBJECT(object));
} else { } else {
fx_value first = fx_iterator_get_value(it); const fx_value *first = fx_iterator_get_value(it);
if (first.v_type) { if (first) {
bshell_table_ctx_prepare_columns_from_format( bshell_table_ctx_prepare_columns_from_format(
&ctx, &ctx,
fx_type_get_by_id(first.v_type), fx_type_get_by_id(first->v_type),
fmt); fmt);
} }
bshell_table_ctx_print_headers(&ctx); bshell_table_ctx_print_headers(&ctx);
fx_foreach(value, it) fx_foreach(value, it)
{ {
bshell_table_ctx_print_record(&ctx, &value); bshell_table_ctx_print_record(&ctx, value);
} }
} }
@@ -188,7 +188,7 @@ enum bshell_status bshell_table_ctx_prepare_columns_from_object(
fx_iterator *it = fx_type_get_properties(record_type); fx_iterator *it = fx_type_get_properties(record_type);
fx_foreach(prop_v, it) fx_foreach(prop_v, it)
{ {
fx_array_push_back(properties, prop_v); fx_array_push_back(properties, *prop_v);
} }
fx_iterator_unref(it); fx_iterator_unref(it);
@@ -1,6 +1,8 @@
#ifndef BSHELL_COMMAND_FUNCTION_H_ #ifndef BSHELL_COMMAND_FUNCTION_H_
#define BSHELL_COMMAND_FUNCTION_H_ #define BSHELL_COMMAND_FUNCTION_H_
#include <bshell/runtime/script-block.h>
#include <fx/collections/array.h>
#include <fx/macros.h> #include <fx/macros.h>
FX_DECLS_BEGIN; FX_DECLS_BEGIN;
@@ -17,6 +19,14 @@ FX_TYPE_CLASS_DECLARATION_END(bshell_function)
extern fx_type_id bshell_function_get_type(void); extern fx_type_id bshell_function_get_type(void);
extern bshell_function *bshell_function_create(const char *name); 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; FX_DECLS_END;
+4
View File
@@ -1,6 +1,7 @@
#ifndef BSHELL_COMPILE_H_ #ifndef BSHELL_COMPILE_H_
#define BSHELL_COMPILE_H_ #define BSHELL_COMPILE_H_
#include <bshell/command/function.h>
#include <bshell/runtime/script-block.h> #include <bshell/runtime/script-block.h>
struct bshell_ast_node; struct bshell_ast_node;
@@ -8,5 +9,8 @@ struct bshell_ast_node;
extern enum bshell_status bshell_compile( extern enum bshell_status bshell_compile(
struct bshell_ast_node *src, struct bshell_ast_node *src,
bshell_scriptblock *dest); bshell_scriptblock *dest);
extern enum bshell_status bshell_compile_function(
struct bshell_ast_node *src,
bshell_function **out);
#endif #endif
@@ -2,6 +2,7 @@
#define BSHELL_RUNTIME_RUNTIME_H_ #define BSHELL_RUNTIME_RUNTIME_H_
#include <bshell/command/command.h> #include <bshell/command/command.h>
#include <bshell/command/function.h>
#include <bshell/runtime/script-block.h> #include <bshell/runtime/script-block.h>
#include <bshell/runtime/var.h> #include <bshell/runtime/var.h>
#include <fx/collections/hashtable.h> #include <fx/collections/hashtable.h>
@@ -32,6 +33,9 @@ extern bshell_variable *bshell_runtime_find_var(
extern bshell_variable *bshell_runtime_define_var( extern bshell_variable *bshell_runtime_define_var(
struct bshell_runtime *rt, struct bshell_runtime *rt,
const char *name); const char *name);
extern enum bshell_status bshell_runtime_define_function(
struct bshell_runtime *rt,
bshell_function *func);
extern bshell_command *bshell_runtime_find_command( extern bshell_command *bshell_runtime_find_command(
struct bshell_runtime *rt, struct bshell_runtime *rt,
+1 -1
View File
@@ -19,7 +19,7 @@ extern bshell_variable *bshell_variable_create(const char *name);
extern const char *bshell_variable_get_name(const bshell_variable *var); extern const char *bshell_variable_get_name(const bshell_variable *var);
extern const fx_value *bshell_variable_get_value(const bshell_variable *var); extern const fx_value *bshell_variable_get_value(const bshell_variable *var);
extern void bshell_variable_set_value(bshell_variable *var, fx_value *value); extern void bshell_variable_set_value(bshell_variable *var, fx_value value);
FX_DECLS_END; FX_DECLS_END;
+2
View File
@@ -124,6 +124,8 @@ FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_verb)
FX_TYPE_CLASS_DECLARATION_END(bshell_verb) FX_TYPE_CLASS_DECLARATION_END(bshell_verb)
extern enum bshell_status bshell_init_all_verbs(void); extern enum bshell_status bshell_init_all_verbs(void);
extern enum bshell_status bshell_cleanup_all_verbs(void);
extern fx_hashtable *bshell_get_all_verbs(void); extern fx_hashtable *bshell_get_all_verbs(void);
extern bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id); extern bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id);
extern bshell_verb *bshell_verb_get_by_name(const char *name); extern bshell_verb *bshell_verb_get_by_name(const char *name);
+1 -1
View File
@@ -107,7 +107,7 @@ extern struct bshell_lex_state *lex_state_push(
struct bshell_lex_ctx *ctx, struct bshell_lex_ctx *ctx,
enum bshell_lex_state_id state_type, enum bshell_lex_state_id state_type,
enum state_flags flags); enum state_flags flags);
extern void lex_state_pop(struct bshell_lex_ctx *ctx); extern void lex_state_pop(struct bshell_lex_ctx *ctx, bool no_preserve_root);
extern struct bshell_lex_state *lex_state_get(struct bshell_lex_ctx *ctx); extern struct bshell_lex_state *lex_state_get(struct bshell_lex_ctx *ctx);
extern void lex_state_change( extern void lex_state_change(
struct bshell_lex_ctx *ctx, struct bshell_lex_ctx *ctx,
+12 -5
View File
@@ -198,11 +198,14 @@ struct bshell_lex_state *lex_state_push(
return state; return state;
} }
void lex_state_pop(struct bshell_lex_ctx *ctx) void lex_state_pop(struct bshell_lex_ctx *ctx, bool no_preserve_root)
{ {
fx_queue_entry *entry = fx_queue_last(&ctx->lex_state); fx_queue_entry *entry = fx_queue_last(&ctx->lex_state);
if (!entry || !fx_queue_prev(entry)) { if (!entry) {
/* don't pop if this is the root state */ return;
}
if (!no_preserve_root && !fx_queue_prev(entry)) {
return; return;
} }
@@ -451,6 +454,10 @@ enum bshell_status bshell_lex_ctx_cleanup(struct bshell_lex_ctx *ctx)
fx_string_unref(ctx->lex_tmp); fx_string_unref(ctx->lex_tmp);
} }
while (!fx_queue_empty(&ctx->lex_state)) {
lex_state_pop(ctx, true);
}
memset(ctx, 0x0, sizeof *ctx); memset(ctx, 0x0, sizeof *ctx);
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
@@ -1228,7 +1235,7 @@ static bool do_lex_state_transition(
if (!recursive) { if (!recursive) {
for (unsigned int i = 0; i < state->s_nr_terminators; i++) { for (unsigned int i = 0; i < state->s_nr_terminators; i++) {
if (state->s_terminators[i] == token) { if (state->s_terminators[i] == token) {
lex_state_pop(ctx); lex_state_pop(ctx, false);
return true; return true;
} }
} }
@@ -1275,7 +1282,7 @@ static bool do_lex_state_transition(
const struct bshell_lex_state_link *link = best_matches[i]; const struct bshell_lex_state_link *link = best_matches[i];
switch (link->l_type) { switch (link->l_type) {
case BSHELL_LEX_STATE_LINK_POP: case BSHELL_LEX_STATE_LINK_POP:
lex_state_pop(ctx); lex_state_pop(ctx, false);
result = true; result = true;
break; break;
case BSHELL_LEX_STATE_LINK_PUSH: { case BSHELL_LEX_STATE_LINK_PUSH: {
+7 -5
View File
@@ -21,7 +21,7 @@ static enum bshell_status word_symbol(struct bshell_lex_ctx *ctx)
lex_state_push(ctx, BSHELL_LEX_STATE_STATEMENT, 0); lex_state_push(ctx, BSHELL_LEX_STATE_STATEMENT, 0);
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
case BSHELL_SYM_RIGHT_PAREN: case BSHELL_SYM_RIGHT_PAREN:
lex_state_pop(ctx); lex_state_pop(ctx, false);
status = push_symbol(ctx, sym->id); status = push_symbol(ctx, sym->id);
if (status != BSHELL_SUCCESS) { if (status != BSHELL_SUCCESS) {
@@ -92,7 +92,8 @@ static enum bshell_status word_content(struct bshell_lex_ctx *ctx)
static enum bshell_status word_begin(struct bshell_lex_ctx *ctx) static enum bshell_status word_begin(struct bshell_lex_ctx *ctx)
{ {
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_WORD_START); struct bshell_lex_token *tok
= bshell_lex_token_create(BSHELL_TOK_WORD_START);
if (!tok) { if (!tok) {
return BSHELL_ERR_NO_MEMORY; return BSHELL_ERR_NO_MEMORY;
} }
@@ -107,7 +108,8 @@ static enum bshell_status word_begin(struct bshell_lex_ctx *ctx)
static enum bshell_status word_end(struct bshell_lex_ctx *ctx) static enum bshell_status word_end(struct bshell_lex_ctx *ctx)
{ {
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_WORD_END); struct bshell_lex_token *tok
= bshell_lex_token_create(BSHELL_TOK_WORD_END);
if (!tok) { if (!tok) {
return BSHELL_ERR_NO_MEMORY; return BSHELL_ERR_NO_MEMORY;
} }
@@ -121,12 +123,12 @@ static enum bshell_status word_pump_token(struct bshell_lex_ctx *ctx)
fx_wchar c = peek_char(ctx); fx_wchar c = peek_char(ctx);
if (fx_wchar_is_space(c)) { if (fx_wchar_is_space(c)) {
lex_state_pop(ctx); lex_state_pop(ctx, false);
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
if (char_has_flags(ctx, c, BSHELL_LEX_TOKEN_TERMINATES_WORD)) { if (char_has_flags(ctx, c, BSHELL_LEX_TOKEN_TERMINATES_WORD)) {
lex_state_pop(ctx); lex_state_pop(ctx, false);
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
+2
View File
@@ -41,6 +41,8 @@ void bshell_lex_token_destroy(struct bshell_lex_token *tok)
switch (tok->tok_type) { switch (tok->tok_type) {
case BSHELL_TOK_WORD: case BSHELL_TOK_WORD:
case BSHELL_TOK_FLAG: case BSHELL_TOK_FLAG:
case BSHELL_TOK_VAR:
case BSHELL_TOK_VAR_SPLAT:
case BSHELL_TOK_STRING: case BSHELL_TOK_STRING:
if (tok->tok_str) { if (tok->tok_str) {
free(tok->tok_str); free(tok->tok_str);
+5 -5
View File
@@ -31,6 +31,11 @@ static void cmdcall_fini(fx_object *obj, void *priv)
{ {
struct bshell_cmdcall_p *cmdcall = priv; struct bshell_cmdcall_p *cmdcall = priv;
if (cmdcall->cmd_target) {
bshell_command_end_processing(cmdcall->cmd_target);
bshell_command_unref(cmdcall->cmd_target);
}
if (cmdcall->cmd_native_path) { if (cmdcall->cmd_native_path) {
free(cmdcall->cmd_native_path); free(cmdcall->cmd_native_path);
} }
@@ -44,11 +49,6 @@ static void cmdcall_fini(fx_object *obj, void *priv)
} }
fx_vector_destroy(cmdcall->cmd_args, NULL); fx_vector_destroy(cmdcall->cmd_args, NULL);
if (cmdcall->cmd_target) {
bshell_command_end_processing(cmdcall->cmd_target);
bshell_command_unref(cmdcall->cmd_target);
}
} }
static enum bshell_status cmdcall_push_arg( static enum bshell_status cmdcall_push_arg(
+8 -4
View File
@@ -241,7 +241,7 @@ static enum bshell_status eval_instruction(
pool_value = bshell_scriptblock_get_pool_value( pool_value = bshell_scriptblock_get_pool_value(
scope->s_block, scope->s_block,
arg, arg,
FX_TYPE_CSTR); FX_TYPE_STRING);
if (!pool_value) { if (!pool_value) {
fprintf(stderr, "RUNTIME: invalid stlocal operand\n"); fprintf(stderr, "RUNTIME: invalid stlocal operand\n");
return BSHELL_ERR_BAD_SYNTAX; return BSHELL_ERR_BAD_SYNTAX;
@@ -253,7 +253,7 @@ static enum bshell_status eval_instruction(
var = bshell_runtime_define_var(rt, s); var = bshell_runtime_define_var(rt, s);
} }
bshell_variable_set_value(var, &x); bshell_variable_set_value(var, x);
bshell_runtime_scope_push_value(scope, &x); bshell_runtime_scope_push_value(scope, &x);
fx_value_unset(&x); fx_value_unset(&x);
break; break;
@@ -314,7 +314,8 @@ static enum bshell_status eval_instruction(
bshell_cmdcall *result = bshell_cmdcall_create(); bshell_cmdcall *result = bshell_cmdcall_create();
while (arg > 0) { while (arg > 0) {
fx_value cmd_arg = bshell_runtime_scope_pop_value(scope); fx_value cmd_arg
= bshell_runtime_scope_pop_value(scope);
bshell_cmdcall_push_arg(result, cmd_arg); bshell_cmdcall_push_arg(result, cmd_arg);
fx_value_unset(&cmd_arg); fx_value_unset(&cmd_arg);
arg--; arg--;
@@ -322,6 +323,7 @@ static enum bshell_status eval_instruction(
bstatus = bshell_cmdcall_resolve(result, rt); bstatus = bshell_cmdcall_resolve(result, rt);
if (bstatus != BSHELL_SUCCESS) { if (bstatus != BSHELL_SUCCESS) {
bshell_cmdcall_unref(result);
break; break;
} }
@@ -422,7 +424,9 @@ fx_value bshell_runtime_eval_global(
{ {
enum bshell_status status = BSHELL_SUCCESS; enum bshell_status status = BSHELL_SUCCESS;
bshell_runtime_scope_set_block(rt->rt_global, block); bshell_runtime_scope_set_block(rt->rt_global, block);
return runtime_eval(rt); fx_value result = runtime_eval(rt);
bshell_runtime_scope_set_block(rt->rt_global, NULL);
return result;
} }
fx_value bshell_runtime_eval_script( fx_value bshell_runtime_eval_script(
+3 -2
View File
@@ -26,6 +26,7 @@ static void pipeline_fini(fx_object *obj, void *priv)
for (size_t i = 0; i < pipeline->p_cmds.count; i++) { for (size_t i = 0; i < pipeline->p_cmds.count; i++) {
bshell_cmdcall_unref(pipeline->p_cmds.items[i]); bshell_cmdcall_unref(pipeline->p_cmds.items[i]);
} }
fx_vector_destroy(pipeline->p_cmds, NULL);
if (pipeline->p_in) { if (pipeline->p_in) {
fx_array_unref(pipeline->p_in); fx_array_unref(pipeline->p_in);
@@ -56,10 +57,10 @@ static enum bshell_status write_value(
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
fx_iterator *it = fx_iterator_begin(container); const fx_iterator *it = fx_iterator_begin(container);
fx_foreach(v, it) fx_foreach(v, it)
{ {
fx_array_push_back(dest, fx_value_copy_return(v)); fx_array_push_back(dest, fx_value_ref_copy_return(v));
} }
fx_iterator_unref(it); fx_iterator_unref(it);
+29
View File
@@ -21,6 +21,10 @@ struct bshell_runtime *bshell_runtime_create(void)
void bshell_runtime_destroy(struct bshell_runtime *rt) void bshell_runtime_destroy(struct bshell_runtime *rt)
{ {
while (!fx_queue_empty(&rt->rt_scope)) {
runtime_pop_scope(rt);
}
fx_hashtable_unref(rt->rt_aliases); fx_hashtable_unref(rt->rt_aliases);
free(rt); free(rt);
} }
@@ -63,6 +67,31 @@ bshell_variable *bshell_runtime_define_var(
return var; return var;
} }
enum bshell_status bshell_runtime_define_function(
struct bshell_runtime *rt,
bshell_function *func)
{
struct bshell_runtime_scope *scope = runtime_get_scope(rt);
if (!scope) {
return BSHELL_ERR_BAD_STATE;
}
fx_string *name
= fx_string_create_from_cstr(bshell_function_get_name(func));
if (!name) {
return BSHELL_ERR_NO_MEMORY;
}
fx_string_transform_lowercase(name);
fx_hashtable_put(
scope->s_functions,
&FX_VALUE_OBJECT(name),
&FX_VALUE_OBJECT(func));
fx_string_unref(name);
return BSHELL_SUCCESS;
}
bshell_command *bshell_runtime_find_command( bshell_command *bshell_runtime_find_command(
struct bshell_runtime *rt, struct bshell_runtime *rt,
const char *callable_name) const char *callable_name)
+13 -2
View File
@@ -37,7 +37,14 @@ void runtime_pop_scope(struct bshell_runtime *rt)
struct bshell_runtime_scope *scope struct bshell_runtime_scope *scope
= fx_unbox(struct bshell_runtime_scope, entry, s_entry); = fx_unbox(struct bshell_runtime_scope, entry, s_entry);
/* TODO */
if (scope->s_block) {
bshell_scriptblock_unref(scope->s_block);
}
fx_value_unset_array(scope->s_stack.items, scope->s_stack.count);
var_map_cleanup(&scope->s_vars);
fx_vector_destroy(scope->s_stack, NULL);
fx_hashtable_unref(scope->s_functions); fx_hashtable_unref(scope->s_functions);
free(scope); free(scope);
} }
@@ -79,7 +86,11 @@ void bshell_runtime_scope_set_block(
struct bshell_runtime_scope *scope, struct bshell_runtime_scope *scope,
bshell_scriptblock *block) bshell_scriptblock *block)
{ {
scope->s_block = block; if (scope->s_block) {
bshell_scriptblock_unref(scope->s_block);
}
scope->s_block = bshell_scriptblock_ref(block);
scope->s_ip = 0; scope->s_ip = 0;
bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr); bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr);
bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool); bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool);
+11 -4
View File
@@ -1,7 +1,16 @@
#include "var-map.h" #include "var-map.h"
static void var_entry_cleanup(fx_namemap_entry *entry)
{
struct var_map_entry *map_entry
= fx_unbox(struct var_map_entry, entry, e_entry);
bshell_variable_unref(map_entry->e_var);
free(map_entry);
}
void var_map_cleanup(struct var_map *map) void var_map_cleanup(struct var_map *map)
{ {
fx_namemap_cleanup(&map->m_vars, var_entry_cleanup);
} }
enum bshell_status var_map_put(struct var_map *map, bshell_variable *var) enum bshell_status var_map_put(struct var_map *map, bshell_variable *var)
@@ -27,9 +36,7 @@ bshell_variable *var_map_get(struct var_map *map, const char *name)
return NULL; return NULL;
} }
struct var_map_entry *entry = fx_unbox( struct var_map_entry *entry
struct var_map_entry, = fx_unbox(struct var_map_entry, e, e_entry);
e,
e_entry);
return entry->e_var; return entry->e_var;
} }
+3 -3
View File
@@ -29,10 +29,10 @@ static const fx_value *variable_get_value(const struct bshell_variable_p *var)
return &var->var_value; return &var->var_value;
} }
static void variable_set_value(struct bshell_variable_p *var, fx_value *value) static void variable_set_value(struct bshell_variable_p *var, fx_value value)
{ {
fx_value_unset(&var->var_value); fx_value_unset(&var->var_value);
fx_value_copy(&var->var_value, value); var->var_value = fx_value_copy_return(value);
} }
bshell_variable *bshell_variable_create(const char *name) bshell_variable *bshell_variable_create(const char *name)
@@ -70,7 +70,7 @@ const fx_value *bshell_variable_get_value(const bshell_variable *var)
var); var);
} }
void bshell_variable_set_value(bshell_variable *var, fx_value *value) void bshell_variable_set_value(bshell_variable *var, fx_value value)
{ {
FX_CLASS_DISPATCH_STATIC_V( FX_CLASS_DISPATCH_STATIC_V(
BSHELL_TYPE_VARIABLE, BSHELL_TYPE_VARIABLE,
+9 -10
View File
@@ -18,21 +18,20 @@ struct bshell_scriptblock_p {
fx_namemap b_strings; fx_namemap b_strings;
}; };
static fx_status pool_destroy(void *p) static void cache_entry_cleanup(fx_namemap_entry *e)
{ {
fx_value_unset(p); struct string_cache_entry *entry
return FX_SUCCESS; = fx_unbox(struct string_cache_entry, e, e_entry);
free(entry);
} }
static fx_vector_ops pool_ops = {
.v_destroy = pool_destroy,
};
static void scriptblock_fini(fx_object *obj, void *priv) static void scriptblock_fini(fx_object *obj, void *priv)
{ {
struct bshell_scriptblock_p *block = priv; struct bshell_scriptblock_p *block = priv;
fx_vector_destroy(block->b_pool, &pool_ops); fx_namemap_cleanup(&block->b_strings, cache_entry_cleanup);
fx_value_unset_array(block->b_pool.items, block->b_pool.count);
fx_vector_destroy(block->b_pool, NULL);
fx_vector_destroy(block->b_text, NULL); fx_vector_destroy(block->b_text, NULL);
} }
@@ -125,7 +124,7 @@ static unsigned long scriptblock_add_pool_value(
fx_value *value) fx_value *value)
{ {
unsigned long id = block->b_pool.count; unsigned long id = block->b_pool.count;
fx_value *slot = fx_vector_emplace_back(block->b_pool, &pool_ops); fx_value *slot = fx_vector_emplace_back(block->b_pool, NULL);
if (!slot) { if (!slot) {
return (unsigned long)-1; return (unsigned long)-1;
} }
@@ -176,7 +175,7 @@ static unsigned long scriptblock_get_string(
} }
unsigned long index = block->b_pool.count; unsigned long index = block->b_pool.count;
fx_value *slot = fx_vector_emplace_back(block->b_pool, &pool_ops); fx_value *slot = fx_vector_emplace_back(block->b_pool, NULL);
if (!slot) { if (!slot) {
goto cleanup; goto cleanup;
} }
+34 -24
View File
@@ -25,9 +25,8 @@ bshell_verb *bshell_verb_create(
return NULL; return NULL;
} }
struct bshell_verb_p *verb_p = fx_object_get_private( struct bshell_verb_p *verb_p
verb, = fx_object_get_private(verb, BSHELL_TYPE_VERB);
BSHELL_TYPE_VERB);
verb_p->v_id = id; verb_p->v_id = id;
verb_p->v_name = name; verb_p->v_name = name;
@@ -75,9 +74,8 @@ static fx_status get_name(
{ {
bshell_verb *verb = NULL; bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb); fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p = fx_object_get_private( struct bshell_verb_p *verb_p
verb, = fx_object_get_private(verb, BSHELL_TYPE_VERB);
BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_name); *out = FX_CSTR(verb_p->v_name);
return FX_SUCCESS; return FX_SUCCESS;
@@ -90,9 +88,8 @@ static fx_status get_alias_prefix(
{ {
bshell_verb *verb = NULL; bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb); fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p = fx_object_get_private( struct bshell_verb_p *verb_p
verb, = fx_object_get_private(verb, BSHELL_TYPE_VERB);
BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_alias_prefix); *out = FX_CSTR(verb_p->v_alias_prefix);
return FX_SUCCESS; return FX_SUCCESS;
} }
@@ -104,9 +101,8 @@ static fx_status get_group(
{ {
bshell_verb *verb = NULL; bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb); fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p = fx_object_get_private( struct bshell_verb_p *verb_p
verb, = fx_object_get_private(verb, BSHELL_TYPE_VERB);
BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_group); *out = FX_CSTR(verb_p->v_group);
return FX_SUCCESS; return FX_SUCCESS;
} }
@@ -118,13 +114,17 @@ static fx_status get_description(
{ {
bshell_verb *verb = NULL; bshell_verb *verb = NULL;
fx_value_get_object(verb_v, &verb); fx_value_get_object(verb_v, &verb);
struct bshell_verb_p *verb_p = fx_object_get_private( struct bshell_verb_p *verb_p
verb, = fx_object_get_private(verb, BSHELL_TYPE_VERB);
BSHELL_TYPE_VERB);
*out = FX_CSTR(verb_p->v_description); *out = FX_CSTR(verb_p->v_description);
return FX_SUCCESS; return FX_SUCCESS;
} }
static void verb_fini(fx_object *obj, void *priv)
{
struct bshell_verb_p *verb = priv;
}
FX_TYPE_CLASS_BEGIN(bshell_verb) FX_TYPE_CLASS_BEGIN(bshell_verb)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL; FX_INTERFACE_ENTRY(to_string) = NULL;
@@ -143,6 +143,7 @@ FX_TYPE_DEFINITION_BEGIN(bshell_verb)
FX_TYPE_NAME("bshell.verb"); FX_TYPE_NAME("bshell.verb");
FX_TYPE_CLASS(bshell_verb_class); FX_TYPE_CLASS(bshell_verb_class);
FX_TYPE_INSTANCE_PRIVATE(struct bshell_verb_p); FX_TYPE_INSTANCE_PRIVATE(struct bshell_verb_p);
FX_TYPE_INSTANCE_FINI(verb_fini);
FX_TYPE_DEFINITION_END(bshell_verb) FX_TYPE_DEFINITION_END(bshell_verb)
static fx_hashtable *all_verbs_by_name = NULL; static fx_hashtable *all_verbs_by_name = NULL;
@@ -405,18 +406,18 @@ enum bshell_status bshell_init_all_verbs(void)
"dc", "dc",
"Communications", "Communications",
"Breaks the link between a source and a destination"); "Breaks the link between a source and a destination");
PUT_VERB(
READ,
"Read",
"rd",
"Communications",
"Acquires information from a source");
PUT_VERB( PUT_VERB(
RECEIVE, RECEIVE,
"Receive", "Receive",
"rc", "rc",
"Communications", "Communications",
"Accepts information sent from a source"); "Accepts information sent from a source");
PUT_VERB(
READ,
"Read",
"rd",
"Communications",
"Acquires information from a source");
PUT_VERB( PUT_VERB(
SEND, SEND,
"Send", "Send",
@@ -788,6 +789,16 @@ enum bshell_status bshell_init_all_verbs(void)
return BSHELL_SUCCESS; return BSHELL_SUCCESS;
} }
enum bshell_status bshell_cleanup_all_verbs(void)
{
for (size_t i = 0; i < __BSHELL_VERB_MAX; i++) {
all_verbs_by_id[i] = NULL;
}
fx_hashtable_unref(all_verbs_by_name);
return BSHELL_SUCCESS;
}
fx_hashtable *bshell_get_all_verbs(void) fx_hashtable *bshell_get_all_verbs(void)
{ {
return all_verbs_by_name; return all_verbs_by_name;
@@ -804,9 +815,8 @@ bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id)
bshell_verb *bshell_verb_get_by_name(const char *name) bshell_verb *bshell_verb_get_by_name(const char *name)
{ {
const fx_value *val = fx_hashtable_get( const fx_value *val
all_verbs_by_name, = fx_hashtable_get(all_verbs_by_name, &FX_CSTR(name));
&FX_CSTR(name));
if (!val) { if (!val) {
return NULL; return NULL;
} }