diff --git a/bshell.runtime/include/bshell/runtime/runtime.h b/bshell.runtime/include/bshell/runtime/runtime.h index b5c7841..16c6284 100644 --- a/bshell.runtime/include/bshell/runtime/runtime.h +++ b/bshell.runtime/include/bshell/runtime/runtime.h @@ -2,6 +2,7 @@ #define BSHELL_RUNTIME_RUNTIME_H_ #include +#include #include #include #include @@ -32,6 +33,9 @@ extern bshell_variable *bshell_runtime_find_var( extern bshell_variable *bshell_runtime_define_var( struct bshell_runtime *rt, 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( struct bshell_runtime *rt, diff --git a/bshell.runtime/include/bshell/runtime/var.h b/bshell.runtime/include/bshell/runtime/var.h index b79e7ec..5005b3b 100644 --- a/bshell.runtime/include/bshell/runtime/var.h +++ b/bshell.runtime/include/bshell/runtime/var.h @@ -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 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; diff --git a/bshell.runtime/runtime/cmdcall.c b/bshell.runtime/runtime/cmdcall.c index 3871b0a..61fa685 100644 --- a/bshell.runtime/runtime/cmdcall.c +++ b/bshell.runtime/runtime/cmdcall.c @@ -31,6 +31,11 @@ static void cmdcall_fini(fx_object *obj, void *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) { 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); - - if (cmdcall->cmd_target) { - bshell_command_end_processing(cmdcall->cmd_target); - bshell_command_unref(cmdcall->cmd_target); - } } static enum bshell_status cmdcall_push_arg( diff --git a/bshell.runtime/runtime/eval.c b/bshell.runtime/runtime/eval.c index 0979556..7415cbb 100644 --- a/bshell.runtime/runtime/eval.c +++ b/bshell.runtime/runtime/eval.c @@ -241,7 +241,7 @@ static enum bshell_status eval_instruction( pool_value = bshell_scriptblock_get_pool_value( scope->s_block, arg, - FX_TYPE_CSTR); + FX_TYPE_STRING); if (!pool_value) { fprintf(stderr, "RUNTIME: invalid stlocal operand\n"); return BSHELL_ERR_BAD_SYNTAX; @@ -253,7 +253,7 @@ static enum bshell_status eval_instruction( 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); fx_value_unset(&x); break; @@ -314,7 +314,8 @@ static enum bshell_status eval_instruction( bshell_cmdcall *result = bshell_cmdcall_create(); 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); fx_value_unset(&cmd_arg); arg--; @@ -322,6 +323,7 @@ static enum bshell_status eval_instruction( bstatus = bshell_cmdcall_resolve(result, rt); if (bstatus != BSHELL_SUCCESS) { + bshell_cmdcall_unref(result); break; } @@ -422,7 +424,9 @@ fx_value bshell_runtime_eval_global( { enum bshell_status status = BSHELL_SUCCESS; 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( diff --git a/bshell.runtime/runtime/pipeline.c b/bshell.runtime/runtime/pipeline.c index dc41c1b..1edcbec 100644 --- a/bshell.runtime/runtime/pipeline.c +++ b/bshell.runtime/runtime/pipeline.c @@ -26,6 +26,7 @@ static void pipeline_fini(fx_object *obj, void *priv) for (size_t i = 0; i < pipeline->p_cmds.count; i++) { bshell_cmdcall_unref(pipeline->p_cmds.items[i]); } + fx_vector_destroy(pipeline->p_cmds, NULL); if (pipeline->p_in) { fx_array_unref(pipeline->p_in); diff --git a/bshell.runtime/runtime/runtime.c b/bshell.runtime/runtime/runtime.c index 351c2c3..27eef01 100644 --- a/bshell.runtime/runtime/runtime.c +++ b/bshell.runtime/runtime/runtime.c @@ -21,6 +21,10 @@ struct bshell_runtime *bshell_runtime_create(void) 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); free(rt); } @@ -63,6 +67,31 @@ bshell_variable *bshell_runtime_define_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( struct bshell_runtime *rt, const char *callable_name) diff --git a/bshell.runtime/runtime/scope.c b/bshell.runtime/runtime/scope.c index 682a362..b3b0dc2 100644 --- a/bshell.runtime/runtime/scope.c +++ b/bshell.runtime/runtime/scope.c @@ -37,7 +37,14 @@ void runtime_pop_scope(struct bshell_runtime *rt) struct bshell_runtime_scope *scope = 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); free(scope); } @@ -79,7 +86,11 @@ void bshell_runtime_scope_set_block( struct bshell_runtime_scope *scope, 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; bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr); bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool); diff --git a/bshell.runtime/runtime/var-map.c b/bshell.runtime/runtime/var-map.c index 55a3cde..0f5e321 100644 --- a/bshell.runtime/runtime/var-map.c +++ b/bshell.runtime/runtime/var-map.c @@ -1,7 +1,16 @@ #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) { + fx_namemap_cleanup(&map->m_vars, var_entry_cleanup); } 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; } - struct var_map_entry *entry = fx_unbox( - struct var_map_entry, - e, - e_entry); + struct var_map_entry *entry + = fx_unbox(struct var_map_entry, e, e_entry); return entry->e_var; } diff --git a/bshell.runtime/runtime/var.c b/bshell.runtime/runtime/var.c index 0a12868..66b8a7f 100644 --- a/bshell.runtime/runtime/var.c +++ b/bshell.runtime/runtime/var.c @@ -29,10 +29,10 @@ static const fx_value *variable_get_value(const struct bshell_variable_p *var) 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_copy(&var->var_value, value); + var->var_value = fx_value_copy_return(value); } bshell_variable *bshell_variable_create(const char *name) @@ -70,7 +70,7 @@ const fx_value *bshell_variable_get_value(const bshell_variable *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( BSHELL_TYPE_VARIABLE,