forked from arendst/Tasmota
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbe_globallib.c
118 lines (107 loc) · 3.33 KB
/
be_globallib.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/********************************************************************
** Copyright (c) 2018-2021 Guan Wenliang & Stephan Hadinger
** This file is part of the Berry default interpreter.
** [email protected], https://github.com/Skiars/berry
** See Copyright Notice in the LICENSE file or at
** https://github.com/Skiars/berry/blob/master/LICENSE
********************************************************************/
#include "be_object.h"
#include "be_module.h"
#include "be_string.h"
#include "be_vector.h"
#include "be_class.h"
#include "be_debug.h"
#include "be_map.h"
#include "be_vm.h"
#include "be_var.h"
#include <string.h>
#if BE_USE_GLOBAL_MODULE
#define global(vm) ((vm)->gbldesc.global)
static void dump_map_keys(bvm *vm, bmap *map)
{
if (!map) { return; } /* protect agains potential null pointer */
bmapnode *node;
bmapiter iter = be_map_iter();
while ((node = be_map_next(map, &iter)) != NULL) {
if (var_isstr(&node->key)) {
/* 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);
}
}
}
}
static int m_globals(bvm *vm)
{
be_newobject(vm, "list");
dump_map_keys(vm, global(vm).vtab);
be_pop(vm, 1);
be_return(vm);
}
static int m_contains(bvm *vm)
{
int top = be_top(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 >= 0);
be_return(vm);
}
be_return_nil(vm);
}
static int m_findglobal(bvm *vm)
{
int top = be_top(vm);
if (top >= 1 && be_isstring(vm, 1)) {
const char * name = be_tostring(vm, 1);
be_getglobal(vm, name);
be_return(vm);
}
be_return_nil(vm);
}
static int m_setglobal(bvm *vm)
{
int top = be_top(vm);
if (top >= 2 && be_isstring(vm, 1)) {
const char * name = be_tostring(vm, 1);
be_setglobal(vm, name);
}
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);
#else
/* @const_object_info_begin
module global (scope: global, depend: BE_USE_GLOBAL_MODULE) {
(), func(m_globals)
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"
#endif
#endif /* BE_USE_GLOBAL_MODULE */