Tasmota/lib/libesp32/Berry/src/be_var.c
2021-04-12 19:53:35 +02:00

143 lines
3.7 KiB
C

/********************************************************************
** Copyright (c) 2018-2020 Guan Wenliang
** This file is part of the Berry default interpreter.
** skiars@qq.com, https://github.com/Skiars/berry
** See Copyright Notice in the LICENSE file or at
** https://github.com/Skiars/berry/blob/master/LICENSE
********************************************************************/
#include "be_var.h"
#include "be_vm.h"
#include "be_vector.h"
#include "be_string.h"
#include "be_map.h"
#include "be_gc.h"
#define global(vm) ((vm)->gbldesc.global)
#define builtin(vm) ((vm)->gbldesc.builtin)
void be_globalvar_init(bvm *vm)
{
global(vm).vtab = be_map_new(vm);
be_gc_fix(vm, gc_object(global(vm).vtab));
be_vector_init(vm, &global(vm).vlist, sizeof(bvalue));
#if !BE_USE_PRECOMPILED_OBJECT
builtin(vm).vtab = be_map_new(vm);
be_vector_init(vm, &builtin(vm).vlist, sizeof(bvalue));
be_gc_fix(vm, gc_object(builtin(vm).vtab));
#endif
}
void be_globalvar_deinit(bvm *vm)
{
global(vm).vtab = NULL;
be_vector_delete(vm, &global(vm).vlist);
#if !BE_USE_PRECOMPILED_OBJECT
builtin(vm).vtab = NULL;
be_vector_delete(vm, &builtin(vm).vlist);
#endif
}
static int global_find(bvm *vm, bstring *name)
{
bvalue *res = be_map_findstr(vm, global(vm).vtab, name);
if (res) {
return var_toidx(res) + be_builtin_count(vm);
}
return -1; /* not found */
}
int be_global_find(bvm *vm, bstring *name)
{
int res = global_find(vm, name);
return res != -1 ? res : be_builtin_find(vm, name);
}
static int global_new_anonymous(bvm *vm)
{
int idx = be_global_count(vm);
/* allocate space for new variables */
be_vector_resize(vm, &global(vm).vlist, idx + 1);
/* set the new variable to nil */
var_setnil((bvalue *)global(vm).vlist.end);
return idx;
}
int be_global_new(bvm *vm, bstring *name)
{
int idx = global_find(vm, name);
if (idx == -1) {
bvalue *desc;
idx = global_new_anonymous(vm);
desc = be_map_insertstr(vm, global(vm).vtab, name, NULL);
var_setint(desc, idx);
idx += be_builtin_count(vm);
}
return idx;
}
bvalue* be_global_var(bvm *vm, int index)
{
int bcnt = be_builtin_count(vm);
if (index < bcnt) {
return be_vector_at(&builtin(vm).vlist, index);
}
index -= bcnt;
return be_vector_at(&global(vm).vlist, index);
}
void be_global_release_space(bvm *vm)
{
be_map_release(vm, global(vm).vtab);
be_vector_release(vm, &global(vm).vlist);
}
int be_builtin_find(bvm *vm, bstring *name)
{
bvalue *res = be_map_findstr(vm, builtin(vm).vtab, name);
if (res) {
return var_toidx(res);
}
return -1; /* not found */
}
bstring* be_builtin_name(bvm *vm, int index)
{
bmap *map = builtin(vm).vtab;
bmapnode *end, *node = map->slots;
for (end = node + map->size; node < end; ++node) {
if (var_isstr(&node->key) && node->value.v.i == index) {
return node->key.v.s;
}
}
return NULL;
}
#if !BE_USE_PRECOMPILED_OBJECT
int be_builtin_new(bvm *vm, bstring *name)
{
int idx = be_builtin_find(vm, name);
if (idx == -1) {
bvalue *desc;
idx = be_map_count(builtin(vm).vtab);
desc = be_map_insertstr(vm, builtin(vm).vtab, name, NULL);
var_setint(desc, idx);
be_vector_resize(vm, &builtin(vm).vlist, idx + 1);
/* set the new variable to nil */
var_setnil((bvalue*)(builtin(vm).vlist.end));
}
return idx;
}
void be_bulitin_release_space(bvm *vm)
{
be_map_release(vm, builtin(vm).vtab);
be_vector_release(vm, &builtin(vm).vlist);
}
#else
void be_const_builtin_set(bvm *vm, const bmap *map, const bvector *vec)
{
builtin(vm).vtab = cast(bmap*, map);
builtin(vm).vlist = *vec;
}
#endif