2026-05-17 15:34:24 +01:00
|
|
|
#include "scope.h"
|
|
|
|
|
|
2026-05-25 10:33:29 +01:00
|
|
|
#include <bshell/runtime/runtime.h>
|
2026-05-17 15:34:24 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
struct bshell_runtime *bshell_runtime_create(void)
|
|
|
|
|
{
|
|
|
|
|
struct bshell_runtime *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
|
|
|
|
out->rt_global = runtime_push_scope(out, RUNTIME_SCOPE_GLOBAL, NULL);
|
2026-05-24 20:22:05 +01:00
|
|
|
out->rt_aliases = fx_hashtable_create();
|
2026-05-17 15:34:24 +01:00
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void bshell_runtime_destroy(struct bshell_runtime *rt)
|
|
|
|
|
{
|
2026-05-24 20:22:05 +01:00
|
|
|
fx_hashtable_unref(rt->rt_aliases);
|
2026-05-17 15:34:24 +01:00
|
|
|
free(rt);
|
|
|
|
|
}
|
2026-05-24 20:22:05 +01:00
|
|
|
|
|
|
|
|
bshell_variable *bshell_runtime_find_var(
|
|
|
|
|
struct bshell_runtime *rt,
|
|
|
|
|
const char *name)
|
|
|
|
|
{
|
|
|
|
|
bshell_variable *var = NULL;
|
|
|
|
|
fx_queue_entry *cur = fx_queue_last(&rt->rt_scope);
|
|
|
|
|
while (cur) {
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_runtime_scope *scope
|
|
|
|
|
= fx_unbox(struct bshell_runtime_scope, cur, s_entry);
|
2026-05-24 20:22:05 +01:00
|
|
|
var = var_map_get(&scope->s_vars, name);
|
|
|
|
|
if (var) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cur = fx_queue_prev(cur);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return var;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bshell_variable *bshell_runtime_define_var(
|
|
|
|
|
struct bshell_runtime *rt,
|
|
|
|
|
const char *name)
|
|
|
|
|
{
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_runtime_scope *scope = runtime_get_scope(rt);
|
2026-05-24 20:22:05 +01:00
|
|
|
if (!scope) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bshell_variable *var = bshell_variable_create(name);
|
|
|
|
|
if (!var) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var_map_put(&scope->s_vars, var);
|
|
|
|
|
return var;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bshell_command *bshell_runtime_find_command(
|
|
|
|
|
struct bshell_runtime *rt,
|
|
|
|
|
const char *callable_name)
|
|
|
|
|
{
|
|
|
|
|
bshell_command *alias = NULL, *func = NULL;
|
2026-05-25 10:33:29 +01:00
|
|
|
const fx_value *alias_v
|
|
|
|
|
= fx_hashtable_get(rt->rt_aliases, &FX_CSTR(callable_name));
|
2026-05-24 20:22:05 +01:00
|
|
|
if (alias_v) {
|
|
|
|
|
fx_value_get_object(alias_v, &alias);
|
|
|
|
|
bshell_command_ref(alias);
|
|
|
|
|
return alias;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fx_queue_entry *cur = fx_queue_last(&rt->rt_scope);
|
|
|
|
|
while (cur) {
|
2026-05-25 10:33:29 +01:00
|
|
|
struct bshell_runtime_scope *scope
|
|
|
|
|
= fx_unbox(struct bshell_runtime_scope, cur, s_entry);
|
2026-05-24 20:22:05 +01:00
|
|
|
const fx_value *func_v = fx_hashtable_get(
|
|
|
|
|
scope->s_functions,
|
|
|
|
|
&FX_CSTR(callable_name));
|
|
|
|
|
if (func_v) {
|
|
|
|
|
fx_value_get_object(func_v, &func);
|
|
|
|
|
bshell_command_ref(func);
|
|
|
|
|
return func;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cur = fx_queue_prev(cur);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bshell_command *cmd = bshell_command_find_static(callable_name);
|
|
|
|
|
if (cmd) {
|
|
|
|
|
return cmd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO find native executables */
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2026-05-25 10:33:29 +01:00
|
|
|
|
|
|
|
|
struct bshell_runtime_scope *bshell_runtime_get_current_scope(
|
|
|
|
|
struct bshell_runtime *rt)
|
|
|
|
|
{
|
|
|
|
|
return runtime_get_scope(rt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct bshell_runtime_scope *bshell_runtime_get_parent_scope(
|
|
|
|
|
struct bshell_runtime *rt,
|
|
|
|
|
struct bshell_runtime_scope *scope)
|
|
|
|
|
{
|
|
|
|
|
fx_queue_entry *parent = fx_queue_prev(&scope->s_entry);
|
|
|
|
|
return fx_unbox(struct bshell_runtime_scope, parent, s_entry);
|
|
|
|
|
}
|