136 lines
2.7 KiB
C
136 lines
2.7 KiB
C
#include "scope.h"
|
|
|
|
#include <bshell/runtime/runtime.h>
|
|
#include <fx/vector.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct bshell_runtime_scope *runtime_push_scope(
|
|
struct bshell_runtime *rt,
|
|
enum bshell_runtime_scope_type type,
|
|
bshell_scriptblock *block)
|
|
{
|
|
struct bshell_runtime_scope *out = malloc(sizeof *out);
|
|
if (!out) {
|
|
return NULL;
|
|
}
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
out->s_type = type;
|
|
out->s_functions = fx_hashtable_create();
|
|
|
|
if (block) {
|
|
bshell_runtime_scope_set_block(out, block);
|
|
}
|
|
|
|
fx_queue_push_back(&rt->rt_scope, &out->s_entry);
|
|
return out;
|
|
}
|
|
|
|
void runtime_pop_scope(struct bshell_runtime *rt)
|
|
{
|
|
fx_queue_entry *entry = fx_queue_pop_back(&rt->rt_scope);
|
|
if (!entry) {
|
|
return;
|
|
}
|
|
|
|
struct bshell_runtime_scope *scope
|
|
= fx_unbox(struct bshell_runtime_scope, entry, s_entry);
|
|
|
|
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);
|
|
}
|
|
|
|
struct bshell_runtime_scope *runtime_get_scope(struct bshell_runtime *rt)
|
|
{
|
|
fx_queue_entry *entry = fx_queue_last(&rt->rt_scope);
|
|
if (!entry) {
|
|
return NULL;
|
|
}
|
|
|
|
return fx_unbox(struct bshell_runtime_scope, entry, s_entry);
|
|
}
|
|
|
|
void bshell_runtime_scope_push_value(
|
|
struct bshell_runtime_scope *scope,
|
|
const fx_value *value)
|
|
{
|
|
fx_value *slot = fx_vector_emplace_back(scope->s_stack, NULL);
|
|
if (!slot) {
|
|
return;
|
|
}
|
|
|
|
fx_value_copy(slot, value);
|
|
}
|
|
|
|
fx_value bshell_runtime_scope_pop_value(struct bshell_runtime_scope *scope)
|
|
{
|
|
if (scope->s_stack.count == 0) {
|
|
return FX_VALUE_EMPTY;
|
|
}
|
|
|
|
fx_value v = scope->s_stack.items[scope->s_stack.count - 1];
|
|
fx_vector_pop_back(scope->s_stack, NULL);
|
|
return v;
|
|
}
|
|
|
|
void bshell_runtime_scope_set_block(
|
|
struct bshell_runtime_scope *scope,
|
|
bshell_scriptblock *block)
|
|
{
|
|
if (scope->s_block) {
|
|
bshell_scriptblock_unref(scope->s_block);
|
|
}
|
|
|
|
if (!block) {
|
|
scope->s_block = NULL;
|
|
scope->s_ip = 0;
|
|
scope->s_instr = NULL;
|
|
scope->s_nr_instr = 0;
|
|
scope->s_pool = NULL;
|
|
scope->s_nr_pool = 0;
|
|
} else {
|
|
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);
|
|
}
|
|
}
|
|
|
|
fx_hashtable *bshell_runtime_scope_get_functions(
|
|
struct bshell_runtime_scope *scope)
|
|
{
|
|
return scope->s_functions;
|
|
}
|
|
|
|
bshell_variable *bshell_runtime_scope_define_variable(
|
|
struct bshell_runtime_scope *scope,
|
|
const char *name)
|
|
{
|
|
if (!scope) {
|
|
return NULL;
|
|
}
|
|
|
|
bshell_variable *var = bshell_variable_create(name);
|
|
if (!var) {
|
|
return NULL;
|
|
}
|
|
|
|
var_map_put(&scope->s_vars, var);
|
|
return var;
|
|
}
|