Berry check non-method

This commit is contained in:
Stephan Hadinger 2022-01-18 22:13:40 +01:00
parent d432b44268
commit cd401d3928
23 changed files with 1651 additions and 1230 deletions

View File

@ -14,6 +14,7 @@ extern const bcstring be_const_str_BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20;
extern const bcstring be_const_str_BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s;
extern const bcstring be_const_str_BRY_X3A_X20could_X20not_X20save_X20compiled_X20file_X20_X25s_X20_X28_X25s_X29;
extern const bcstring be_const_str_BRY_X3A_X20failed_X20to_X20load_X20_persist_X2Ejson;
extern const bcstring be_const_str_BRY_X3A_X20method_X20not_X20allowed_X2C_X20use_X20a_X20closure_X20like_X20_X27_X2F_X20args_X20_X2D_X3E_X20obj_X2Efunc_X28args_X29_X27;
extern const bcstring be_const_str_BUTTON_CONFIGURATION;
extern const bcstring be_const_str_CFG_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s;
extern const bcstring be_const_str_CFG_X3A_X20No_X20_X27_X2A_X2Eautoconf_X27_X20file_X20found;
@ -261,6 +262,7 @@ extern const bcstring be_const_str_cb_obj;
extern const bcstring be_const_str_ceil;
extern const bcstring be_const_str_char;
extern const bcstring be_const_str_chars_in_string;
extern const bcstring be_const_str_check_not_method;
extern const bcstring be_const_str_check_privileged_access;
extern const bcstring be_const_str_class;
extern const bcstring be_const_str_class_init_obj;
@ -451,6 +453,7 @@ extern const bcstring be_const_str_ins_ramp;
extern const bcstring be_const_str_ins_time;
extern const bcstring be_const_str_insert;
extern const bcstring be_const_str_instance;
extern const bcstring be_const_str_instance_X20required;
extern const bcstring be_const_str_instance_size;
extern const bcstring be_const_str_int;
extern const bcstring be_const_str_internal_error;
@ -462,6 +465,7 @@ extern const bcstring be_const_str_is_dirty;
extern const bcstring be_const_str_is_first_time;
extern const bcstring be_const_str_is_running;
extern const bcstring be_const_str_isinstance;
extern const bcstring be_const_str_ismethod;
extern const bcstring be_const_str_isnan;
extern const bcstring be_const_str_isrunning;
extern const bcstring be_const_str_issubclass;
@ -725,6 +729,7 @@ extern const bcstring be_const_str_true;
extern const bcstring be_const_str_try;
extern const bcstring be_const_str_try_rule;
extern const bcstring be_const_str_type;
extern const bcstring be_const_str_type_error;
extern const bcstring be_const_str_udp;
extern const bcstring be_const_str_unknown_X20instruction;
extern const bcstring be_const_str_update;

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,92 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tasmota_map) {
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
{ be_const_key(read_sensors, 20), be_const_func(l_read_sensors) },
{ be_const_key(response_append, 50), be_const_func(l_respAppend) },
{ be_const_key(try_rule, 74), be_const_closure(Tasmota_try_rule_closure) },
{ be_const_key(eth, -1), be_const_func(l_eth) },
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
{ be_const_key(remove_driver, 64), be_const_closure(Tasmota_remove_driver_closure) },
{ be_const_key(load, -1), be_const_closure(Tasmota_load_closure) },
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
{ be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) },
{ be_const_key(_fl, 34), be_const_var(0) },
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
{ be_const_key(global, 73), be_const_var(1) },
{ be_const_key(cmd_res, -1), be_const_var(2) },
{ be_const_key(find_op, 7), be_const_closure(Tasmota_find_op_closure) },
{ be_const_key(get_power, -1), be_const_func(l_getpower) },
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
{ be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) },
{ be_const_key(exec_tele, 71), be_const_closure(Tasmota_exec_tele_closure) },
{ be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
{ be_const_key(remove_cmd, 10), be_const_closure(Tasmota_remove_cmd_closure) },
{ be_const_key(millis, 18), be_const_func(l_millis) },
{ be_const_key(publish, 28), be_const_func(l_publish) },
{ be_const_key(_drivers, -1), be_const_var(3) },
{ be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
{ be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) },
{ be_const_key(response_append, -1), be_const_func(l_respAppend) },
{ be_const_key(resp_cmnd_done, 29), be_const_func(l_respCmndDone) },
{ be_const_key(try_rule, -1), be_const_closure(Tasmota_try_rule_closure) },
{ be_const_key(get_light, 8), be_const_closure(Tasmota_get_light_closure) },
{ be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
{ be_const_key(eth, 76), be_const_func(l_eth) },
{ be_const_key(time_dump, -1), be_const_func(l_time_dump) },
{ be_const_key(delay, 61), be_const_func(l_delay) },
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
{ be_const_key(memory, -1), be_const_func(l_memory) },
{ be_const_key(gen_cb, 0), be_const_closure(Tasmota_gen_cb_closure) },
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
{ be_const_key(chars_in_string, 60), be_const_closure(Tasmota_chars_in_string_closure) },
{ be_const_key(init, -1), be_const_closure(Tasmota_init_closure) },
{ be_const_key(_timers, -1), be_const_var(4) },
{ be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
{ be_const_key(wd, -1), be_const_var(5) },
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
{ be_const_key(_global_def, 58), be_const_comptr(&be_tasmota_global_struct) },
{ be_const_key(resp_cmnd_failed, 15), be_const_func(l_respCmndFailed) },
{ be_const_key(set_timer, 47), be_const_closure(Tasmota_set_timer_closure) },
{ be_const_key(cmd_res, -1), be_const_var(0) },
{ be_const_key(_drivers, 18), be_const_var(1) },
{ be_const_key(find_key_i, -1), be_const_closure(Tasmota_find_key_i_closure) },
{ be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) },
{ be_const_key(load, 9), be_const_closure(Tasmota_load_closure) },
{ be_const_key(set_light, 15), be_const_closure(Tasmota_set_light_closure) },
{ be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) },
{ be_const_key(settings, -1), be_const_var(2) },
{ be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
{ be_const_key(_debug_present, 3), be_const_var(6) },
{ be_const_key(settings, -1), be_const_var(7) },
{ be_const_key(_ccmd, -1), be_const_var(8) },
{ be_const_key(remove_rule, -1), be_const_closure(Tasmota_remove_rule_closure) },
{ be_const_key(exec_rules, 69), be_const_closure(Tasmota_exec_rules_closure) },
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
{ be_const_key(add_driver, 2), be_const_closure(Tasmota_add_driver_closure) },
{ be_const_key(kv, 49), be_const_closure(Tasmota_kv_closure) },
{ be_const_key(time_reached, 43), be_const_func(l_timereached) },
{ be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
{ be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) },
{ be_const_key(run_deferred, 46), be_const_closure(Tasmota_run_deferred_closure) },
{ be_const_key(arch, -1), be_const_func(l_arch) },
{ be_const_key(strptime, -1), be_const_func(l_strptime) },
{ be_const_key(wire1, 5), be_const_var(9) },
{ be_const_key(time_str, -1), be_const_closure(Tasmota_time_str_closure) },
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
{ be_const_key(_cmd, 19), be_const_func(l_cmd) },
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
{ be_const_key(web_send, -1), be_const_func(l_webSend) },
{ be_const_key(_rules, -1), be_const_var(10) },
{ be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) },
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
{ be_const_key(get_switch, -1), be_const_func(l_getswitch) },
{ be_const_key(publish_result, -1), be_const_func(l_publish_result) },
{ be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
{ be_const_key(log, 37), be_const_func(l_logInfo) },
{ be_const_key(save, 11), be_const_func(l_save) },
{ be_const_key(init, 20), be_const_closure(Tasmota_init_closure) },
{ be_const_key(get_option, -1), be_const_func(l_getoption) },
{ be_const_key(memory, 37), be_const_func(l_memory) },
{ be_const_key(find_op, -1), be_const_closure(Tasmota_find_op_closure) },
{ be_const_key(yield, -1), be_const_func(l_yield) },
{ be_const_key(resolvecmnd, -1), be_const_func(l_resolveCmnd) },
{ be_const_key(resp_cmnd_done, -1), be_const_func(l_respCmndDone) },
{ be_const_key(get_light, 4), be_const_closure(Tasmota_get_light_closure) },
{ be_const_key(publish_result, 19), be_const_func(l_publish_result) },
{ be_const_key(_timers, 33), be_const_var(3) },
{ be_const_key(_ccmd, 75), be_const_var(4) },
{ be_const_key(read_sensors, 26), be_const_func(l_read_sensors) },
{ be_const_key(rtc, -1), be_const_func(l_rtc) },
{ be_const_key(delay, 73), be_const_func(l_delay) },
{ be_const_key(event, 35), be_const_closure(Tasmota_event_closure) },
{ be_const_key(web_send, 12), be_const_func(l_webSend) },
{ be_const_key(i2c_enabled, 78), be_const_func(l_i2cenabled) },
{ be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
{ be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
{ be_const_key(cmd, -1), be_const_closure(Tasmota_cmd_closure) },
{ be_const_key(_cmd, 62), be_const_func(l_cmd) },
{ be_const_key(wifi, 71), be_const_func(l_wifi) },
{ be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) },
{ be_const_key(resp_cmnd, 17), be_const_func(l_respCmnd) },
{ be_const_key(wire2, -1), be_const_var(5) },
{ be_const_key(get_switch, 51), be_const_func(l_getswitch) },
{ be_const_key(chars_in_string, -1), be_const_closure(Tasmota_chars_in_string_closure) },
{ be_const_key(remove_cmd, 7), be_const_closure(Tasmota_remove_cmd_closure) },
{ be_const_key(_fl, 1), be_const_var(6) },
{ be_const_key(hs2rgb, -1), be_const_closure(Tasmota_hs2rgb_closure) },
{ be_const_key(wd, 38), be_const_var(7) },
{ be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
{ be_const_key(wire2, -1), be_const_var(11) },
{ be_const_key(event, 32), be_const_closure(Tasmota_event_closure) },
{ be_const_key(strftime, -1), be_const_func(l_strftime) },
{ be_const_key(_global_addr, 65), be_const_comptr(&TasmotaGlobal) },
{ be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) },
{ be_const_key(time_reached, -1), be_const_func(l_timereached) },
{ be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
{ be_const_key(remove_rule, 67), be_const_closure(Tasmota_remove_rule_closure) },
{ be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) },
{ be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) },
{ be_const_key(time_str, 14), be_const_closure(Tasmota_time_str_closure) },
{ be_const_key(exec_rules, -1), be_const_closure(Tasmota_exec_rules_closure) },
{ be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
{ be_const_key(global, 4), be_const_var(8) },
{ be_const_key(kv, 2), be_const_closure(Tasmota_kv_closure) },
{ be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) },
{ be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
{ be_const_key(log, -1), be_const_func(l_logInfo) },
{ be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) },
{ be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) },
{ be_const_key(millis, 58), be_const_func(l_millis) },
{ be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
{ be_const_key(run_deferred, -1), be_const_closure(Tasmota_run_deferred_closure) },
{ be_const_key(_debug_present, 30), be_const_var(9) },
{ be_const_key(remove_driver, -1), be_const_closure(Tasmota_remove_driver_closure) },
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
{ be_const_key(check_not_method, -1), be_const_closure(Tasmota_check_not_method_closure) },
{ be_const_key(resolvecmnd, 74), be_const_func(l_resolveCmnd) },
{ be_const_key(arch, -1), be_const_func(l_arch) },
{ be_const_key(save, -1), be_const_func(l_save) },
{ be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) },
{ be_const_key(publish, -1), be_const_func(l_publish) },
{ be_const_key(wire1, 77), be_const_var(10) },
{ be_const_key(_rules, 28), be_const_var(11) },
{ be_const_key(add_driver, -1), be_const_closure(Tasmota_add_driver_closure) },
};
static be_define_const_map(
be_class_tasmota_map,
80
81
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -1,16 +1,17 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libintrospect_map) {
{ be_const_key(get, -1), be_const_func(m_findmember) },
{ be_const_key(toptr, 3), be_const_func(m_toptr) },
{ be_const_key(members, 3), be_const_func(m_attrlist) },
{ be_const_key(set, -1), be_const_func(m_setmember) },
{ be_const_key(fromptr, -1), be_const_func(m_fromptr) },
{ be_const_key(members, 1), be_const_func(m_attrlist) },
{ be_const_key(get, -1), be_const_func(m_findmember) },
{ be_const_key(toptr, -1), be_const_func(m_toptr) },
{ be_const_key(ismethod, -1), be_const_func(m_ismethod) },
{ be_const_key(fromptr, 2), be_const_func(m_fromptr) },
};
static be_define_const_map(
m_libintrospect_map,
5
6
);
static be_define_const_module(

View File

@ -114,7 +114,7 @@ static int m_fromptr(bvm *vm)
v = (void*) be_toint(vm, 1);
}
if (v) {
bgcobject * ptr = (bgcobject*) v;
bgcobject *ptr = (bgcobject*)v;
if (var_basetype(ptr) >= BE_GCOBJECT) {
bvalue *top = be_incrtop(vm);
var_setobj(top, ptr->type, ptr);
@ -127,6 +127,22 @@ static int m_fromptr(bvm *vm)
be_return_nil(vm);
}
/* checks if the function (berry bytecode bproto only) is hinted as a method */
static int m_ismethod(bvm *vm)
{
int top = be_top(vm);
if (top >= 1) {
bvalue *v = be_indexof(vm, 1);
if (var_isclosure(v)) {
bclosure *cl = var_toobj(v);
bproto *pr = cl->proto;
be_pushbool(vm, pr->varg & BE_VA_METHOD);
be_return(vm);
}
}
be_return_nil(vm);
}
#if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(introspect) {
be_native_module_function("members", m_attrlist),
@ -136,6 +152,8 @@ be_native_module_attr_table(introspect) {
be_native_module_function("toptr", m_toptr),
be_native_module_function("fromptr", m_fromptr),
be_native_module_function("ismethod", m_ismethod),
};
be_define_native_module(introspect, NULL);
@ -149,6 +167,8 @@ module introspect (scope: global, depend: BE_USE_INTROSPECT_MODULE) {
toptr, func(m_toptr)
fromptr, func(m_fromptr)
ismethod, func(m_ismethod)
}
@const_object_info_end */
#include "../generate/be_fixed_introspect.h"

View File

@ -40,6 +40,10 @@
#define func_setstatic(o) ((o)->type |= BE_FUNC_STATIC)
#define func_clearstatic(o) ((o)->type &= ~BE_FUNC_STATIC)
/* values for bproto.varg */
#define BE_VA_VARARG (1 << 0) /* function has variable number of arguments */
#define BE_VA_METHOD (1 << 1) /* function is a method (this is only a hint) */
#define array_count(a) (sizeof(a) / sizeof((a)[0]))
#define bcommon_header \

View File

@ -557,7 +557,7 @@ static void func_vararg(bparser *parser) {
str = next_token(parser).u.s;
match_token(parser, TokenId); /* match and skip ID */
new_var(parser, str, &v); /* new variable */
parser->finfo->proto->varg = 1; /* set varg flag */
parser->finfo->proto->varg |= BE_VA_VARARG; /* set varg flag */
}
/* Parse function or method definition variable list */
@ -606,6 +606,7 @@ static bproto* funcbody(bparser *parser, bstring *name, int type)
finfo.proto->name = name;
if (type & FUNC_METHOD) { /* If method, add an implicit first argument `self` */
new_localvar(parser, parser_newstr(parser, "self"));
finfo.proto->varg |= BE_VA_METHOD;
}
func_varlist(parser); /* parse arg list */
stmtlist(parser); /* parse statement without final `end` */

View File

@ -81,7 +81,11 @@ void be_vector_resize(bvm *vm, bvector *vector, int count)
vector->capacity = newcap;
}
vector->count = count;
vector->end = (char*)vector->data + size * ((size_t)count - 1);
if (count == 0) {
vector->end = (char*)vector->data - size;
} else {
vector->end = (char*)vector->data + size * ((size_t)count - 1);
}
}
}

