mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 03:06:33 +00:00
Berry 'global.undef()' to undefine a global variable (#23073)
This commit is contained in:
parent
e92e411040
commit
9a98db9773
@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Allow acl in mqtt when client certificate is in use with `#define USE_MQTT_CLIENT_CERT` (#22998)
|
||||
- Berry `tasmota.when_network_up()` and simplified Matter using it (#23057)
|
||||
- Berry `introspect.solidified()` to know if a Berry object is solidified or in RAM (#23063)
|
||||
- Berry `global.undef()` to undefine a global variable
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
|
@ -82,8 +82,8 @@ BERRY_API void be_regfunc(bvm *vm, const char *name, bntvfunc f)
|
||||
bstring *s = be_newstr(vm, name);
|
||||
#if !BE_USE_PRECOMPILED_OBJECT
|
||||
int idx = be_builtin_find(vm, s);
|
||||
be_assert(idx == -1);
|
||||
if (idx == -1) { /* new function */
|
||||
be_assert(idx < 0);
|
||||
if (idx < 0) { /* new function */
|
||||
idx = be_builtin_new(vm, s);
|
||||
#else
|
||||
int idx = be_global_find(vm, s);
|
||||
@ -102,8 +102,8 @@ BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib)
|
||||
bstring *s = be_newstr(vm, name);
|
||||
#if !BE_USE_PRECOMPILED_OBJECT
|
||||
int idx = be_builtin_find(vm, s);
|
||||
be_assert(idx == -1);
|
||||
if (idx == -1) { /* new function */
|
||||
be_assert(idx < 0);
|
||||
if (idx < 0) { /* new function */
|
||||
idx = be_builtin_new(vm, s);
|
||||
#else
|
||||
int idx = be_global_find(vm, s);
|
||||
@ -599,7 +599,7 @@ BERRY_API bbool be_getglobal(bvm *vm, const char *name)
|
||||
{
|
||||
int idx = be_global_find(vm, be_newstr(vm, name));
|
||||
bvalue *top = be_incrtop(vm);
|
||||
if (idx > -1) {
|
||||
if (idx >= 0) {
|
||||
*top = *be_global_var(vm, idx);
|
||||
return btrue;
|
||||
}
|
||||
|
@ -27,10 +27,14 @@ static void dump_map_keys(bvm *vm, bmap *map)
|
||||
bmapiter iter = be_map_iter();
|
||||
while ((node = be_map_next(map, &iter)) != NULL) {
|
||||
if (var_isstr(&node->key)) {
|
||||
bstring *s = var_tostr(&node->key);
|
||||
be_pushstring(vm, str(s));
|
||||
be_data_push(vm, -2);
|
||||
be_pop(vm, 1);
|
||||
/* check if the global was not undefined/removed */
|
||||
int idx = var_toidx(&node->value);
|
||||
if (idx >= 0) { /* the key is present in global, and the index is valid */
|
||||
bstring *s = var_tostr(&node->key);
|
||||
be_pushstring(vm, str(s));
|
||||
be_data_push(vm, -2);
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,7 +53,7 @@ static int m_contains(bvm *vm)
|
||||
if (top >= 1 && be_isstring(vm, 1)) {
|
||||
const char * name = be_tostring(vm, 1);
|
||||
int idx = be_global_find(vm, be_newstr(vm, name));
|
||||
be_pushbool(vm, idx > -1);
|
||||
be_pushbool(vm, idx >= 0);
|
||||
be_return(vm);
|
||||
}
|
||||
be_return_nil(vm);
|
||||
@ -76,12 +80,25 @@ static int m_setglobal(bvm *vm)
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
/* Remove a global variable from global scope */
|
||||
/* Internally the global name cannot be removed but it's value is replaced with BE_NONE */
|
||||
/* and global function pretend that BE_NONE is equivalent to the name being absent */
|
||||
static int m_undef(bvm *vm)
|
||||
{
|
||||
int top = be_top(vm);
|
||||
if (top >= 1 && be_isstring(vm, 1)) {
|
||||
be_global_undef(vm, be_newstr(vm, be_tostring(vm, 1)));
|
||||
}
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
#if !BE_USE_PRECOMPILED_OBJECT
|
||||
be_native_module_attr_table(global) {
|
||||
be_native_module_function("()", m_globals),
|
||||
be_native_module_function("contains", m_contains),
|
||||
be_native_module_function("member", m_findglobal),
|
||||
be_native_module_function("setmember", m_setglobal),
|
||||
be_native_module_function("undef", m_undef),
|
||||
};
|
||||
|
||||
be_define_native_module(global, NULL);
|
||||
@ -92,6 +109,7 @@ module global (scope: global, depend: BE_USE_GLOBAL_MODULE) {
|
||||
contains, func(m_contains)
|
||||
member, func(m_findglobal)
|
||||
setmember, func(m_setglobal)
|
||||
undef, func(m_undef)
|
||||
}
|
||||
@const_object_info_end */
|
||||
#include "../generate/be_fixed_global.h"
|
||||
|
@ -67,19 +67,39 @@ 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);
|
||||
int idx = var_toidx(res);
|
||||
if (idx >= 0) {
|
||||
return idx + be_builtin_count(vm);
|
||||
} else {
|
||||
return idx; /* the global does not exist (-1) or was underfined (< -1)*/
|
||||
}
|
||||
}
|
||||
return -1; /* not found */
|
||||
}
|
||||
|
||||
bbool be_global_undef(bvm *vm, bstring *name)
|
||||
{
|
||||
int idx = global_find(vm, name);
|
||||
if (idx >= 0) {
|
||||
bvalue *desc = be_map_findstr(vm, global(vm).vtab, name);
|
||||
int index = var_toidx(desc);
|
||||
var_setint(desc, -index - 2); /* negate the index to mark it as undefined */
|
||||
|
||||
bvalue* val = be_vector_at(&global(vm).vlist, index);
|
||||
var_setnil(val);
|
||||
return btrue;
|
||||
}
|
||||
return bfalse;
|
||||
}
|
||||
|
||||
int be_global_find(bvm *vm, bstring *name)
|
||||
{
|
||||
int res = global_find(vm, name);
|
||||
int res = global_find(vm, name); /* returns negative if not found, -1 if does not exist, < -1 if existed but undefined */
|
||||
if (res < 0) {
|
||||
res = be_builtin_find(vm, name);
|
||||
res = be_builtin_find(vm, name); /* returns -1 if not found */
|
||||
}
|
||||
if (res < 0) {
|
||||
res = global_native_class_find(vm, name);
|
||||
res = global_native_class_find(vm, name); /* returns -1 if not found */
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -97,11 +117,18 @@ static int global_new_anonymous(bvm *vm)
|
||||
int be_global_new(bvm *vm, bstring *name)
|
||||
{
|
||||
int idx = global_find(vm, name);
|
||||
if (idx == -1) {
|
||||
if (idx < 0) {
|
||||
bvalue *desc;
|
||||
idx = global_new_anonymous(vm);
|
||||
desc = be_map_insertstr(vm, global(vm).vtab, name, NULL);
|
||||
var_setint(desc, idx);
|
||||
if (idx == -1) {
|
||||
idx = global_new_anonymous(vm);
|
||||
desc = be_map_insertstr(vm, global(vm).vtab, name, NULL);
|
||||
var_setint(desc, idx);
|
||||
} else {
|
||||
/* the global exists but was undefined */
|
||||
idx = -idx - 2;
|
||||
desc = be_map_findstr(vm, global(vm).vtab, name);
|
||||
var_setint(desc, idx);
|
||||
}
|
||||
idx += be_builtin_count(vm);
|
||||
}
|
||||
return idx;
|
||||
|
@ -20,6 +20,7 @@ void be_globalvar_init(bvm *vm);
|
||||
void be_globalvar_deinit(bvm *vm);
|
||||
int be_global_find(bvm *vm, bstring *name);
|
||||
int be_global_new(bvm *vm, bstring *name);
|
||||
bbool be_global_undef(bvm *vm, bstring *name);
|
||||
bvalue* be_global_var(bvm *vm, int index);
|
||||
void be_global_release_space(bvm *vm);
|
||||
int be_builtin_find(bvm *vm, bstring *name);
|
||||
|
@ -591,7 +591,7 @@ newframe: /* a new call frame */
|
||||
if (var_isstr(b)) {
|
||||
bstring *name = var_tostr(b);
|
||||
int idx = be_global_find(vm, name);
|
||||
if (idx > -1) {
|
||||
if (idx >= 0) {
|
||||
*v = *be_global_var(vm, idx);
|
||||
} else {
|
||||
vm_error(vm, "attribute_error", "'%s' undeclared", str(name));
|
||||
|
Loading…
x
Reference in New Issue
Block a user