View File

@ -1110,29 +1110,6 @@ newframe: /* a new call frame */
goto recall; /* call '()' method */
}
case BE_CLOSURE: {
// bvalue *v, *end;
// bproto *proto = var2cl(var)->proto; /* get proto for closure */
// push_closure(vm, var, proto->nstack, mode); /* prepare stack for closure */
// reg = vm->reg; /* `reg` has changed, now new base register */
// v = reg + argc; /* end of provided arguments */
// end = reg + proto->argc; /* end of expected arguments */
// for (; v < end; ++v) { /* set all not provided arguments to nil */
// var_setnil(v);
// }
// if (proto->varg) { /* there are vararg at the last argument, build the list */
// /* code below uses mostly low-level calls for performance */
// be_stack_require(vm, argc + 2); /* make sure we don't overflow the stack */
// bvalue *top_save = vm->top; /* save original stack, we need fresh slots to create the 'list' instance */
// vm->top = v; /* move top of stack right after last argument */
// be_newobject(vm, "list"); /* this creates 2 objects on stack: list instance, BE_LIST object */
// blist *list = var_toobj(vm->top-1); /* get low-level BE_LIST structure */
// v = reg + proto->argc - 1; /* last argument */
// for (; v < reg + argc; v++) {
// be_list_push(vm, list, v); /* push all varargs into list */
// }
// *(reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */
// vm->top = top_save; /* restore top of stack pointer */
// }
prep_closure(vm, var - reg, argc, mode);
reg = vm->reg; /* `reg` has changed, now new base register */
goto newframe; /* continue execution of the closure */
@ -1204,7 +1181,7 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
for (v = vm->reg + argc; v <= end; ++v) {
var_setnil(v);
}
if (proto->varg) { /* there are vararg at the last argument, build the list */
if (proto->varg & BE_VA_VARARG) { /* there are vararg at the last argument, build the list */
/* code below uses mostly low-level calls for performance */
be_stack_require(vm, argc + 2); /* make sure we don't overflow the stack */
bvalue *top_save = vm->top; /* save original stack, we need fresh slots to create the 'list' instance */

View File

@ -0,0 +1,14 @@
# and, or, xor
a = 11
assert(a & 0xFE == 10)
assert(a | 32 == 43)
assert(a ^ 33 == 42)
# same with literal
assert(11 & 0xFE == 10)
assert(11 | 32 == 43)
assert(11 ^ 33 == 42)
# flip
assert(~a == -12)
assert(~11 == -12)

View File

@ -0,0 +1,102 @@
#- -#
#- witness function dumping first 3 args -#
#- -#
def f(a,b,c) return [a,b,c] end
#- simple calls with fixed args -#
assert(call(f) == [nil, nil, nil])
assert(call(f, 1) == [1, nil, nil])
assert(call(f, 1, 2) == [1, 2, nil])
assert(call(f, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(call(f, []) == [nil, nil, nil])
assert(call(f, [1]) == [1, nil, nil])
assert(call(f, [1, 2]) == [1, 2, nil])
assert(call(f, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(call(f, 1, []) == [1, nil, nil])
assert(call(f, 1, [2]) == [1, 2, nil])
assert(call(f, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(call(f, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- same tests with vararg function -#
#- -#
def g(a, *b)
if size(b) == 0 return [a, nil, nil]
elif size(b) == 1 return [a, b[0], nil]
elif size(b) > 1 return [a, b[0], b[1]]
end
end
#- simple calls with fixed args -#
assert(call(g) == [nil, nil, nil])
assert(call(g, 1) == [1, nil, nil])
assert(call(g, 1, 2) == [1, 2, nil])
assert(call(g, 1, 2, 3, 4) == [1, 2, 3])
#- call with var args -#
assert(call(g, []) == [nil, nil, nil])
assert(call(g, [1]) == [1, nil, nil])
assert(call(g, [1, 2]) == [1, 2, nil])
assert(call(g, [1, 2, 3, 4]) == [1, 2, 3])
#- mixed args -#
assert(call(g, 1, []) == [1, nil, nil])
assert(call(g, 1, [2]) == [1, 2, nil])
assert(call(g, 1, [2, "foo", 4]) == [1, 2, "foo"])
#- non terminal list -#
assert(call(g, 1, [2, 3, 4], "foo") == [1, [2, 3, 4], "foo"])
#- -#
#- test with vararg only -#
#- -#
def c(*a) return size(a) end
#- simple calls with fixed args -#
assert(call(c) == 0)
assert(call(c, 1) == 1)
assert(call(c, 1, 2) == 2)
assert(call(c, 1, 2, 3, 4) == 4)
#- call with var args -#
assert(call(c, []) == 0)
assert(call(c, [1]) == 1)
assert(call(c, [1, 2]) == 2)
assert(call(c, [1, 2, 3, 4]) == 4)
#- mixed args -#
assert(call(c, 1, []) == 1)
assert(call(c, 1, [2]) == 2)
assert(call(c, 1, [2, "foo", 4]) == 4)
#- non terminal list -#
assert(call(c, 1, [2, 3, 4], "foo") == 3)
#- -#
#- test with native function -#
#- -#
import string
assert(call(string.format, "a") == "a")
assert(call(string.format, "%i", 1) == "1")
assert(call(string.format, "%i - %i", 1, 2) == "1 - 2")
assert(call(string.format, "%i - %i", [1, 2]) == "1 - 2")
assert(call(string.format, "%i - %i", [1, 2, 3]) == "1 - 2")
assert(call(string.format, "%i - %i", 1, [1, 2, 3]) == "1 - 1")
#- -#
#- try with an insanely high number of arguments to check that we don't blow up the stack -#
#- -#
l50 = []
for i:1..50 l50.push(i) end
assert(call(g, l50) == [1, 2, 3])
assert(call(c, l50) == 50)

View File

@ -0,0 +1,122 @@
def assert_attribute_error(f)
try
f()
assert(false, 'unexpected execution flow')
except .. as e, m
assert(e == 'attribute_error')
end
end
class A
static a
def init() self.b = 2 end
def f() end
var b
static c, s, r
end
assert(A.a == nil)
assert(A.c == nil)
assert(A.s == nil)
assert_attribute_error(/-> A.b)
assert_attribute_error(/-> A.d)
a = A()
assert(a.b == 2)
assert(a.a == nil)
assert(a.c == nil)
A.a = 1
A.c = 3
A.s = "foo"
A.r = 3.5
assert(a.a == 1)
assert(a.c == 3)
assert(A.a == 1)
assert(A.c == 3)
import gc gc.collect()
assert(A.s == "foo")
assert(a.s == "foo")
assert(A.r == 3.5)
assert(a.r == 3.5)
#- test valid or invalid methods and members -#
def assert_attribute_error(c)
try
compile(c)()
assert(false, 'unexpected execution flow')
except .. as e, m
assert(e == 'attribute_error')
end
end
class A
var a, g
static h
def init() self.a = 1 end
def f(x, y) return type(self) end
end
a=A()
a.g = def (x, y) return type(x) end
A.h = def (x, y) return type(x) end
assert(type(a.g) == 'function')
assert(type(a.h) == 'function')
assert(a.g(1) == 'int')
assert(a.h(1) == 'int')
assert(A.h(1) == 'int')
class A
var a
static def g(x, y) return [x,y] end
static h = def (x, y) return [x,y] end
def init() self.a = 1 end
def f(x, y) return type(self) end
end
a=A()
assert(type(a.g) == 'function')
assert(type(a.h) == 'function')
assert(type(A.g) == 'function')
assert(type(A.h) == 'function')
assert(a.g(1,2) == [1,2])
assert(a.h(1,2) == [1,2])
assert(A.g(1,2) == [1,2])
assert(A.h(1,2) == [1,2])
a.a = def (x,y) return [x,y] end
assert(a.a(1,2) == [1,2])
#- test static initializers -#
class A
static a = 1, b, c = 3.5, d = 42, e = "foo", f = [1], g = {}
var aa,ab
end
assert(A.a == 1)
assert(A.b == nil)
assert(A.c == 3.5)
assert(A.d == 42)
assert(A.e == "foo")
assert(A.f == [1])
a = A()
assert(a.a == 1)
assert(a.b == nil)
assert(a.c == 3.5)
assert(a.d == 42)
assert(a.e == "foo")
assert(a.f == [1])
assert(a.g == A.g)
assert(a.aa == nil)
assert(a.ab == nil)
#- used to fail for subclasses -#
class A static a=1 end
class B:A static a=A def f() end static b=1 static c=A end
assert(A.a == 1)
assert(B.a == A)
assert(B.b == 1)
assert(B.c == A)

View File

@ -16,4 +16,13 @@ assert(a.a == 6)
b=A()
assert(b.a == 1)
b.g(10)
assert(b.a == 6)
assert(b.a == 6)
# bug in compound assignments
class A var a,b end
c=A()
c.a = {"x": 1, "y": 2}
c.b = "x"
assert(c.a[c.b] == 1)
c.a[c.b] += 2 # this is where the bug happens
assert(c.a[c.b] == 3)

View File

@ -0,0 +1,29 @@
# test for introspect.ismethod
import introspect
# ismethod should return nil for any non-Berry closure
assert(introspect.ismethod() == nil)
assert(introspect.ismethod(true) == nil)
assert(introspect.ismethod("a") == nil)
assert(introspect.ismethod([]) == nil)
assert(introspect.ismethod({}) == nil)
assert(introspect.ismethod(introspect) == nil) # module
assert(introspect.ismethod(introspect.ismethod) == nil) # native method
def h() end
class A
def f() end
static def g() end
var h
end
a=A()
a.h = h
assert(introspect.ismethod(h) == false)
assert(introspect.ismethod(A.f) == true)
assert(introspect.ismethod(A.g) == false)
assert(introspect.ismethod(a.f) == true)
assert(introspect.ismethod(a.g) == false)
assert(introspect.ismethod(a.h) == false)

View File

@ -51,3 +51,8 @@ assert_dump({1: 'x'}, '{"1":"x"}');
assert_dump([1, 'x'], '[\n 1,\n "x"\n]', 'format');
assert_dump({1: 'x'}, '{\n "1": "x"\n}', 'format');
assert_dump({1: 'x', 'k': 'v'}, '{"k":"v","1":"x"}');
class map2 : map def init() super(self).init() end end
var m = map2()
m['key'] = 1
assert_dump(m, '{"key":1}')

View File

@ -38,7 +38,6 @@ check(45.e+2, 4500)
test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'')
test_source('x = 5; 0...x;', 'unexpected symbol near \'.\'')
# test_source('45..', 'unexpected symbol near \'EOS\'')
test_source('0xg', 'invalid hexadecimal number')
test_source('"\\x5g"', 'invalid hexadecimal number')
test_source('0x5g', 'malformed number')

View File

@ -0,0 +1,32 @@
m = { 'a':1, 'b':3.5, 'c': "foo", 0:1}
assert(type(m) == 'instance')
assert(classname(m) == 'map')
# accessor
assert(m['a'] == 1)
assert(m['b'] == 3.5)
assert(m['c'] == 'foo')
assert(m[0] == 1)
# find
assert(m.find('a') == 1)
assert(m.find('z') == nil)
assert(m.find('z', 4) == 4)
# contains
assert(m.contains('a'))
assert(m.contains(0))
assert(!m.contains('z'))
assert(!m.contains())
# set
m['y'] = -1
assert(m['y'] == -1)
# remove
m={1:2}
m.remove(2)
assert(str(m) == '{1: 2}')
m.remove(1)
assert(str(m) == '{}')

View File

@ -0,0 +1,14 @@
import math
#- nan -#
n = math.nan
assert(str(n) == 'nan')
assert(math.isnan(n))
assert(math.isnan(n+n))
assert(math.isnan(n+1))
assert(math.isnan(n*0))
assert(!math.isnan(0))
assert(!math.isnan(1.5))
assert(n != n) #- nan is never identical to itself -#

View File

@ -13,7 +13,7 @@ be_local_closure(Animate_rotate_init, /* name */
be_nested_proto(
12, /* nstack */
5, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -84,7 +84,7 @@ be_local_closure(Animate_from_to_init, /* name */
be_nested_proto(
12, /* nstack */
5, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -144,7 +144,7 @@ be_local_closure(Animate_back_forth_init, /* name */
be_nested_proto(
12, /* nstack */
5, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -225,7 +225,7 @@ be_local_closure(Animate_ins_goto_init, /* name */
be_nested_proto(
4, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -272,7 +272,7 @@ be_local_closure(Animate_ins_ramp_init, /* name */
be_nested_proto(
4, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -319,7 +319,7 @@ be_local_closure(Animate_engine_run, /* name */
be_nested_proto(
6, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -368,7 +368,7 @@ be_local_closure(Animate_engine_init, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -405,7 +405,7 @@ be_local_closure(Animate_engine_autorun, /* name */
be_nested_proto(
7, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -441,7 +441,7 @@ be_local_closure(Animate_engine_stop, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -475,7 +475,7 @@ be_local_closure(Animate_engine_is_running, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -502,7 +502,7 @@ be_local_closure(Animate_engine_every_50ms, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -530,7 +530,7 @@ be_local_closure(Animate_engine_animate, /* name */
be_nested_proto(
12, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */

View File

@ -14,7 +14,7 @@ be_local_closure(Autoconf_page_autoconf_ctl, /* name */
be_nested_proto(
13, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -196,7 +196,7 @@ be_local_closure(Autoconf_autoexec, /* name */
be_nested_proto(
9, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -359,7 +359,7 @@ be_local_closure(Autoconf_run_bat, /* name */
be_nested_proto(
13, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -447,7 +447,7 @@ be_local_closure(Autoconf_page_autoconf_mgr, /* name */
be_nested_proto(
19, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -634,7 +634,7 @@ be_local_closure(Autoconf_get_current_module_name, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -665,7 +665,7 @@ be_local_closure(Autoconf_delete_all_configs, /* name */
be_nested_proto(
10, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -723,7 +723,7 @@ be_local_closure(Autoconf_set_first_time, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -757,7 +757,7 @@ be_local_closure(Autoconf_load_templates, /* name */
be_nested_proto(
15, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -888,7 +888,7 @@ be_local_closure(Autoconf_web_add_config_button, /* name */
be_nested_proto(
5, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -920,7 +920,7 @@ be_local_closure(Autoconf_is_first_time, /* name */
be_nested_proto(
5, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -955,7 +955,7 @@ be_local_closure(Autoconf_init, /* name */
be_nested_proto(
12, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1047,7 +1047,7 @@ be_local_closure(Autoconf_preinit, /* name */
be_nested_proto(
7, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1107,7 +1107,7 @@ be_local_closure(Autoconf_reset, /* name */
be_nested_proto(
12, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1179,7 +1179,7 @@ be_local_closure(Autoconf_web_add_handler, /* name */
be_nested_proto(
7, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
1, /* has sup protos */
@ -1268,7 +1268,7 @@ be_local_closure(Autoconf_clear_first_time, /* name */
be_nested_proto(
5, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1300,7 +1300,7 @@ be_local_closure(Autoconf_get_current_module_path, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */

View File

@ -13,7 +13,7 @@ be_local_closure(Driver_add_cmd, /* name */
be_nested_proto(
7, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
1, /* has sup protos */

View File

@ -62,31 +62,40 @@ be_local_closure(Tasmota_add_driver, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(_drivers),
/* K1 */ be_nested_str(push),
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str(instance),
/* K1 */ be_nested_str(value_error),
/* K2 */ be_nested_str(instance_X20required),
/* K3 */ be_nested_str(_drivers),
/* K4 */ be_nested_str(push),
}),
&be_const_str_add_driver,
&be_const_str_solidified,
( &(const binstruction[12]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x780A0004, // 0001 JMPF R2 #0007
0x88080100, // 0002 GETMBR R2 R0 K0
0x8C080501, // 0003 GETMET R2 R2 K1
0x5C100200, // 0004 MOVE R4 R1
0x7C080400, // 0005 CALL R2 2
0x70020003, // 0006 JMP #000B
0x60080012, // 0007 GETGBL R2 G18
0x7C080000, // 0008 CALL R2 0
0x400C0401, // 0009 CONNECT R3 R2 R1
0x90020002, // 000A SETMBR R0 K0 R2
0x80000000, // 000B RET 0
( &(const binstruction[18]) { /* code */
0x60080004, // 0000 GETGBL R2 G4
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x20080500, // 0003 NE R2 R2 K0
0x780A0000, // 0004 JMPF R2 #0006
0xB0060302, // 0005 RAISE 1 K1 K2
0x88080103, // 0006 GETMBR R2 R0 K3
0x780A0004, // 0007 JMPF R2 #000D
0x88080103, // 0008 GETMBR R2 R0 K3
0x8C080504, // 0009 GETMET R2 R2 K4
0x5C100200, // 000A MOVE R4 R1
0x7C080400, // 000B CALL R2 2
0x70020003, // 000C JMP #0011
0x60080012, // 000D GETGBL R2 G18
0x7C080000, // 000E CALL R2 0
0x400C0401, // 000F CONNECT R3 R2 R1
0x90020602, // 0010 SETMBR R0 K3 R2
0x80000000, // 0011 RET 0
})
)
);
@ -100,7 +109,7 @@ be_local_closure(Tasmota_gc, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -133,7 +142,7 @@ be_local_closure(Tasmota_find_op, /* name */
be_nested_proto(
13, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -205,7 +214,7 @@ be_local_closure(Tasmota_try_rule, /* name */
be_nested_proto(
15, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -386,7 +395,7 @@ be_local_closure(Tasmota_gen_cb, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -417,7 +426,7 @@ be_local_closure(Tasmota_set_light, /* name */
be_nested_proto(
8, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -462,7 +471,7 @@ be_local_closure(Tasmota_exec_tele, /* name */
be_nested_proto(
12, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -539,7 +548,7 @@ be_local_closure(Tasmota_run_deferred, /* name */
be_nested_proto(
6, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -598,7 +607,7 @@ be_local_closure(Tasmota_remove_driver, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -638,7 +647,7 @@ be_local_closure(Tasmota_fast_loop, /* name */
be_nested_proto(
5, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -672,6 +681,7 @@ be_local_closure(Tasmota_fast_loop, /* name */
);
/*******************************************************************/
/********************************************************************
** Solidified function: add_fast_loop
********************************************************************/
@ -679,48 +689,53 @@ be_local_closure(Tasmota_add_fast_loop, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str(_fl),
/* K1 */ be_nested_str(function),
/* K2 */ be_nested_str(value_error),
/* K3 */ be_nested_str(argument_X20must_X20be_X20a_X20function),
/* K4 */ be_nested_str(global),
/* K5 */ be_nested_str(fast_loop_enabled),
/* K6 */ be_const_int(1),
/* K7 */ be_nested_str(push),
( &(const bvalue[ 9]) { /* constants */
/* K0 */ be_nested_str(check_not_method),
/* K1 */ be_nested_str(_fl),
/* K2 */ be_nested_str(function),
/* K3 */ be_nested_str(value_error),
/* K4 */ be_nested_str(argument_X20must_X20be_X20a_X20function),
/* K5 */ be_nested_str(global),
/* K6 */ be_nested_str(fast_loop_enabled),
/* K7 */ be_const_int(1),
/* K8 */ be_nested_str(push),
}),
&be_const_str_add_fast_loop,
&be_const_str_solidified,
( &(const binstruction[18]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x740A0002, // 0001 JMPT R2 #0005
0x60080012, // 0002 GETGBL R2 G18
0x7C080000, // 0003 CALL R2 0
0x90020002, // 0004 SETMBR R0 K0 R2
0x60080004, // 0005 GETGBL R2 G4
0x5C0C0200, // 0006 MOVE R3 R1
0x7C080200, // 0007 CALL R2 1
0x20080501, // 0008 NE R2 R2 K1
0x780A0000, // 0009 JMPF R2 #000B
0xB0060503, // 000A RAISE 1 K2 K3
0x88080104, // 000B GETMBR R2 R0 K4
0x900A0B06, // 000C SETMBR R2 K5 K6
0x88080100, // 000D GETMBR R2 R0 K0
0x8C080507, // 000E GETMET R2 R2 K7
0x5C100200, // 000F MOVE R4 R1
0x7C080400, // 0010 CALL R2 2
0x80000000, // 0011 RET 0
( &(const binstruction[21]) { /* code */
0x8C080100, // 0000 GETMET R2 R0 K0
0x5C100200, // 0001 MOVE R4 R1
0x7C080400, // 0002 CALL R2 2
0x88080101, // 0003 GETMBR R2 R0 K1
0x740A0002, // 0004 JMPT R2 #0008
0x60080012, // 0005 GETGBL R2 G18
0x7C080000, // 0006 CALL R2 0
0x90020202, // 0007 SETMBR R0 K1 R2
0x60080004, // 0008 GETGBL R2 G4
0x5C0C0200, // 0009 MOVE R3 R1
0x7C080200, // 000A CALL R2 1
0x20080502, // 000B NE R2 R2 K2
0x780A0000, // 000C JMPF R2 #000E
0xB0060704, // 000D RAISE 1 K3 K4
0x88080105, // 000E GETMBR R2 R0 K5
0x900A0D07, // 000F SETMBR R2 K6 K7
0x88080101, // 0010 GETMBR R2 R0 K1
0x8C080508, // 0011 GETMET R2 R2 K8
0x5C100200, // 0012 MOVE R4 R1
0x7C080400, // 0013 CALL R2 2
0x80000000, // 0014 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: event
********************************************************************/
@ -728,7 +743,7 @@ be_local_closure(Tasmota_event, /* name */
be_nested_proto(
20, /* nstack */
6, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -866,7 +881,7 @@ be_local_closure(Tasmota_find_key_i, /* name */
be_nested_proto(
10, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -925,7 +940,7 @@ be_local_closure(Tasmota_wire_scan, /* name */
be_nested_proto(
6, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -987,7 +1002,7 @@ be_local_closure(Tasmota_init, /* name */
be_nested_proto(
7, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1062,7 +1077,7 @@ be_local_closure(Tasmota_time_str, /* name */
be_nested_proto(
13, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1110,7 +1125,7 @@ be_local_closure(Tasmota_remove_rule, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1160,7 +1175,7 @@ be_local_closure(Tasmota_load, /* name */
be_nested_proto(
21, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
1, /* has sup protos */
@ -1168,7 +1183,7 @@ be_local_closure(Tasmota_load, /* name */
be_nested_proto(
6, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1201,7 +1216,7 @@ be_local_closure(Tasmota_load, /* name */
be_nested_proto(
7, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1393,7 +1408,7 @@ be_local_closure(Tasmota_chars_in_string, /* name */
be_nested_proto(
10, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1450,7 +1465,7 @@ be_local_closure(Tasmota_cmd, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1488,38 +1503,42 @@ be_local_closure(Tasmota_cmd, /* name */
********************************************************************/
be_local_closure(Tasmota_add_cmd, /* name */
be_nested_proto(
5, /* nstack */
6, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str(_ccmd),
/* K1 */ be_nested_str(function),
/* K2 */ be_nested_str(value_error),
/* K3 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function),
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str(check_not_method),
/* K1 */ be_nested_str(_ccmd),
/* K2 */ be_nested_str(function),
/* K3 */ be_nested_str(value_error),
/* K4 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function),
}),
&be_const_str_add_cmd,
&be_const_str_solidified,
( &(const binstruction[15]) { /* code */
0x880C0100, // 0000 GETMBR R3 R0 K0
0x740E0002, // 0001 JMPT R3 #0005
0x600C0013, // 0002 GETGBL R3 G19
0x7C0C0000, // 0003 CALL R3 0
0x90020003, // 0004 SETMBR R0 K0 R3
0x600C0004, // 0005 GETGBL R3 G4
0x5C100400, // 0006 MOVE R4 R2
0x7C0C0200, // 0007 CALL R3 1
0x1C0C0701, // 0008 EQ R3 R3 K1
0x780E0002, // 0009 JMPF R3 #000D
0x880C0100, // 000A GETMBR R3 R0 K0
0x980C0202, // 000B SETIDX R3 R1 R2
0x70020000, // 000C JMP #000E
0xB0060503, // 000D RAISE 1 K2 K3
0x80000000, // 000E RET 0
( &(const binstruction[18]) { /* code */
0x8C0C0100, // 0000 GETMET R3 R0 K0
0x5C140400, // 0001 MOVE R5 R2
0x7C0C0400, // 0002 CALL R3 2
0x880C0101, // 0003 GETMBR R3 R0 K1
0x740E0002, // 0004 JMPT R3 #0008
0x600C0013, // 0005 GETGBL R3 G19
0x7C0C0000, // 0006 CALL R3 0
0x90020203, // 0007 SETMBR R0 K1 R3
0x600C0004, // 0008 GETGBL R3 G4
0x5C100400, // 0009 MOVE R4 R2
0x7C0C0200, // 000A CALL R3 1
0x1C0C0702, // 000B EQ R3 R3 K2
0x780E0002, // 000C JMPF R3 #0010
0x880C0101, // 000D GETMBR R3 R0 K1
0x980C0202, // 000E SETIDX R3 R1 R2
0x70020000, // 000F JMP #0011
0xB0060704, // 0010 RAISE 1 K3 K4
0x80000000, // 0011 RET 0
})
)
);
@ -1533,43 +1552,47 @@ be_local_closure(Tasmota_add_rule, /* name */
be_nested_proto(
9, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 6]) { /* constants */
/* K0 */ be_nested_str(_rules),
/* K1 */ be_nested_str(function),
/* K2 */ be_nested_str(push),
/* K3 */ be_nested_str(kv),
/* K4 */ be_nested_str(value_error),
/* K5 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function),
( &(const bvalue[ 7]) { /* constants */
/* K0 */ be_nested_str(check_not_method),
/* K1 */ be_nested_str(_rules),
/* K2 */ be_nested_str(function),
/* K3 */ be_nested_str(push),
/* K4 */ be_nested_str(kv),
/* K5 */ be_nested_str(value_error),
/* K6 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function),
}),
&be_const_str_add_rule,
&be_const_str_solidified,
( &(const binstruction[20]) { /* code */
0x880C0100, // 0000 GETMBR R3 R0 K0
0x740E0002, // 0001 JMPT R3 #0005
0x600C0012, // 0002 GETGBL R3 G18
0x7C0C0000, // 0003 CALL R3 0
0x90020003, // 0004 SETMBR R0 K0 R3
0x600C0004, // 0005 GETGBL R3 G4
0x5C100400, // 0006 MOVE R4 R2
0x7C0C0200, // 0007 CALL R3 1
0x1C0C0701, // 0008 EQ R3 R3 K1
0x780E0007, // 0009 JMPF R3 #0012
0x880C0100, // 000A GETMBR R3 R0 K0
0x8C0C0702, // 000B GETMET R3 R3 K2
0x8C140103, // 000C GETMET R5 R0 K3
0x5C1C0200, // 000D MOVE R7 R1
0x5C200400, // 000E MOVE R8 R2
0x7C140600, // 000F CALL R5 3
0x7C0C0400, // 0010 CALL R3 2
0x70020000, // 0011 JMP #0013
0xB0060905, // 0012 RAISE 1 K4 K5
0x80000000, // 0013 RET 0
( &(const binstruction[23]) { /* code */
0x8C0C0100, // 0000 GETMET R3 R0 K0
0x5C140400, // 0001 MOVE R5 R2
0x7C0C0400, // 0002 CALL R3 2
0x880C0101, // 0003 GETMBR R3 R0 K1
0x740E0002, // 0004 JMPT R3 #0008
0x600C0012, // 0005 GETGBL R3 G18
0x7C0C0000, // 0006 CALL R3 0
0x90020203, // 0007 SETMBR R0 K1 R3
0x600C0004, // 0008 GETGBL R3 G4
0x5C100400, // 0009 MOVE R4 R2
0x7C0C0200, // 000A CALL R3 1
0x1C0C0702, // 000B EQ R3 R3 K2
0x780E0007, // 000C JMPF R3 #0015
0x880C0101, // 000D GETMBR R3 R0 K1
0x8C0C0703, // 000E GETMET R3 R3 K3
0x8C140104, // 000F GETMET R5 R0 K4
0x5C1C0200, // 0010 MOVE R7 R1
0x5C200400, // 0011 MOVE R8 R2
0x7C140600, // 0012 CALL R5 3
0x7C0C0400, // 0013 CALL R3 2
0x70020000, // 0014 JMP #0016
0xB0060B06, // 0015 RAISE 1 K5 K6
0x80000000, // 0016 RET 0
})
)
);
@ -1583,7 +1606,7 @@ be_local_closure(Tasmota_exec_rules, /* name */
be_nested_proto(
12, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1667,7 +1690,7 @@ be_local_closure(Tasmota_hs2rgb, /* name */
be_nested_proto(
17, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1765,7 +1788,7 @@ be_local_closure(KV_init, /* name */
be_nested_proto(
3, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1809,7 +1832,7 @@ be_local_closure(Tasmota_kv, /* name */
be_nested_proto(
7, /* nstack */
3, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1841,7 +1864,7 @@ be_local_closure(Tasmota_remove_cmd, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1874,7 +1897,7 @@ be_local_closure(Tasmota_set_timer, /* name */
be_nested_proto(
10, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1918,7 +1941,7 @@ be_local_closure(Tasmota_remove_timer, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -1972,7 +1995,7 @@ be_local_closure(Tasmota_exec_cmd, /* name */
be_nested_proto(
12, /* nstack */
4, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -2028,7 +2051,7 @@ be_local_closure(Tasmota_get_light, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
@ -2063,6 +2086,42 @@ be_local_closure(Tasmota_get_light, /* name */
);
/*******************************************************************/
/********************************************************************
** Solidified function: check_not_method
********************************************************************/
be_local_closure(Tasmota_check_not_method, /* name */
be_nested_proto(
6, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str(introspect),
/* K1 */ be_nested_str(ismethod),
/* K2 */ be_nested_str(type_error),
/* K3 */ be_nested_str(BRY_X3A_X20method_X20not_X20allowed_X2C_X20use_X20a_X20closure_X20like_X20_X27_X2F_X20args_X20_X2D_X3E_X20obj_X2Efunc_X28args_X29_X27),
}),
&be_const_str_check_not_method,
&be_const_str_solidified,
( &(const binstruction[ 9]) { /* code */
0xA40A0000, // 0000 IMPORT R2 K0
0x8C0C0501, // 0001 GETMET R3 R2 K1
0x5C140200, // 0002 MOVE R5 R1
0x7C0C0400, // 0003 CALL R3 2
0x50100200, // 0004 LDBOOL R4 1 0
0x1C0C0604, // 0005 EQ R3 R3 R4
0x780E0000, // 0006 JMPF R3 #0008
0xB0060503, // 0007 RAISE 1 K2 K3
0x80000000, // 0008 RET 0
})
)
);
/*******************************************************************/
#include "be_fixed_be_class_tasmota.h"
@ -2162,6 +2221,8 @@ class be_class_tasmota (scope: global, name: Tasmota) {
wire_scan, closure(Tasmota_wire_scan_closure)
time_str, closure(Tasmota_time_str_closure)
check_not_method, closure(Tasmota_check_not_method_closure)
hs2rgb, closure(Tasmota_hs2rgb_closure)
gen_cb, closure(Tasmota_gen_cb_closure)

View File

@ -47,6 +47,14 @@ class Tasmota
end
end
# check that the parameter is not a method, it would require a closure instead
def check_not_method(f)
import introspect
if introspect.ismethod(f) == true
raise "type_error", "BRY: method not allowed, use a closure like '/ args -> obj.func(args)'"
end
end
# create a specific sub-class for rules: pattern(string) -> closure
# Classs KV has two members k and v
def kv(k, v)
@ -120,6 +128,7 @@ class Tasmota
# Rules
def add_rule(pat,f)
self.check_not_method(f)
if !self._rules
self._rules=[]
end
@ -273,6 +282,7 @@ class Tasmota
# Add command to list
def add_cmd(c,f)
self.check_not_method(f)
if !self._ccmd
self._ccmd={}
end
@ -444,6 +454,7 @@ class Tasmota
end
def add_fast_loop(cl)
self.check_not_method(cl)
if !self._fl self._fl = [] end
if type(cl) != 'function' raise "value_error", "argument must be a function" end
self.global.fast_loop_enabled = 1 # enable fast_loop at global level: `TasmotaGlobal.fast_loop_enabled = true`
@ -492,6 +503,9 @@ class Tasmota
end
def add_driver(d)
if type(d) != 'instance'
raise "value_error", "instance required"
end
if self._drivers
self._drivers.push(d)
else