From b613e1db37fcfbfe558e713b976e4c14ccb2855e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 28 Feb 2021 20:50:37 +0100 Subject: [PATCH] Berry improvements --- .../Berry-0.1.10/generate/be_const_strtab.h | 233 +++---- .../generate/be_const_strtab_def.h | 335 +++++---- .../Berry-0.1.10/generate/be_fixed_debug.h | 13 +- .../Berry-0.1.10/generate/be_fixed_os.h | 22 - .../Berry-0.1.10/generate/be_fixed_path.h | 2 + .../Berry-0.1.10/generate/be_fixed_sys.h | 15 - .../Berry-0.1.10/generate/be_fixed_time.h | 17 - lib/libesp32/Berry-0.1.10/src/be_gc.c | 2 +- lib/libesp32/Berry-0.1.10/src/be_gc.h | 8 +- lib/libesp32/Berry-0.1.10/src/be_lexer.c | 3 +- lib/libesp32/Berry-0.1.10/src/be_object.h | 31 - lib/libesp32/Berry-0.1.10/src/be_parser.c | 2 +- lib/libesp32/Berry-0.1.10/src/be_string.c | 19 +- lib/libesp32/Berry-0.1.10/src/be_string.h | 2 +- lib/libesp32/Berry-0.1.10/src/be_strlib.c | 6 +- lib/libesp32/Berry-0.1.10/src/be_vector.c | 8 +- .../Berry-0.1.10/src/port/be_modtab.c | 6 +- .../Berry-0.1.10/src/port/be_tasmotalib.c | 19 +- .../Berry-0.1.10/src/port/be_wirelib.c | 36 + .../Berry-0.1.10/src/port/berry_conf.h | 25 +- tasmota/berry/tasmota.be | 20 + tasmota/xdrv_52_3_berry_native.ino | 323 +++++++++ tasmota/xdrv_52_7_berry_embedded.ino | 281 ++++++++ tasmota/xdrv_52_9_berry.ino | 354 ++++++++++ tasmota/xdrv_52_berry.ino | 650 ------------------ 25 files changed, 1335 insertions(+), 1097 deletions(-) create mode 100644 lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h create mode 100644 lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c create mode 100644 tasmota/xdrv_52_3_berry_native.ino create mode 100644 tasmota/xdrv_52_7_berry_embedded.ino create mode 100644 tasmota/xdrv_52_9_berry.ino delete mode 100644 tasmota/xdrv_52_berry.ino diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h b/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h index 9234199bb..d3ad809d7 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_const_strtab.h @@ -1,128 +1,111 @@ -extern const bcstring be_const_str_calldepth; -extern const bcstring be_const_str_clock; -extern const bcstring be_const_str_size; -extern const bcstring be_const_str_system; -extern const bcstring be_const_str_type; -extern const bcstring be_const_str_if; -extern const bcstring be_const_str_int; -extern const bcstring be_const_str_isfile; -extern const bcstring be_const_str_log; -extern const bcstring be_const_str_raise; -extern const bcstring be_const_str_concat; -extern const bcstring be_const_str_list; -extern const bcstring be_const_str_map; -extern const bcstring be_const_str_for; -extern const bcstring be_const_str_dot_p; -extern const bcstring be_const_str_isdir; -extern const bcstring be_const_str_mkdir; -extern const bcstring be_const_str_remove; -extern const bcstring be_const_str_cosh; -extern const bcstring be_const_str_abs; -extern const bcstring be_const_str_reverse; -extern const bcstring be_const_str_sinh; -extern const bcstring be_const_str_hex; -extern const bcstring be_const_str_tostring; -extern const bcstring be_const_str_opt_add; -extern const bcstring be_const_str_atan; -extern const bcstring be_const_str_real; -extern const bcstring be_const_str_iter; -extern const bcstring be_const_str_top; -extern const bcstring be_const_str_except; -extern const bcstring be_const_str_getcwd; -extern const bcstring be_const_str_listdir; -extern const bcstring be_const_str_log10; -extern const bcstring be_const_str_allocated; -extern const bcstring be_const_str_init; -extern const bcstring be_const_str_module; -extern const bcstring be_const_str_ceil; -extern const bcstring be_const_str_clear; -extern const bcstring be_const_str_collect; -extern const bcstring be_const_str_find; -extern const bcstring be_const_str_item; -extern const bcstring be_const_str_format; -extern const bcstring be_const_str_sqrt; -extern const bcstring be_const_str_classname; -extern const bcstring be_const_str_byte; -extern const bcstring be_const_str_else; -extern const bcstring be_const_str_deinit; -extern const bcstring be_const_str_end; -extern const bcstring be_const_str_true; -extern const bcstring be_const_str___upper__; -extern const bcstring be_const_str_char; -extern const bcstring be_const_str_load; -extern const bcstring be_const_str_resize; -extern const bcstring be_const_str_sethook; -extern const bcstring be_const_str_varname; -extern const bcstring be_const_str_deg; -extern const bcstring be_const_str_srand; -extern const bcstring be_const_str_str; -extern const bcstring be_const_str_range; -extern const bcstring be_const_str_toupper; -extern const bcstring be_const_str_; -extern const bcstring be_const_str_copy; -extern const bcstring be_const_str_exp; -extern const bcstring be_const_str_time; -extern const bcstring be_const_str_break; -extern const bcstring be_const_str_opt_neq; -extern const bcstring be_const_str_assert; -extern const bcstring be_const_str_attrdump; -extern const bcstring be_const_str_chdir; -extern const bcstring be_const_str_isinstance; -extern const bcstring be_const_str_continue; -extern const bcstring be_const_str_do; -extern const bcstring be_const_str_lower; -extern const bcstring be_const_str_pow; -extern const bcstring be_const_str_false; -extern const bcstring be_const_str_count; -extern const bcstring be_const_str_exit; -extern const bcstring be_const_str_print; -extern const bcstring be_const_str_def; -extern const bcstring be_const_str_pop; -extern const bcstring be_const_str_tolower; -extern const bcstring be_const_str_classof; -extern const bcstring be_const_str_cos; -extern const bcstring be_const_str_dump; -extern const bcstring be_const_str_join; -extern const bcstring be_const_str_push; -extern const bcstring be_const_str_sin; -extern const bcstring be_const_str_return; -extern const bcstring be_const_str_path; -extern const bcstring be_const_str_rand; -extern const bcstring be_const_str_class; -extern const bcstring be_const_str_nil; -extern const bcstring be_const_str_input; -extern const bcstring be_const_str_floor; -extern const bcstring be_const_str_keys; -extern const bcstring be_const_str_number; -extern const bcstring be_const_str_rad; -extern const bcstring be_const_str_imin; -extern const bcstring be_const_str_pi; -extern const bcstring be_const_str_splitext; -extern const bcstring be_const_str_compile; -extern const bcstring be_const_str_setrange; -extern const bcstring be_const_str_traceback; -extern const bcstring be_const_str_upper; -extern const bcstring be_const_str_var; -extern const bcstring be_const_str_opt_eq; -extern const bcstring be_const_str_codedump; -extern const bcstring be_const_str_tan; -extern const bcstring be_const_str_setitem; -extern const bcstring be_const_str_tanh; -extern const bcstring be_const_str_as; -extern const bcstring be_const_str_issubclass; -extern const bcstring be_const_str_upvname; -extern const bcstring be_const_str_opt_connect; -extern const bcstring be_const_str_try; -extern const bcstring be_const_str_while; -extern const bcstring be_const_str_import; -extern const bcstring be_const_str___lower__; -extern const bcstring be_const_str_open; extern const bcstring be_const_str_acos; extern const bcstring be_const_str_asin; -extern const bcstring be_const_str_imax; -extern const bcstring be_const_str_insert; -extern const bcstring be_const_str_split; -extern const bcstring be_const_str___iterator__; -extern const bcstring be_const_str_exists; -extern const bcstring be_const_str_super; +extern const bcstring be_const_str_list; +extern const bcstring be_const_str_module; +extern const bcstring be_const_str_pop; +extern const bcstring be_const_str_int; +extern const bcstring be_const_str_push; +extern const bcstring be_const_str_setrange; +extern const bcstring be_const_str_sinh; extern const bcstring be_const_str_elif; +extern const bcstring be_const_str_iter; +extern const bcstring be_const_str_load; +extern const bcstring be_const_str_class; +extern const bcstring be_const_str_if; +extern const bcstring be_const_str_opt_eq; +extern const bcstring be_const_str_ceil; +extern const bcstring be_const_str_floor; +extern const bcstring be_const_str_map; +extern const bcstring be_const_str_print; +extern const bcstring be_const_str_else; +extern const bcstring be_const_str_find; +extern const bcstring be_const_str_str; +extern const bcstring be_const_str___upper__; +extern const bcstring be_const_str_dump; +extern const bcstring be_const_str_atan; +extern const bcstring be_const_str_size; +extern const bcstring be_const_str_tolower; +extern const bcstring be_const_str_opt_add; +extern const bcstring be_const_str_abs; +extern const bcstring be_const_str_lower; +extern const bcstring be_const_str_end; +extern const bcstring be_const_str_import; +extern const bcstring be_const_str_classof; +extern const bcstring be_const_str_concat; +extern const bcstring be_const_str_byte; +extern const bcstring be_const_str_top; +extern const bcstring be_const_str_clear; +extern const bcstring be_const_str_opt_connect; +extern const bcstring be_const_str_collect; +extern const bcstring be_const_str_init; +extern const bcstring be_const_str_log10; +extern const bcstring be_const_str_nil; +extern const bcstring be_const_str_; +extern const bcstring be_const_str_real; +extern const bcstring be_const_str_calldepth; +extern const bcstring be_const_str_format; +extern const bcstring be_const_str_pi; +extern const bcstring be_const_str_do; +extern const bcstring be_const_str___iterator__; +extern const bcstring be_const_str_number; +extern const bcstring be_const_str_type; +extern const bcstring be_const_str_dot_p; +extern const bcstring be_const_str_traceback; +extern const bcstring be_const_str_as; +extern const bcstring be_const_str___lower__; +extern const bcstring be_const_str_exp; +extern const bcstring be_const_str_hex; +extern const bcstring be_const_str_char; +extern const bcstring be_const_str_split; +extern const bcstring be_const_str_toupper; +extern const bcstring be_const_str_deinit; +extern const bcstring be_const_str_tan; +extern const bcstring be_const_str_srand; +extern const bcstring be_const_str_imin; +extern const bcstring be_const_str_input; +extern const bcstring be_const_str_issubclass; +extern const bcstring be_const_str_tostring; +extern const bcstring be_const_str_break; +extern const bcstring be_const_str_insert; +extern const bcstring be_const_str_var; +extern const bcstring be_const_str_open; +extern const bcstring be_const_str_tanh; +extern const bcstring be_const_str_upper; +extern const bcstring be_const_str_allocated; +extern const bcstring be_const_str_rad; +extern const bcstring be_const_str_attrdump; +extern const bcstring be_const_str_copy; +extern const bcstring be_const_str_sqrt; +extern const bcstring be_const_str_for; +extern const bcstring be_const_str_raise; +extern const bcstring be_const_str_opt_neq; +extern const bcstring be_const_str_assert; +extern const bcstring be_const_str_item; +extern const bcstring be_const_str_reverse; +extern const bcstring be_const_str_sin; +extern const bcstring be_const_str_super; +extern const bcstring be_const_str_try; +extern const bcstring be_const_str_range; +extern const bcstring be_const_str_return; +extern const bcstring be_const_str_compile; +extern const bcstring be_const_str_false; +extern const bcstring be_const_str_resize; +extern const bcstring be_const_str_continue; +extern const bcstring be_const_str_log; +extern const bcstring be_const_str_true; +extern const bcstring be_const_str_while; +extern const bcstring be_const_str_pow; +extern const bcstring be_const_str_cos; +extern const bcstring be_const_str_count; +extern const bcstring be_const_str_remove; +extern const bcstring be_const_str_imax; +extern const bcstring be_const_str_rand; +extern const bcstring be_const_str_codedump; +extern const bcstring be_const_str_deg; +extern const bcstring be_const_str_keys; +extern const bcstring be_const_str_setitem; +extern const bcstring be_const_str_def; +extern const bcstring be_const_str_except; +extern const bcstring be_const_str_classname; +extern const bcstring be_const_str_isinstance; +extern const bcstring be_const_str_cosh; diff --git a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h b/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h index 25b5b9221..b967bc818 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_const_strtab_def.h @@ -1,190 +1,165 @@ -be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, &be_const_str_clock); -be_define_const_str(clock, "clock", 363073373u, 0, 5, &be_const_str_size); -be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_system); -be_define_const_str(system, "system", 1226705564u, 0, 6, &be_const_str_type); -be_define_const_str(type, "type", 1361572173u, 0, 4, &be_const_str_if); -be_define_const_str(if, "if", 959999494u, 50, 2, NULL); -be_define_const_str(int, "int", 2515107422u, 0, 3, &be_const_str_isfile); -be_define_const_str(isfile, "isfile", 3131505107u, 0, 6, &be_const_str_log); -be_define_const_str(log, "log", 1062293841u, 0, 3, &be_const_str_raise); -be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL); -be_define_const_str(concat, "concat", 4124019837u, 0, 6, &be_const_str_list); -be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_map); -be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_for); -be_define_const_str(for, "for", 2901640080u, 54, 3, NULL); -be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str_isdir); -be_define_const_str(isdir, "isdir", 2340917412u, 0, 5, &be_const_str_mkdir); -be_define_const_str(mkdir, "mkdir", 2883839448u, 0, 5, &be_const_str_remove); -be_define_const_str(remove, "remove", 3683784189u, 0, 6, NULL); -be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, NULL); -be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_reverse); -be_define_const_str(reverse, "reverse", 558918661u, 0, 7, &be_const_str_sinh); -be_define_const_str(sinh, "sinh", 282220607u, 0, 4, NULL); -be_define_const_str(hex, "hex", 4273249610u, 0, 3, NULL); -be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, NULL); -be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_atan); -be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_real); -be_define_const_str(real, "real", 3604983901u, 0, 4, NULL); -be_define_const_str(iter, "iter", 3124256359u, 0, 4, &be_const_str_top); -be_define_const_str(top, "top", 2802900028u, 0, 3, &be_const_str_except); -be_define_const_str(except, "except", 950914032u, 69, 6, NULL); -be_define_const_str(getcwd, "getcwd", 652026575u, 0, 6, &be_const_str_listdir); -be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, &be_const_str_log10); -be_define_const_str(log10, "log10", 2346846000u, 0, 5, NULL); -be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_init); -be_define_const_str(init, "init", 380752755u, 0, 4, &be_const_str_module); -be_define_const_str(module, "module", 3617558685u, 0, 6, NULL); -be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_clear); -be_define_const_str(clear, "clear", 1550717474u, 0, 5, &be_const_str_collect); -be_define_const_str(collect, "collect", 2399039025u, 0, 7, &be_const_str_find); -be_define_const_str(find, "find", 3186656602u, 0, 4, &be_const_str_item); -be_define_const_str(item, "item", 2671260646u, 0, 4, NULL); -be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_sqrt); -be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL); -be_define_const_str(classname, "classname", 1998589948u, 0, 9, NULL); -be_define_const_str(byte, "byte", 1683620383u, 0, 4, NULL); -be_define_const_str(else, "else", 3183434736u, 52, 4, NULL); -be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_end); -be_define_const_str(end, "end", 1787721130u, 56, 3, &be_const_str_true); -be_define_const_str(true, "true", 1303515621u, 61, 4, NULL); -be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, NULL); -be_define_const_str(char, "char", 2823553821u, 0, 4, &be_const_str_load); -be_define_const_str(load, "load", 3859241449u, 0, 4, &be_const_str_resize); -be_define_const_str(resize, "resize", 3514612129u, 0, 6, &be_const_str_sethook); -be_define_const_str(sethook, "sethook", 3963967276u, 0, 7, &be_const_str_varname); -be_define_const_str(varname, "varname", 2273276445u, 0, 7, NULL); -be_define_const_str(deg, "deg", 3327754271u, 0, 3, &be_const_str_srand); -be_define_const_str(srand, "srand", 465518633u, 0, 5, &be_const_str_str); -be_define_const_str(str, "str", 3259748752u, 0, 3, NULL); -be_define_const_str(range, "range", 4208725202u, 0, 5, &be_const_str_toupper); -be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, NULL); -be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_copy); -be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_exp); -be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_time); -be_define_const_str(time, "time", 1564253156u, 0, 4, &be_const_str_break); -be_define_const_str(break, "break", 3378807160u, 58, 5, NULL); -be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_assert); -be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_attrdump); -be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_chdir); -be_define_const_str(chdir, "chdir", 806634853u, 0, 5, &be_const_str_isinstance); -be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, &be_const_str_continue); -be_define_const_str(continue, "continue", 2977070660u, 59, 8, &be_const_str_do); -be_define_const_str(do, "do", 1646057492u, 65, 2, NULL); -be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_pow); -be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_false); -be_define_const_str(false, "false", 184981848u, 62, 5, NULL); -be_define_const_str(count, "count", 967958004u, 0, 5, NULL); -be_define_const_str(exit, "exit", 3454868101u, 0, 4, &be_const_str_print); -be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_def); -be_define_const_str(def, "def", 3310976652u, 55, 3, NULL); -be_define_const_str(pop, "pop", 1362321360u, 0, 3, &be_const_str_tolower); -be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL); -be_define_const_str(classof, "classof", 1796577762u, 0, 7, &be_const_str_cos); -be_define_const_str(cos, "cos", 4220379804u, 0, 3, &be_const_str_dump); -be_define_const_str(dump, "dump", 3663001223u, 0, 4, &be_const_str_join); -be_define_const_str(join, "join", 3374496889u, 0, 4, &be_const_str_push); -be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_sin); -be_define_const_str(sin, "sin", 3761252941u, 0, 3, &be_const_str_return); -be_define_const_str(return, "return", 2246981567u, 60, 6, NULL); -be_define_const_str(path, "path", 2223459638u, 0, 4, &be_const_str_rand); -be_define_const_str(rand, "rand", 2711325910u, 0, 4, &be_const_str_class); -be_define_const_str(class, "class", 2872970239u, 57, 5, &be_const_str_nil); -be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL); -be_define_const_str(input, "input", 4191711099u, 0, 5, NULL); -be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_keys); -be_define_const_str(keys, "keys", 4182378701u, 0, 4, &be_const_str_number); -be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_rad); -be_define_const_str(rad, "rad", 1358899048u, 0, 3, NULL); -be_define_const_str(imin, "imin", 2714127864u, 0, 4, &be_const_str_pi); -be_define_const_str(pi, "pi", 1213090802u, 0, 2, NULL); -be_define_const_str(splitext, "splitext", 2150391934u, 0, 8, NULL); -be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_setrange); -be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, &be_const_str_traceback); -be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, &be_const_str_upper); -be_define_const_str(upper, "upper", 176974407u, 0, 5, &be_const_str_var); -be_define_const_str(var, "var", 2317739966u, 64, 3, NULL); -be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, NULL); -be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, &be_const_str_tan); -be_define_const_str(tan, "tan", 2633446552u, 0, 3, NULL); -be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL); -be_define_const_str(tanh, "tanh", 153638352u, 0, 4, &be_const_str_as); -be_define_const_str(as, "as", 1579491469u, 67, 2, NULL); -be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, &be_const_str_upvname); -be_define_const_str(upvname, "upvname", 3848760617u, 0, 7, NULL); -be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, NULL); -be_define_const_str(try, "try", 2887626766u, 68, 3, &be_const_str_while); -be_define_const_str(while, "while", 231090382u, 53, 5, NULL); -be_define_const_str(import, "import", 288002260u, 66, 6, NULL); -be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_open); -be_define_const_str(open, "open", 3546203337u, 0, 4, NULL); be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_asin); -be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_imax); -be_define_const_str(imax, "imax", 3084515410u, 0, 4, &be_const_str_insert); -be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_split); -be_define_const_str(split, "split", 2276994531u, 0, 5, NULL); -be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_exists); -be_define_const_str(exists, "exists", 1002329533u, 0, 6, &be_const_str_super); -be_define_const_str(super, "super", 4152230356u, 0, 5, &be_const_str_elif); +be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_list); +be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_module); +be_define_const_str(module, "module", 3617558685u, 0, 6, &be_const_str_pop); +be_define_const_str(pop, "pop", 1362321360u, 0, 3, NULL); +be_define_const_str(int, "int", 2515107422u, 0, 3, &be_const_str_push); +be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_setrange); +be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, &be_const_str_sinh); +be_define_const_str(sinh, "sinh", 282220607u, 0, 4, &be_const_str_elif); be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL); +be_define_const_str(iter, "iter", 3124256359u, 0, 4, &be_const_str_load); +be_define_const_str(load, "load", 3859241449u, 0, 4, &be_const_str_class); +be_define_const_str(class, "class", 2872970239u, 57, 5, &be_const_str_if); +be_define_const_str(if, "if", 959999494u, 50, 2, NULL); +be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, &be_const_str_ceil); +be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, NULL); +be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_map); +be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_print); +be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_else); +be_define_const_str(else, "else", 3183434736u, 52, 4, NULL); +be_define_const_str(find, "find", 3186656602u, 0, 4, &be_const_str_str); +be_define_const_str(str, "str", 3259748752u, 0, 3, NULL); +be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_dump); +be_define_const_str(dump, "dump", 3663001223u, 0, 4, NULL); +be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_size); +be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_tolower); +be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL); +be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_abs); +be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_lower); +be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_end); +be_define_const_str(end, "end", 1787721130u, 56, 3, &be_const_str_import); +be_define_const_str(import, "import", 288002260u, 66, 6, NULL); +be_define_const_str(classof, "classof", 1796577762u, 0, 7, &be_const_str_concat); +be_define_const_str(concat, "concat", 4124019837u, 0, 6, NULL); +be_define_const_str(byte, "byte", 1683620383u, 0, 4, &be_const_str_top); +be_define_const_str(top, "top", 2802900028u, 0, 3, NULL); +be_define_const_str(clear, "clear", 1550717474u, 0, 5, NULL); +be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str_collect); +be_define_const_str(collect, "collect", 2399039025u, 0, 7, &be_const_str_init); +be_define_const_str(init, "init", 380752755u, 0, 4, &be_const_str_log10); +be_define_const_str(log10, "log10", 2346846000u, 0, 5, &be_const_str_nil); +be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL); +be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_real); +be_define_const_str(real, "real", 3604983901u, 0, 4, NULL); +be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, &be_const_str_format); +be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_pi); +be_define_const_str(pi, "pi", 1213090802u, 0, 2, &be_const_str_do); +be_define_const_str(do, "do", 1646057492u, 65, 2, NULL); +be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_number); +be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_type); +be_define_const_str(type, "type", 1361572173u, 0, 4, NULL); +be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str_traceback); +be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, &be_const_str_as); +be_define_const_str(as, "as", 1579491469u, 67, 2, NULL); +be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_exp); +be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_hex); +be_define_const_str(hex, "hex", 4273249610u, 0, 3, NULL); +be_define_const_str(char, "char", 2823553821u, 0, 4, &be_const_str_split); +be_define_const_str(split, "split", 2276994531u, 0, 5, &be_const_str_toupper); +be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, NULL); +be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_tan); +be_define_const_str(tan, "tan", 2633446552u, 0, 3, NULL); +be_define_const_str(srand, "srand", 465518633u, 0, 5, NULL); +be_define_const_str(imin, "imin", 2714127864u, 0, 4, &be_const_str_input); +be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_issubclass); +be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, NULL); +be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, &be_const_str_break); +be_define_const_str(break, "break", 3378807160u, 58, 5, NULL); +be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_var); +be_define_const_str(var, "var", 2317739966u, 64, 3, NULL); +be_define_const_str(open, "open", 3546203337u, 0, 4, &be_const_str_tanh); +be_define_const_str(tanh, "tanh", 153638352u, 0, 4, &be_const_str_upper); +be_define_const_str(upper, "upper", 176974407u, 0, 5, NULL); +be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_rad); +be_define_const_str(rad, "rad", 1358899048u, 0, 3, NULL); +be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_copy); +be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_sqrt); +be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL); +be_define_const_str(for, "for", 2901640080u, 54, 3, &be_const_str_raise); +be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL); +be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_assert); +be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_item); +be_define_const_str(item, "item", 2671260646u, 0, 4, &be_const_str_reverse); +be_define_const_str(reverse, "reverse", 558918661u, 0, 7, &be_const_str_sin); +be_define_const_str(sin, "sin", 3761252941u, 0, 3, &be_const_str_super); +be_define_const_str(super, "super", 4152230356u, 0, 5, &be_const_str_try); +be_define_const_str(try, "try", 2887626766u, 68, 3, NULL); +be_define_const_str(range, "range", 4208725202u, 0, 5, &be_const_str_return); +be_define_const_str(return, "return", 2246981567u, 60, 6, NULL); +be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_false); +be_define_const_str(false, "false", 184981848u, 62, 5, NULL); +be_define_const_str(resize, "resize", 3514612129u, 0, 6, NULL); +be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL); +be_define_const_str(log, "log", 1062293841u, 0, 3, &be_const_str_true); +be_define_const_str(true, "true", 1303515621u, 61, 4, NULL); +be_define_const_str(while, "while", 231090382u, 53, 5, NULL); +be_define_const_str(pow, "pow", 1479764693u, 0, 3, NULL); +be_define_const_str(cos, "cos", 4220379804u, 0, 3, &be_const_str_count); +be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_remove); +be_define_const_str(remove, "remove", 3683784189u, 0, 6, NULL); +be_define_const_str(imax, "imax", 3084515410u, 0, 4, &be_const_str_rand); +be_define_const_str(rand, "rand", 2711325910u, 0, 4, NULL); +be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, &be_const_str_deg); +be_define_const_str(deg, "deg", 3327754271u, 0, 3, &be_const_str_keys); +be_define_const_str(keys, "keys", 4182378701u, 0, 4, &be_const_str_setitem); +be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL); +be_define_const_str(def, "def", 3310976652u, 55, 3, &be_const_str_except); +be_define_const_str(except, "except", 950914032u, 69, 6, NULL); +be_define_const_str(classname, "classname", 1998589948u, 0, 9, &be_const_str_isinstance); +be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, NULL); +be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, NULL); static const bstring* const m_string_table[] = { - (const bstring *)&be_const_str_calldepth, - (const bstring *)&be_const_str_int, - (const bstring *)&be_const_str_concat, - (const bstring *)&be_const_str_dot_p, - NULL, - (const bstring *)&be_const_str_cosh, - (const bstring *)&be_const_str_abs, - (const bstring *)&be_const_str_hex, - (const bstring *)&be_const_str_tostring, - (const bstring *)&be_const_str_opt_add, - (const bstring *)&be_const_str_iter, - (const bstring *)&be_const_str_getcwd, - NULL, - (const bstring *)&be_const_str_allocated, - (const bstring *)&be_const_str_ceil, - (const bstring *)&be_const_str_format, - (const bstring *)&be_const_str_classname, - (const bstring *)&be_const_str_byte, - (const bstring *)&be_const_str_else, - (const bstring *)&be_const_str_deinit, - (const bstring *)&be_const_str___upper__, - (const bstring *)&be_const_str_char, - NULL, - (const bstring *)&be_const_str_deg, - NULL, - (const bstring *)&be_const_str_range, - (const bstring *)&be_const_str_, - NULL, - (const bstring *)&be_const_str_opt_neq, - (const bstring *)&be_const_str_lower, - (const bstring *)&be_const_str_count, - (const bstring *)&be_const_str_exit, - (const bstring *)&be_const_str_pop, - (const bstring *)&be_const_str_classof, - (const bstring *)&be_const_str_path, - (const bstring *)&be_const_str_input, - (const bstring *)&be_const_str_floor, - (const bstring *)&be_const_str_imin, - (const bstring *)&be_const_str_splitext, - NULL, - (const bstring *)&be_const_str_compile, - (const bstring *)&be_const_str_opt_eq, - (const bstring *)&be_const_str_codedump, - (const bstring *)&be_const_str_setitem, - (const bstring *)&be_const_str_tanh, - (const bstring *)&be_const_str_issubclass, - (const bstring *)&be_const_str_opt_connect, - (const bstring *)&be_const_str_try, - (const bstring *)&be_const_str_import, - (const bstring *)&be_const_str___lower__, - NULL, (const bstring *)&be_const_str_acos, - (const bstring *)&be_const_str___iterator__ + NULL, + (const bstring *)&be_const_str_int, + NULL, + (const bstring *)&be_const_str_iter, + (const bstring *)&be_const_str_opt_eq, + (const bstring *)&be_const_str_floor, + (const bstring *)&be_const_str_find, + (const bstring *)&be_const_str___upper__, + (const bstring *)&be_const_str_atan, + (const bstring *)&be_const_str_opt_add, + NULL, + (const bstring *)&be_const_str_classof, + (const bstring *)&be_const_str_byte, + (const bstring *)&be_const_str_clear, + (const bstring *)&be_const_str_opt_connect, + (const bstring *)&be_const_str_, + (const bstring *)&be_const_str_calldepth, + (const bstring *)&be_const_str___iterator__, + (const bstring *)&be_const_str_dot_p, + (const bstring *)&be_const_str___lower__, + (const bstring *)&be_const_str_char, + (const bstring *)&be_const_str_deinit, + (const bstring *)&be_const_str_srand, + (const bstring *)&be_const_str_imin, + (const bstring *)&be_const_str_tostring, + (const bstring *)&be_const_str_insert, + (const bstring *)&be_const_str_open, + (const bstring *)&be_const_str_allocated, + (const bstring *)&be_const_str_attrdump, + (const bstring *)&be_const_str_for, + (const bstring *)&be_const_str_opt_neq, + (const bstring *)&be_const_str_range, + (const bstring *)&be_const_str_compile, + (const bstring *)&be_const_str_resize, + (const bstring *)&be_const_str_continue, + (const bstring *)&be_const_str_log, + (const bstring *)&be_const_str_while, + (const bstring *)&be_const_str_pow, + (const bstring *)&be_const_str_cos, + (const bstring *)&be_const_str_imax, + (const bstring *)&be_const_str_codedump, + (const bstring *)&be_const_str_def, + (const bstring *)&be_const_str_classname, + (const bstring *)&be_const_str_cosh }; static const struct bconststrtab m_const_string_table = { - .size = 53, - .count = 107, + .size = 45, + .count = 90, .table = m_string_table }; diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h b/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h index 4139381d9..d6ab2709c 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_fixed_debug.h @@ -1,19 +1,16 @@ #include "be_constobj.h" static be_define_const_map_slots(m_libdebug_map) { - { be_const_key(attrdump, -1), be_const_func(m_attrdump) }, - { be_const_key(upvname, -1), be_const_func(m_upvname) }, - { be_const_key(codedump, -1), be_const_func(m_codedump) }, - { be_const_key(top, -1), be_const_func(m_top) }, - { be_const_key(sethook, 3), be_const_func(m_sethook) }, - { be_const_key(varname, 7), be_const_func(m_varname) }, - { be_const_key(calldepth, -1), be_const_func(m_calldepth) }, { be_const_key(traceback, -1), be_const_func(m_traceback) }, + { be_const_key(codedump, -1), be_const_func(m_codedump) }, + { be_const_key(calldepth, -1), be_const_func(m_calldepth) }, + { be_const_key(top, -1), be_const_func(m_top) }, + { be_const_key(attrdump, 0), be_const_func(m_attrdump) }, }; static be_define_const_map( m_libdebug_map, - 8 + 5 ); static be_define_const_module( diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h b/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h index 25022b87d..12eff88ab 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_fixed_os.h @@ -1,24 +1,2 @@ #include "be_constobj.h" -static be_define_const_map_slots(m_libos_map) { - { be_const_key(listdir, 1), be_const_func(m_listdir) }, - { be_const_key(mkdir, -1), be_const_func(m_mkdir) }, - { be_const_key(chdir, -1), be_const_func(m_chdir) }, - { be_const_key(exit, 2), be_const_func(m_exit) }, - { be_const_key(system, -1), be_const_func(m_system) }, - { be_const_key(remove, 3), be_const_func(m_remove) }, - { be_const_key(path, -1), be_const_module(m_libpath) }, - { be_const_key(getcwd, -1), be_const_func(m_getcwd) }, -}; - -static be_define_const_map( - m_libos_map, - 8 -); - -static be_define_const_module( - m_libos, - "os" -); - -BE_EXPORT_VARIABLE be_define_const_native_module(os, NULL); diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h b/lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h new file mode 100644 index 000000000..12eff88ab --- /dev/null +++ b/lib/libesp32/Berry-0.1.10/generate/be_fixed_path.h @@ -0,0 +1,2 @@ +#include "be_constobj.h" + diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h b/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h index 5fb85ceb0..12eff88ab 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_fixed_sys.h @@ -1,17 +1,2 @@ #include "be_constobj.h" -static be_define_const_map_slots(m_libsys_map) { - { be_const_key(path, -1), be_const_func(m_path) }, -}; - -static be_define_const_map( - m_libsys_map, - 1 -); - -static be_define_const_module( - m_libsys, - "sys" -); - -BE_EXPORT_VARIABLE be_define_const_native_module(sys, NULL); diff --git a/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h b/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h index 7c10c5fb9..12eff88ab 100644 --- a/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h +++ b/lib/libesp32/Berry-0.1.10/generate/be_fixed_time.h @@ -1,19 +1,2 @@ #include "be_constobj.h" -static be_define_const_map_slots(m_libtime_map) { - { be_const_key(dump, 1), be_const_func(m_dump) }, - { be_const_key(clock, -1), be_const_func(m_clock) }, - { be_const_key(time, 0), be_const_func(m_time) }, -}; - -static be_define_const_map( - m_libtime_map, - 3 -); - -static be_define_const_module( - m_libtime, - "time" -); - -BE_EXPORT_VARIABLE be_define_const_native_module(time, NULL); diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.c b/lib/libesp32/Berry-0.1.10/src/be_gc.c index 58a00f73a..37abd1f94 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_gc.c +++ b/lib/libesp32/Berry-0.1.10/src/be_gc.c @@ -310,7 +310,7 @@ static void free_ntvclos(bvm *vm, bgcobject *obj) while (count--) { be_free(vm, *uv++, sizeof(bupval)); } - be_free(vm, f, sizeof(bntvclos)); + be_free(vm, f, sizeof(bntvclos) + sizeof(bupval*) * f->nupvals); } } diff --git a/lib/libesp32/Berry-0.1.10/src/be_gc.h b/lib/libesp32/Berry-0.1.10/src/be_gc.h index 5943a7392..16ca7e766 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_gc.h +++ b/lib/libesp32/Berry-0.1.10/src/be_gc.h @@ -13,7 +13,7 @@ #define BE_GCOBJECT BE_STRING #define gc_object(o) cast(bgcobject*, o) -#define gc_cast(o, t, T) ((o) && pgm_read_byte(&(o)->type) == (t) ? (T*)(o) : NULL) +#define gc_cast(o, t, T) ((o) && (o)->type == (t) ? (T*)(o) : NULL) #define cast_proto(o) gc_cast(o, BE_PROTO, bproto) #define cast_closure(o) gc_cast(o, BE_CLOSURE, bclosure) #define cast_ntvclos(o) gc_cast(o, BE_NTVCLOS, bntvclos) @@ -38,11 +38,11 @@ if (!gc_isconst(o)) { \ #define gc_setwhite(o) gc_setmark((o), GC_WHITE) #define gc_setgray(o) gc_setmark((o), GC_GRAY) #define gc_setdark(o) gc_setmark((o), GC_DARK) -#define gc_isfixed(o) ((pgm_read_byte(&(o)->marked) & GC_FIXED) != 0) +#define gc_isfixed(o) (((o)->marked & GC_FIXED) != 0) #define gc_setfixed(o) ((o)->marked |= GC_FIXED) #define gc_clearfixed(o) ((o)->marked &= ~GC_FIXED) -#define gc_isconst(o) ((pgm_read_byte(&(o)->marked) & GC_CONST) != 0) -#define gc_exmark(o) ((pgm_read_byte(&(o)->marked) >> 4) & 0x0F) +#define gc_isconst(o) (((o)->marked & GC_CONST) != 0) +#define gc_exmark(o) (((o)->marked >> 4) & 0x0F) #define gc_setexmark(o, k) ((o)->marked |= (k) << 4) #define be_isgctype(t) ((t) >= BE_GCOBJECT) diff --git a/lib/libesp32/Berry-0.1.10/src/be_lexer.c b/lib/libesp32/Berry-0.1.10/src/be_lexer.c index b201e8df2..eea82109d 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_lexer.c +++ b/lib/libesp32/Berry-0.1.10/src/be_lexer.c @@ -105,8 +105,7 @@ static int next(blexer *lexer) lr->s = s ? s : &eos; --lr->len; } - // lexer->cursor = *lr->s++; // SH - lexer->cursor = pgm_read_byte(lr->s++); + lexer->cursor = *lr->s++; return lexer->cursor; } diff --git a/lib/libesp32/Berry-0.1.10/src/be_object.h b/lib/libesp32/Berry-0.1.10/src/be_object.h index dd73a8a87..d465138ec 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_object.h +++ b/lib/libesp32/Berry-0.1.10/src/be_object.h @@ -10,37 +10,6 @@ #include "berry.h" -/* support for PROGMEM on ESP8266 and AVR */ -#ifdef _PGMSPACE_H_ - #define strncmp strncmp_PP - #define strcmp(str1P, str2P) strncmp_PP((str1P), (str2P), SIZE_IRRELEVANT) - #define strncasecmp strncasecmp_P - #define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT) - #define strlen strlen_P - #define strchr strchr_P - #define strcat strcat_P - #define strncat strncat_P - #define strcpy strcpy_P - #define strncpy strncpy_P - #define memcpy memcpy_P - #define memccpy memccpy_P - #define memmove memmove_P - #define memcmp memcmp_P - #define memmem memmem_P - #define memchr memchr_P - #define sprintf sprintf_P - #define snprintf snprintf_P -#endif - -#ifndef pgm_read_byte -#define pgm_read_byte(addr) (*(const uint8_t*)(addr)) -#endif - -#ifndef pgm_read_word -#define pgm_read_word(addr) (*(const uint16_t*)(addr)) -#endif - - /* basic types, do not change value */ #define BE_NONE (-1) /* unknow type */ #define BE_COMPTR (-2) /* common pointer */ diff --git a/lib/libesp32/Berry-0.1.10/src/be_parser.c b/lib/libesp32/Berry-0.1.10/src/be_parser.c index bdfdcaf3d..1839e9392 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_parser.c +++ b/lib/libesp32/Berry-0.1.10/src/be_parser.c @@ -31,7 +31,7 @@ #define FUNC_ANONYMOUS 2 /* get binary operator priority */ -#define binary_op_prio(op) (pgm_read_byte(&binary_op_prio_tab[cast_int(op) - OptAdd])) +#define binary_op_prio(op) (binary_op_prio_tab[cast_int(op) - OptAdd]) #define scan_next_token(parser) (be_lexer_scan_next(&(parser)->lexer)) #define next_token(parser) ((parser)->lexer.token) diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.c b/lib/libesp32/Berry-0.1.10/src/be_string.c index 0590fb396..db7dcaebf 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_string.c +++ b/lib/libesp32/Berry-0.1.10/src/be_string.c @@ -44,9 +44,9 @@ int be_eqstr(bstring *s1, bstring *s2) if (s1 == s2) { /* short string or the same string */ return 1; } - slen = pgm_read_byte(&s1->slen); + slen = s1->slen; /* long string */ - if (slen == 255 && slen == pgm_read_byte(&s2->slen)) { + if (slen == 255 && slen == s2->slen) { blstring *ls1 = cast(blstring*, s1); blstring *ls2 = cast(blstring*, s2); return ls1->llen == ls2->llen && !strcmp(lstr(ls1), lstr(ls2)); @@ -88,7 +88,7 @@ static void resize(bvm *vm, int size) static void free_sstring(bvm *vm, bstring *str) { - be_free(vm, str, sizeof(bsstring) + pgm_read_byte(&str->slen) + 1); + be_free(vm, str, sizeof(bsstring) + str->slen + 1); } /* FNV-1a Hash */ @@ -97,8 +97,7 @@ static uint32_t str_hash(const char *str, size_t len) uint32_t hash = 2166136261u; be_assert(str || len); while (len--) { - hash = (hash ^ (unsigned char)pgm_read_byte(str)) * 16777619u; - str++; + hash = (hash ^ (unsigned char)*str++) * 16777619u; } return hash; } @@ -150,7 +149,7 @@ static bstring* find_conststr(const char *str, size_t len) uint32_t hash = str_hash(str, len); bcstring *s = (bcstring*)tab->table[hash % tab->size]; for (; s != NULL; s = next(s)) { - if (len == pgm_read_byte(&s->slen) && !strncmp(str, s->s, len)) { + if (len == s->slen && !strncmp(str, s->s, len)) { return (bstring*)s; } } @@ -166,7 +165,7 @@ static bstring* newshortstr(bvm *vm, const char *str, size_t len) bstring **list = vm->strtab.table + (hash & (size - 1)); for (s = *list; s != NULL; s = next(s)) { - if (len == pgm_read_byte(&s->slen) && !strncmp(str, sstr(s), len)) { + if (len == s->slen && !strncmp(str, sstr(s), len)) { return s; } } @@ -253,7 +252,7 @@ uint32_t be_strhash(const bstring *s) return cast(bcstring*, s)->hash; } #if BE_USE_STR_HASH_CACHE - if (pgm_read_byte(&s->slen) != 255) { + if (s->slen != 255) { return cast(bsstring*, s)->hash; } #endif @@ -266,7 +265,7 @@ const char* be_str2cstr(const bstring *s) if (gc_isconst(s)) { return cstr(s); } - if (pgm_read_byte(&s->slen) == 255) { + if (s->slen == 255) { return lstr(s); } return sstr(s); @@ -277,4 +276,4 @@ void be_str_setextra(bstring *s, int extra) if (!gc_isconst(s)) { s->extra = cast(bbyte, extra); } -} \ No newline at end of file +} diff --git a/lib/libesp32/Berry-0.1.10/src/be_string.h b/lib/libesp32/Berry-0.1.10/src/be_string.h index 8d3fba49e..51b3fd016 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_string.h +++ b/lib/libesp32/Berry-0.1.10/src/be_string.h @@ -33,7 +33,7 @@ typedef struct { } bcstring; #define str_len(_s) \ - (pgm_read_byte(&(_s)->slen) == 255 ? cast(blstring*, _s)->llen : pgm_read_byte(&(_s)->slen)) + ((_s)->slen == 255 ? cast(blstring*, _s)->llen : (_s)->slen) #define str(_s) be_str2cstr(_s) #define str_extra(_s) ((_s)->extra) diff --git a/lib/libesp32/Berry-0.1.10/src/be_strlib.c b/lib/libesp32/Berry-0.1.10/src/be_strlib.c index 37fe8e12b..499383774 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_strlib.c +++ b/lib/libesp32/Berry-0.1.10/src/be_strlib.c @@ -176,7 +176,7 @@ const char* be_pushvfstr(bvm *vm, const char *format, va_list arg) } pushstr(vm, format, p - format); concat2(vm); - switch (pgm_read_byte(&p[1])) { + switch (p[1]) { case 's': { const char *s = va_arg(arg, char*); if (s == NULL) { @@ -339,8 +339,8 @@ bstring* be_strindex(bvm *vm, bstring *str, bvalue *idx) const char* be_splitpath(const char *path) { const char *p; - for (p = path - 1; pgm_read_byte(path) != '\0'; ++path) { - if (pgm_read_byte(path) == '/') { + for (p = path - 1; *path != '\0'; ++path) { + if (*path == '/') { p = path; } } diff --git a/lib/libesp32/Berry-0.1.10/src/be_vector.c b/lib/libesp32/Berry-0.1.10/src/be_vector.c index 2cd3f1e2e..b73479601 100644 --- a/lib/libesp32/Berry-0.1.10/src/be_vector.c +++ b/lib/libesp32/Berry-0.1.10/src/be_vector.c @@ -122,16 +122,16 @@ static int binary_search(int value) const uint16_t *high = tab + array_count(tab) - 1; while (low <= high) { const uint16_t *mid = low + ((high - low) >> 1); - if (pgm_read_word(mid) == value) { - return pgm_read_word(&mid[1]); + if (*mid == value) { + return mid[1]; } - if (pgm_read_word(mid) < value) { + if (*mid < value) { low = mid + 1; } else { high = mid - 1; } } - return pgm_read_word(low); + return *low; } static int nextpow(int value) diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c b/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c index eb83cf5a2..b3e763fec 100644 --- a/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c +++ b/lib/libesp32/Berry-0.1.10/src/port/be_modtab.c @@ -20,7 +20,8 @@ be_extern_native_module(debug); be_extern_native_module(gc); /* Tasmota specific */ -be_extern_native_module(tasmota); +be_extern_native_module(tasmota_ntv); +be_extern_native_module(wire); /* user-defined modules declare start */ @@ -55,7 +56,8 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = { #endif /* user-defined modules register start */ - &be_native_module(tasmota), + &be_native_module(tasmota_ntv), + &be_native_module(wire), /* user-defined modules register end */ NULL /* do not remove */ diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c b/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c index 3e0736fd0..098cb3844 100644 --- a/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c +++ b/lib/libesp32/Berry-0.1.10/src/port/be_tasmotalib.c @@ -13,9 +13,16 @@ extern int l_millis(bvm *vm); extern int l_timereached(bvm *vm); extern int l_yield(bvm *vm); +extern int l_respCmnd(bvm *vm); +extern int l_respCmndStr(bvm *vm); +extern int l_respCmndDone(bvm *vm); +extern int l_respCmndError(bvm *vm); +extern int l_respCmndFailed(bvm *vm); + // #if !BE_USE_PRECOMPILED_OBJECT #if 1 // TODO we will do pre-compiled later -be_native_module_attr_table(tasmota) { + +be_native_module_attr_table(tasmota_ntv) { be_native_module_function("getfreeheap", l_getFreeHeap), be_native_module_function("publish", l_publish), be_native_module_function("cmd", l_cmd), @@ -23,9 +30,17 @@ be_native_module_attr_table(tasmota) { be_native_module_function("millis", l_millis), be_native_module_function("timereached", l_timereached), be_native_module_function("yield", l_yield), + + be_native_module_function("respcmnd", l_respCmnd), + be_native_module_function("respcmndstr", l_respCmndStr), + be_native_module_function("respcmnd_done", l_respCmndDone), + be_native_module_function("respcmnd_error", l_respCmndError), + be_native_module_function("respcmnd_failed", l_respCmndFailed), + + be_native_module_str("_operators", "=<>!|"), }; -be_define_native_module(tasmota, NULL); +be_define_native_module(tasmota_ntv, NULL); #else /* @const_object_info_begin module tasmota (scope: global, depend: 1) { diff --git a/lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c b/lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c new file mode 100644 index 000000000..b52865710 --- /dev/null +++ b/lib/libesp32/Berry-0.1.10/src/port/be_wirelib.c @@ -0,0 +1,36 @@ +/******************************************************************** + * Tasmota lib + * + * To use: `import wire` + * + * 2 wire communication - I2C + *******************************************************************/ +#include "be_object.h" + +extern int b_wire_begintransmission(bvm *vm); +extern int b_wire_endtransmission(bvm *vm); +extern int b_wire_requestfrom(bvm *vm); +extern int b_wire_available(bvm *vm); +extern int b_wire_write(bvm *vm); +extern int b_wire_read(bvm *vm); + +// #if !BE_USE_PRECOMPILED_OBJECT +#if 1 // TODO we will do pre-compiled later +be_native_module_attr_table(wire) { + be_native_module_function("begintransmission", b_wire_begintransmission), + be_native_module_function("endtransmission", b_wire_endtransmission), + be_native_module_function("requestfrom", b_wire_requestfrom), + be_native_module_function("available", b_wire_available), + be_native_module_function("write", b_wire_write), + be_native_module_function("read", b_wire_read), +}; + +be_define_native_module(wire, NULL); +#else +/* @const_object_info_begin +module tasmota (scope: global, depend: 1) { + getfreeheap, func(l_getFreeHeap) +} +@const_object_info_end */ +#include "../generate/be_fixed_tasmota.h" +#endif diff --git a/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h b/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h index 820207003..94f0c27b3 100644 --- a/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h +++ b/lib/libesp32/Berry-0.1.10/src/port/berry_conf.h @@ -8,19 +8,6 @@ #ifndef BERRY_CONF_H #define BERRY_CONF_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - - extern int strncmp_PP(const char * str1P, const char * str2P, size_t size); - extern char * strchr_P(const char *s, int c); - -#ifdef __cplusplus -} -#endif - #include /* Macro: BE_DEBUG @@ -53,12 +40,12 @@ extern "C" { * Use precompiled objects to avoid creating these objects at * runtime. Enable this macro can greatly optimize RAM usage. * Default: 1 - **/ -#ifdef ESP8266 -#define BE_USE_PRECOMPILED_OBJECT 0 -#else -#define BE_USE_PRECOMPILED_OBJECT 0 // will enable later when stabilized -#endif +// **/ +// #ifdef ESP8266 +// #define BE_USE_PRECOMPILED_OBJECT 0 +// #else +#define BE_USE_PRECOMPILED_OBJECT 1 // will enable later when stabilized +// #endif /* Macro: BE_DEBUG_RUNTIME_INFO * Set runtime error debugging information. diff --git a/tasmota/berry/tasmota.be b/tasmota/berry/tasmota.be index 8129b0a6e..213eb0be0 100644 --- a/tasmota/berry/tasmota.be +++ b/tasmota/berry/tasmota.be @@ -20,6 +20,26 @@ def charsinstring(s,c) return -1 end +### +class Tasmota + var _op, _operators, _rules + def init() + self._operators = "=<>!|" + self._op = [ + ['==', /s1,s2-> str(s1) == str(s2)], + ['!==',/s1,s2-> str(s1) != str(s2)], + ['=', /f1,f2-> real(f1) == real(f2)], + ['!=', /f1,f2-> real(f1) != real(f2)], + ['>=', /f1,f2-> real(f1) >= real(f2)], + ['<=', /f1,f2-> real(f1) <= real(f2)], + ['>', /f1,f2-> real(f1) > real(f2)], + ['<', /f1,f2-> real(f1) < real(f2)], + ] + self._rules = {} + end +end +### + tasmota._eqstr=/s1,s2-> str(s1) == str(s2) tasmota._neqstr=/s1,s2-> str(s1) != str(s2) tasmota._eq=/f1,f2-> real(f1) == real(f2) diff --git a/tasmota/xdrv_52_3_berry_native.ino b/tasmota/xdrv_52_3_berry_native.ino new file mode 100644 index 000000000..22cf0b9f1 --- /dev/null +++ b/tasmota/xdrv_52_3_berry_native.ino @@ -0,0 +1,323 @@ +/* + xdrv_52_3_berry_native.ino - Berry scripting language, native fucnctions + + Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifdef USE_BERRY + +#include +#include + +/*********************************************************************************************\ + * Native functions mapped to Berry functions + * + * log(msg:string [,log_level:int]) ->nil + * + * import tasmota + * + * tasmota.getfreeheap() -> int + * tasmota.publish(topic:string, payload:string[, retain:bool]) -> nil + * tasmota.cmd(command:string) -> string + * tasmota.getoption(index:int) -> int + * tasmota.millis([delay:int]) -> int + * tasmota.timereached(timer:int) -> bool + * tasmota.yield() -> nil + * +\*********************************************************************************************/ +extern "C" { + // Berry: `tasmota.publish(topic, payload [,retain]) -> nil`` + // + int32_t l_publish(struct bvm *vm); + int32_t l_publish(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { // 2 mandatory string arguments + if (top == 2 || (top == 3 && be_isbool(vm, 3))) { // 3rd optional argument must be bool + const char * topic = be_tostring(vm, 1); + const char * payload = be_tostring(vm, 2); + bool retain = false; + if (top == 3) { + retain = be_tobool(vm, 3); + } + strlcpy(TasmotaGlobal.mqtt_data, payload, sizeof(TasmotaGlobal.mqtt_data)); + MqttPublish(topic, retain); + be_return(vm); // Return + } + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `tasmota.cmd(command:string) -> string` + // + int32_t l_cmd(struct bvm *vm); + int32_t l_cmd(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1 && be_isstring(vm, 1)) { // only 1 argument of type string accepted + const char * command = be_tostring(vm, 1); + ExecuteCommand(command, SRC_BERRY); + be_pushstring(vm, TasmotaGlobal.mqtt_data); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: tasmota.millis([delay:int]) -> int + // + int32_t l_millis(struct bvm *vm); + int32_t l_millis(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 0 || (top == 1 && be_isint(vm, 1))) { // only 1 argument of type string accepted + uint32_t delay = 0; + if (top == 1) { + delay = be_toint(vm, 1); + } + uint32_t ret_millis = millis() + delay; + be_pushint(vm, ret_millis); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: tasmota.getoption(index:int) -> int + // + int32_t l_getoption(struct bvm *vm); + int32_t l_getoption(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1 && be_isint(vm, 1)) { + uint32_t opt = GetOption(be_toint(vm, 1)); + be_pushint(vm, opt); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: tasmota.timereached(timer:int) -> bool + // + int32_t l_timereached(struct bvm *vm); + int32_t l_timereached(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1 && be_isint(vm, 1)) { // only 1 argument of type string accepted + uint32_t timer = be_toint(vm, 1); + bool reached = TimeReached(timer); + be_pushbool(vm, reached); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `yield() -> nil` + // ESP object + int32_t l_yield(bvm *vm); + int32_t l_yield(bvm *vm) { + optimistic_yield(10); + be_return(vm); + } + + // Berry: `save(file:string, f:closure) -> bool` + int32_t l_save(struct bvm *vm); + int32_t l_save(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top ==2 && be_isstring(vm, 1) && be_isclosure(vm, 2)) { // only 1 argument of type string accepted + const char *fname = be_tostring(vm, 1); + int32_t ret = be_savecode(vm, fname); + be_pushint(vm, ret); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + int32_t l_respCmnd(bvm *vm); + int32_t l_respCmnd(bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1) { + const char *msg = be_tostring(vm, 1); + Response_P("%s", msg); + } + be_return_nil(vm); // Return nil when something goes wrong + } + + int32_t l_respCmndStr(bvm *vm); + int32_t l_respCmndStr(bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1) { + const char *msg = be_tostring(vm, 1); + ResponseCmndChar(msg); + } + be_return_nil(vm); // Return nil when something goes wrong + } + + int32_t l_respCmndDone(bvm *vm); + int32_t l_respCmndDone(bvm *vm) { + ResponseCmndDone(); + be_return_nil(vm); + } + + int32_t l_respCmndError(bvm *vm); + int32_t l_respCmndError(bvm *vm) { + ResponseCmndError(); + be_return_nil(vm); + } + + int32_t l_respCmndFailed(bvm *vm); + int32_t l_respCmndFailed(bvm *vm) { + ResponseCmndFailed(); + be_return_nil(vm); + } +} + +/*********************************************************************************************\ + * Native functions mapped to Berry functions + * + * import wire + * + * wire.getfreeheap() -> int + * +\*********************************************************************************************/ +extern "C" { + // Berry: `begintransmission(address:int) -> nil` + int32_t b_wire_begintransmission(struct bvm *vm); + int32_t b_wire_begintransmission(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1 && be_isint(vm, 1)) { // only 1 argument of type string accepted + int32_t address = be_toint(vm, 1); + Wire.beginTransmission(address); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `endtransmission([stop:bool]) -> nil` + int32_t b_wire_endtransmission(struct bvm *vm); + int32_t b_wire_endtransmission(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 0 || (top == 1 && be_isbool(vm, 1))) { // only 1 argument of type string accepted + bool stop = true; + if (top == 1) { + stop = be_tobool(vm, 1); + } + uint32_t ret = Wire.endTransmission(stop); + be_pushint(vm, ret); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `requestfrom(address:int, quantity:int [stop:bool = true]) -> nil` + int32_t b_wire_requestfrom(struct bvm *vm); + int32_t b_wire_requestfrom(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if ( (top == 2 || (top == 3 && be_isbool(vm, 3))) + && be_isint(vm, 1) && be_isint(vm, 2) ) { + int32_t address = be_toint(vm, 1); + int32_t quantity = be_toint(vm, 2); + bool stop = true; + if (top == 3) { + stop = be_tobool(vm, 3); + } + Wire.requestFrom((uint16_t)address, (uint8_t)quantity, stop); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `available() -> bool` + int32_t b_wire_available(struct bvm *vm); + int32_t b_wire_available(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 0) { + size_t available = Wire.available(); + be_pushint(vm, available); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `write(value:int | s:string) -> nil` + int32_t b_wire_write(struct bvm *vm); + int32_t b_wire_write(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 1 && (be_isint(vm, 1) || be_isint(vm, 1))) { + if (be_isint(vm, 1)) { + int32_t value = be_toint(vm, 1); + Wire.write(value); + } else if (be_isstring(vm, 1)) { + const char * s = be_tostring(vm, 1); + Wire.write(s); + } else { + be_return_nil(vm); + } + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `read() -> int` + int32_t b_wire_read(struct bvm *vm); + int32_t b_wire_read(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top == 0) { + int32_t value = Wire.read(); + be_pushint(vm, value); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + +} + +/*********************************************************************************************\ + * Native functions mapped to Berry functions + * + * log(msg:string [,log_level:int]) ->nil + * +\*********************************************************************************************/ +extern "C" { + // Berry: `log(msg:string [,log_level:int]) ->nil` + // Logs the string at LOG_LEVEL_INFO (loglevel=2) + int32_t l_logInfo(struct bvm *vm); + int32_t l_logInfo(struct bvm *vm) { + int32_t top = be_top(vm); // Get the number of arguments + if (top >= 1 && be_isstring(vm, 1)) { // only 1 argument of type string accepted + const char * msg = be_tostring(vm, 1); + uint32_t log_level = LOG_LEVEL_INFO; + if (top >= 2 && be_isint(vm, 2)) { + log_level = be_toint(vm, 2); + if (log_level > LOG_LEVEL_DEBUG_MORE) { log_level = LOG_LEVEL_DEBUG_MORE; } + } + AddLog(log_level, PSTR("%s"), msg); + be_return(vm); // Return + } + be_return_nil(vm); // Return nil when something goes wrong + } + + // Berry: `getFreeHeap() -> int` + // ESP object + int32_t l_getFreeHeap(bvm *vm); + int32_t l_getFreeHeap(bvm *vm) { + be_pushint(vm, ESP.getFreeHeap()); + be_return(vm); + } +} + +// called as a replacement to Berry `print()` +void berry_log(const char * berry_buf); +void berry_log(const char * berry_buf) { + AddLog(LOG_LEVEL_INFO, PSTR("%s"), berry_buf); +} + + +#endif // USE_BERRY diff --git a/tasmota/xdrv_52_7_berry_embedded.ino b/tasmota/xdrv_52_7_berry_embedded.ino new file mode 100644 index 000000000..4904210d1 --- /dev/null +++ b/tasmota/xdrv_52_7_berry_embedded.ino @@ -0,0 +1,281 @@ +/* + xdrv_52_3_berry_embedded.ino - Berry scripting language, embedded code + + Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifdef USE_BERRY + +/*********************************************************************************************\ + * Handlers for Berry calls and async + * +\*********************************************************************************************/ + +const char berry_prog[] = + "" + //"def func(x) for i:1..x print('a') end end " + //"def testreal() return str(1.2+1) end " + //"def noop() log('noop before'); yield(); log('middle after'); yield(); log('noop after'); end " + //"log(\"foobar\") " + + // auto-import modules + // // import alias + "import wire " + + // Phase 1 + // Prepare the super class that will be eventually in Flash + "class Tasmota_ntv " + "var _op, _operators, _rules, _timers, _cmd " + + // Map all native functions to methods + // Again, this will be eventually pre-compiled + "var getfreeheap, publish, cmd, getoption, millis, timereached, yield " + "var respcmnd, respcmndstr, respcmnd_done, respcmnd_error, respcmnd_failed " + "def init_ntv() " + "import tasmota_ntv " + "self.getfreeheap = tasmota_ntv.getfreeheap " + "self.publish = tasmota_ntv.publish " + "self.cmd = tasmota_ntv.cmd " + "self.getoption = tasmota_ntv.getoption " + "self.millis = tasmota_ntv.millis " + "self.timereached = tasmota_ntv.timereached " + "self.yield = tasmota_ntv.yield " + "self._operators = tasmota_ntv._operators " + + "self.respcmnd = tasmota_ntv.respcmnd " + "self.respcmndstr = tasmota_ntv.respcmndstr " + "self.respcmnd_done = tasmota_ntv.respcmnd_done " + "self.respcmnd_error = tasmota_ntv.respcmnd_error " + "self.respcmnd_failed = tasmota_ntv.respcmnd_failed " + "end " + + "def init() " + "self._op = [ " + "['==', /s1,s2-> str(s1) == str(s2)]," + "['!==',/s1,s2-> str(s1) != str(s2)]," + "['=', /f1,f2-> real(f1) == real(f2)]," + "['!=', /f1,f2-> real(f1) != real(f2)]," + "['>=', /f1,f2-> real(f1) >= real(f2)]," + "['<=', /f1,f2-> real(f1) <= real(f2)]," + "['>', /f1,f2-> real(f1) > real(f2)]," + "['<', /f1,f2-> real(f1) < real(f2)]," + "] " + "self._rules = {} " + "self._timers = [] " + "self._cmd = {} " + "self.init_ntv() " + "end " + "end " + + "class Tasmota: Tasmota_ntv " + // add `charsinstring(s:string,c:string) -> int`` + // looks for any char in c, and return the position of the first chat + // or -1 if not found + "def charsinstring(s,c) " + "for i:0..size(s)-1 " + "for j:0..size(c)-1 " + "if s[i] == c[j] return i end " + "end " + "end " + "return -1 " + "end " + + // find a key in map, case insensitive, return actual key or nil if not found + "def findkeyi(m,keyi) " + "import string " + "var keyu = string.toupper(keyi) " + "if classof(m) == map " + "for k:m.keys() " + "if string.toupper(k)==keyu || keyi=='?' " + "return k " + "end " + "end " + "end " + "end " + + // Rules + "def addrule(pat,f) self._rules[pat] = f end " + + // # split the item when there is an operator, returns a list of (left,op,right) + // # ex: "Dimmer>50" -> ["Dimmer",tasmota_gt,"50"] + "def find_op(item) " + "import string " + "var pos = self.charsinstring(item, self._operators) " + "if pos>=0 " + "var op_split = string.split(item,pos) " + // #print(op_split) + "var op_left = op_split[0] " + "var op_rest = op_split[1] " + // # iterate through operators + "for op: self._op " + "if string.find(op_rest,op[0]) == 0 " + "var op_func = op[1] " + "var op_right = string.split(op_rest,size(op[0]))[1] " + "return [op_left,op_func,op_right] " + "end " + "end " + "end " + "return [item, nil, nil] " + "end " + + // Rules trigger if match. return true if match, false if not + // Note: condition is not yet managed + "def try_rule(ev, rule, f) " + "import string " + "var rl_list = self.find_op(rule) " + "var e=ev " + "var rl=string.split(rl_list[0],'#') " + "for it:rl " + "found=self.findkeyi(e,it) " + "if found == nil " + "return false " + "end " + "e=e[found] " + "end " + // # check if condition is true + "if rl_list[1] " + // # did we find a function + "if !rl_list[1](e,rl_list[2]) " + // # condition is not met + "return false " + "end " + "end " + "f(e,ev) " + "return true " + "end " + + // Run rules, i.e. check each individual rule + // Returns true if at least one rule matched, false if none + "def exec_rules(ev_json) " + "import json " + "var ev = json.load(ev_json) " + "var ret = false " + "if ev == nil " + "print('BRY: ERROR, bad json: '+ev_json, 3) " + "else " + "for r: self._rules.keys() " + "ret = self.try_rule(ev,r,self._rules[r]) || ret " + "end " + "end " + "return ret " + "end " + + "def settimer(delay,f) self._timers.push([self.millis(delay),f]) end " + + "def run_deferred() " + "var i=0 " + "while i. +*/ + + +#ifdef USE_BERRY + +#define XDRV_52 52 + +#include + +const char kBrCommands[] PROGMEM = D_PRFX_BR "|" // prefix + D_CMND_BR_RUN "|" D_CMND_BR_RESET + ; + +void (* const BerryCommand[])(void) PROGMEM = { + CmndBrRun, CmndBrReset, + }; + +class BerrySupport { +public: + bvm *vm = nullptr; // berry vm + bool rules_busy = false; // are we already processing rules, avoid infinite loop + const char *fname = nullptr; // name of berry function to call + int32_t fret = 0; +}; +BerrySupport berry; + +// +// Sanity Check for be_top() +// +// Checks that the Berry stack is empty, if not print a Warning and empty it +// +void checkBeTop(void) { + int32_t top = be_top(berry.vm); + if (top != 0) { + be_pop(berry.vm, top); // TODO should not be there + AddLog(LOG_LEVEL_ERROR, D_LOG_BERRY "Error be_top is non zero=%d", top); + } +} + +/*********************************************************************************************\ + * Handlers for Berry calls and async + * +\*********************************************************************************************/ +// // call a function (if exists) of type void -> void +// void callBerryFunctionVoid_berry(const char * fname) { +// berry.fret = 0; +// callBerryFunctionVoid(berry.fname); +// } + +bool callBerryRule(void) { + if (berry.rules_busy) { return false; } + berry.rules_busy = true; + char * json_event = TasmotaGlobal.mqtt_data; + bool serviced = false; + + checkBeTop(); + be_getglobal(berry.vm, "_exec_rules"); + if (!be_isnil(berry.vm, -1)) { + + // { + // String event_saved = TasmotaGlobal.mqtt_data; + // // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} + // // json_event = {"System":{"Boot":1}} + // // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} + // char *p = strchr(json_event, ':'); + // if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon + // event_saved.replace(F(":"), F(":{\"Data\":")); + // event_saved += F("}"); + // // event_saved = {"SerialReceived":{"Data":"on"}} + // } + // be_pushstring(berry.vm, event_saved.c_str()); + // } + be_pushstring(berry.vm, TasmotaGlobal.mqtt_data); + int ret = be_pcall(berry.vm, 1); + serviced = be_tobool(berry.vm, 1); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Event (%s) serviced=%d"), TasmotaGlobal.mqtt_data, serviced); + be_pop(berry.vm, 2); // remove function object + } else { + be_pop(berry.vm, 1); // remove nil object + } + checkBeTop(); + berry.rules_busy = false; + + return serviced; // TODO event not handled +} + +bool callBerryCommand(void) { + const char * command = nullptr; + + checkBeTop(); + be_getglobal(berry.vm, "_exec_cmd"); + if (!be_isnil(berry.vm, -1)) { + be_pushstring(berry.vm, XdrvMailbox.topic); + be_pushint(berry.vm, XdrvMailbox.index); + be_pushstring(berry.vm, XdrvMailbox.data); + int ret = be_pcall(berry.vm, 3); + command = be_tostring(berry.vm, 3); + strlcpy(XdrvMailbox.topic, command, CMDSZ); + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Command (%s) serviced=%d"), XdrvMailbox.command, serviced); + be_pop(berry.vm, 4); // remove function object + } else { + be_pop(berry.vm, 1); // remove nil object + } + checkBeTop(); + + return command != nullptr; // TODO event not handled +} + +size_t callBerryGC(void) { + size_t ram_used = 0; + checkBeTop(); + be_getglobal(berry.vm, "_gc"); + if (!be_isnil(berry.vm, -1)) { + int ret = be_pcall(berry.vm, 0); + ram_used = be_toint(berry.vm, 1); + be_pop(berry.vm, 1); // remove function object + } else { + be_pop(berry.vm, 1); // remove nil object + } + checkBeTop(); + + return ram_used; +} + +// void callBerryMqttData(void) { +// AddLog(LOG_LEVEL_INFO, D_LOG_BERRY "callBerryMqttData"); +// if (nullptr == berry.vm) { return; } +// if (XdrvMailbox.data_len < 1) { +// return; +// } +// const char * topic = XdrvMailbox.topic; +// const char * payload = XdrvMailbox.data; + +// checkBeTop(); +// be_getglobal(berry.vm, "mqtt_data_dispatch"); +// if (!be_isnil(berry.vm, -1)) { +// be_pushstring(berry.vm, topic); +// be_pushstring(berry.vm, payload); +// be_pcall(berry.vm, 0); +// be_pop(berry.vm, 3); // remove function object +// } else { +// be_pop(berry.vm, 1); // remove nil object +// } +// checkBeTop(); +// } + +// call a function (if exists) of type void -> void +void callBerryFunctionVoid(const char * fname) { + if (nullptr == berry.vm) { return; } + checkBeTop(); + be_getglobal(berry.vm, fname); + if (!be_isnil(berry.vm, -1)) { + be_pcall(berry.vm, 0); + } + be_pop(berry.vm, 1); // remove function or nil object + checkBeTop(); +} + +/*********************************************************************************************\ + * VM Init +\*********************************************************************************************/ +extern "C" { + extern size_t be_gc_memcount(bvm *vm); + extern void be_gc_collect(bvm *vm); +} +void BrReset(void) { + // clean previous VM if any + if (berry.vm != nullptr) { + be_vm_delete(berry.vm); + berry.vm = nullptr; + } + + int32_t ret_code1, ret_code2; + bool berry_init_ok = false; + do { + berry.vm = be_vm_new(); /* create a virtual machine instance */ + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry VM created, RAM used=%u"), be_gc_memcount(berry.vm)); + + // Register functions + be_regfunc(berry.vm, PSTR("log"), l_logInfo); + be_regfunc(berry.vm, PSTR("save"), l_save); + + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry function registered, RAM used=%u"), be_gc_memcount(berry.vm)); + + ret_code1 = be_loadstring(berry.vm, berry_prog); + if (ret_code1 != 0) { + AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_BERRY "ERROR: be_loadstring [%s] %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1)); + be_pop(berry.vm, 2); + break; + } + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code loaded, RAM used=%u"), be_gc_memcount(berry.vm)); + ret_code2 = be_pcall(berry.vm, 0); + if (ret_code1 != 0) { + AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_BERRY "ERROR: be_pcall [%s] %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1)); + be_pop(berry.vm, 2); + break; + } + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code ran, RAM used=%u"), be_gc_memcount(berry.vm)); + be_pop(berry.vm, 1); + + be_gc_collect(berry.vm); + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_BERRY "Berry initialized, RAM used=%u"), callBerryGC()); + // AddLog(LOG_LEVEL_INFO, PSTR("Delete Berry VM")); + // be_vm_delete(vm); + // AddLog(LOG_LEVEL_INFO, PSTR("After Berry")); + + berry_init_ok = true; + } while (0); + + if (!berry_init_ok) { + // free resources + if (berry.vm != nullptr) { + be_vm_delete(berry.vm); + berry.vm = nullptr; + } + } +} + +/*********************************************************************************************\ + * Tasmota Commands +\*********************************************************************************************/ +// +// Command `BrRun` +// +void CmndBrRun(void) { + int32_t ret_code; + const char * ret_type, * ret_val; + + if (berry.vm == nullptr) { ResponseCmndChar_P(PSTR(D_BR_NOT_STARTED)); return; } + + char br_cmd[XdrvMailbox.data_len+12]; + // encapsulate into a function, copied from `be_repl.c` / `try_return()` + snprintf_P(br_cmd, sizeof(br_cmd), PSTR("return (%s)"), XdrvMailbox.data); + + checkBeTop(); + do { + // First try with the `return ()` wrapper + ret_code = be_loadbuffer(berry.vm, PSTR("input"), br_cmd, strlen(br_cmd)); + if (be_getexcept(berry.vm, ret_code) == BE_SYNTAX_ERROR) { + be_pop(berry.vm, 2); // remove exception values + // if fails, try the direct command + ret_code = be_loadbuffer(berry.vm, PSTR("input"), XdrvMailbox.data, strlen(XdrvMailbox.data)); + } + if (0 != ret_code) break; + + ret_code = be_pcall(berry.vm, 0); // execute code + } while (0); + + if (0 == ret_code) { + // code taken from REPL, look first at top, and if nil, look at return value + if (be_isnil(berry.vm, 0)) { + ret_val = be_tostring(berry.vm, -1); + } else { + ret_val = be_tostring(berry.vm, 0); + } + Response_P("{\"" D_PRFX_BR "\":\"%s\"}", ret_val); // can't use XdrvMailbox.command as it may have been overwritten by subcommand + be_pop(berry.vm, 1); + } else { + Response_P(PSTR("{\"" D_PRFX_BR "\":\"[%s] %s\"}"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1)); + be_pop(berry.vm, 2); + } + + checkBeTop(); +} + +// +// Command `BrReset` +// +void CmndBrReset(void) { + if (berry.vm == nullptr) { ResponseCmndChar_P(PSTR(D_BR_NOT_STARTED)); return; } + + BrReset(); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ +bool Xdrv52(uint8_t function) +{ + bool result = false; + + switch (function) { + //case FUNC_PRE_INIT: + case FUNC_INIT: + BrReset(); + break; + case FUNC_EVERY_50_MSECOND: + callBerryFunctionVoid(PSTR("_run_deferred")); + break; + case FUNC_EVERY_100_MSECOND: + callBerryFunctionVoid(PSTR("every_100ms")); + break; + case FUNC_EVERY_SECOND: + callBerryFunctionVoid(PSTR("every_second")); + break; + case FUNC_COMMAND: + result = DecodeCommand(kBrCommands, BerryCommand); + if (!result) { + result = callBerryCommand(); + } + break; + // case FUNC_SET_POWER: + // break; + case FUNC_RULES_PROCESS: + result = callBerryRule(); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_ADD_BUTTON: + break; + case FUNC_WEB_ADD_MAIN_BUTTON: + + break; + case FUNC_WEB_ADD_HANDLER: + break; +#endif // USE_WEBSERVER + case FUNC_SAVE_BEFORE_RESTART: + break; + case FUNC_MQTT_DATA: + // callBerryMqttData(); + break; + case FUNC_WEB_SENSOR: + break; + + case FUNC_JSON_APPEND: + break; + + case FUNC_BUTTON_PRESSED: + break; + + case FUNC_LOOP: + break; + + } + return result; +} + +#endif // USE_BERRY diff --git a/tasmota/xdrv_52_berry.ino b/tasmota/xdrv_52_berry.ino deleted file mode 100644 index d6e4fa015..000000000 --- a/tasmota/xdrv_52_berry.ino +++ /dev/null @@ -1,650 +0,0 @@ -/* - xdrv_52_berry.ino - Berry scripting language - - Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifdef USE_BERRY - -#define XDRV_52 52 - -#include -#include - -const char kBrCommands[] PROGMEM = D_PRFX_BR "|" // prefix - D_CMND_BR_RUN "|" D_CMND_BR_RESET - ; - -void (* const BerryCommand[])(void) PROGMEM = { - CmndBrRun, CmndBrReset, - }; - -class BerrySupport { -public: - bvm *vm = nullptr; // berry vm - bool rules_busy = false; // are we already processing rules, avoid infinite loop - const char *fname = nullptr; // name of berry function to call - int32_t fret = 0; -}; -BerrySupport berry; - -// -// Sanity Check for be_top() -// -// Checks that the Berry stack is empty, if not print a Warning and empty it -// -void checkBeTop(void) { - int32_t top = be_top(berry.vm); - if (top != 0) { - be_pop(berry.vm, top); // TODO should not be there - AddLog(LOG_LEVEL_ERROR, D_LOG_BERRY "Error be_top is non zero=%d", top); - } -} - -/*********************************************************************************************\ - * Native functions mapped to Berry functions - * - * log(msg:string [,log_level:int]) ->nil - * - * import tasmota - * - * tasmota.getfreeheap() -> int - * tasmota.publish(topic:string, payload:string[, retain:bool]) -> nil - * tasmota.cmd(command:string) -> string - * tasmota.getoption(index:int) -> int - * tasmota.millis([delay:int]) -> int - * tasmota.timereached(timer:int) -> bool - * tasmota.yield() -> nil - * -\*********************************************************************************************/ -extern "C" { - // Berry: `log(msg:string [,log_level:int]) ->nil` - // Logs the string at LOG_LEVEL_INFO (loglevel=2) - int32_t l_logInfo(struct bvm *vm); - int32_t l_logInfo(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top >= 1 && be_isstring(vm, 1)) { // only 1 argument of type string accepted - const char * msg = be_tostring(vm, 1); - uint32_t log_level = LOG_LEVEL_INFO; - if (top >= 2 && be_isint(vm, 2)) { - log_level = be_toint(vm, 2); - if (log_level > LOG_LEVEL_DEBUG_MORE) { log_level = LOG_LEVEL_DEBUG_MORE; } - } - AddLog(log_level, PSTR("%s"), msg); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: `getFreeHeap() -> int` - // ESP object - int32_t l_getFreeHeap(bvm *vm); - int32_t l_getFreeHeap(bvm *vm) { - be_pushint(vm, ESP.getFreeHeap()); - be_return(vm); - } - - // Berry: `tasmota.publish(topic, payload [,retain]) -> nil`` - // - int32_t l_publish(struct bvm *vm); - int32_t l_publish(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { // 2 mandatory string arguments - if (top == 2 || (top == 3 && be_isbool(vm, 3))) { // 3rd optional argument must be bool - const char * topic = be_tostring(vm, 1); - const char * payload = be_tostring(vm, 2); - bool retain = false; - if (top == 3) { - retain = be_tobool(vm, 3); - } - strlcpy(TasmotaGlobal.mqtt_data, payload, sizeof(TasmotaGlobal.mqtt_data)); - MqttPublish(topic, retain); - be_return(vm); // Return - } - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: `tasmota.cmd(command:string) -> string` - // - int32_t l_cmd(struct bvm *vm); - int32_t l_cmd(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top == 1 && be_isstring(vm, 1)) { // only 1 argument of type string accepted - const char * command = be_tostring(vm, 1); - ExecuteCommand(command, SRC_BERRY); - be_pushstring(vm, TasmotaGlobal.mqtt_data); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: tasmota.millis([delay:int]) -> int - // - int32_t l_millis(struct bvm *vm); - int32_t l_millis(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top == 0 || (top == 1 && be_isint(vm, 1))) { // only 1 argument of type string accepted - uint32_t delay = 0; - if (top == 1) { - delay = be_toint(vm, 1); - } - uint32_t ret_millis = millis() + delay; - be_pushint(vm, ret_millis); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: tasmota.getoption(index:int) -> int - // - int32_t l_getoption(struct bvm *vm); - int32_t l_getoption(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top == 1 && be_isint(vm, 1)) { - uint32_t opt = GetOption(be_toint(vm, 1)); - be_pushint(vm, opt); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: tasmota.timereached(timer:int) -> bool - // - int32_t l_timereached(struct bvm *vm); - int32_t l_timereached(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top == 1 && be_isint(vm, 1)) { // only 1 argument of type string accepted - uint32_t timer = be_toint(vm, 1); - bool reached = TimeReached(timer); - be_pushbool(vm, reached); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - // Berry: `yield() -> nil` - // ESP object - int32_t l_yield(bvm *vm); - int32_t l_yield(bvm *vm) { - optimistic_yield(10); - be_return(vm); - } - - // Berry: `save(file:string, f:closure) -> bool` - int32_t l_save(struct bvm *vm); - int32_t l_save(struct bvm *vm) { - int32_t top = be_top(vm); // Get the number of arguments - if (top ==2 && be_isstring(vm, 1) && be_isclosure(vm, 2)) { // only 1 argument of type string accepted - const char *fname = be_tostring(vm, 1); - int32_t ret = be_savecode(vm, fname); - be_pushint(vm, ret); - be_return(vm); // Return - } - be_return_nil(vm); // Return nil when something goes wrong - } - - -} - -// called as a replacement to Berry `print()` -void berry_log(const char * berry_buf); -void berry_log(const char * berry_buf) { - AddLog(LOG_LEVEL_INFO, PSTR("%s"), berry_buf); -} - -/*********************************************************************************************\ - * Handlers for Berry calls and async - * -\*********************************************************************************************/ -// // call a function (if exists) of type void -> void -// void callBerryFunctionVoid_berry(const char * fname) { -// berry.fret = 0; -// callBerryFunctionVoid(berry.fname); -// } - -bool callBerryRule(void) { - if (berry.rules_busy) { return false; } - berry.rules_busy = true; - char * json_event = TasmotaGlobal.mqtt_data; - bool serviced = false; - - checkBeTop(); - be_getglobal(berry.vm, "_exec_rules"); - if (!be_isnil(berry.vm, -1)) { - - // { - // String event_saved = TasmotaGlobal.mqtt_data; - // // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} - // // json_event = {"System":{"Boot":1}} - // // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} - // char *p = strchr(json_event, ':'); - // if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon - // event_saved.replace(F(":"), F(":{\"Data\":")); - // event_saved += F("}"); - // // event_saved = {"SerialReceived":{"Data":"on"}} - // } - // be_pushstring(berry.vm, event_saved.c_str()); - // } - be_pushstring(berry.vm, TasmotaGlobal.mqtt_data); - int ret = be_pcall(berry.vm, 1); - serviced = be_tobool(berry.vm, 1); - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Event (%s) serviced=%d"), TasmotaGlobal.mqtt_data, serviced); - be_pop(berry.vm, 2); // remove function object - } else { - be_pop(berry.vm, 1); // remove nil object - } - checkBeTop(); - berry.rules_busy = false; - - return serviced; // TODO event not handled -} - -// void callBerryMqttData(void) { -// AddLog(LOG_LEVEL_INFO, D_LOG_BERRY "callBerryMqttData"); -// if (nullptr == berry.vm) { return; } -// if (XdrvMailbox.data_len < 1) { -// return; -// } -// const char * topic = XdrvMailbox.topic; -// const char * payload = XdrvMailbox.data; - -// checkBeTop(); -// be_getglobal(berry.vm, "mqtt_data_dispatch"); -// if (!be_isnil(berry.vm, -1)) { -// be_pushstring(berry.vm, topic); -// be_pushstring(berry.vm, payload); -// be_pcall(berry.vm, 0); -// be_pop(berry.vm, 3); // remove function object -// } else { -// be_pop(berry.vm, 1); // remove nil object -// } -// checkBeTop(); -// } - -// call a function (if exists) of type void -> void -void callBerryFunctionVoid(const char * fname) { - if (nullptr == berry.vm) { return; } - checkBeTop(); - be_getglobal(berry.vm, fname); - if (!be_isnil(berry.vm, -1)) { - be_pcall(berry.vm, 0); - } - be_pop(berry.vm, 1); // remove function or nil object - checkBeTop(); -} - -/*********************************************************************************************\ - * Handlers for Berry calls and async - * -\*********************************************************************************************/ - -const char berry_prog[] PROGMEM = - "" - //"def func(x) for i:1..x print('a') end end " - //"def testreal() return str(1.2+1) end " - //"def noop() log('noop before'); yield(); log('middle after'); yield(); log('noop after'); end " - //"log(\"foobar\") " - - // auto-import modules - "import string " - "import json " - "import gc " - "import tasmota " - // import alias - "import tasmota as t " - - // add `charsinstring(s:string,c:string) -> int`` - // looks for any char in c, and return the position of the first chat - // or -1 if not found - "def charsinstring(s,c) " - "for i:0..size(s)-1 " - "for j:0..size(c)-1 " - "if s[i] == c[j] return i end " - "end " - "end " - "return -1 " - "end " - - // find a key in map, case insensitive, return actual key or nil if not found - "def findkeyi(m,keyi) " - "var keyu = string.toupper(keyi) " - "if classof(m) == map " - "for k:m.keys() " - "if string.toupper(k)==keyu || keyi=='?' " - "return k " - "end " - "end " - "end " - "end " - - // Rules - - "tasmota._operators='=<>!' " // operators used in rules - // Rules comparisong functions - "tasmota._eqstr=/s1,s2-> str(s1) == str(s2) " - "tasmota._neqstr=/s1,s2-> str(s1) != str(s2) " - "tasmota._eq=/f1,f2-> real(f1) == real(f2) " - "tasmota._neq=/f1,f2-> real(f1) != real(f2) " - "tasmota._gt=/f1,f2-> real(f1) > real(f2) " - "tasmota._lt=/f1,f2-> real(f1) < real(f2) " - "tasmota._ge=/f1,f2-> real(f1) >= real(f2) " - "tasmota._le=/f1,f2-> real(f1) <= real(f2) " - - "tasmota._op=[" - "['==',tasmota._eqstr]," - "['!==',tasmota._neqstr]," - "['=',tasmota._eq]," - "['!=',tasmota._neq]," - "['>=',tasmota._ge]," - "['<=',tasmota._le]," - "['>',tasmota._gt]," - "['<',tasmota._lt]," - "] " - "tasmota_rules={} " - "tasmota.rule = def(pat,f) tasmota_rules[pat] = f end " - - // # split the item when there is an operator, returns a list of (left,op,right) - // # ex: "Dimmer>50" -> ["Dimmer",tasmota_gt,"50"] - "tasmota.find_op = def (item) " - "var pos = charsinstring(item, tasmota._operators) " - "if pos>=0 " - "var op_split = string.split(item,pos) " - // #print(op_split) - "var op_left = op_split[0] " - "var op_rest = op_split[1] " - // # iterate through operators - "for op:tasmota._op " - "if string.find(op_rest,op[0]) == 0 " - "var op_func = op[1] " - "var op_right = string.split(op_rest,size(op[0]))[1] " - "return [op_left,op_func,op_right] " - "end " - "end " - "end " - "return [item, nil, nil] " - "end " - - // Rules trigger if match. return true if match, false if not - // Note: condition is not yet managed - "tasmota.try_rule = def (ev, rule, f) " - "var rl_list = tasmota.find_op(rule) " - "var e=ev " - "var rl=string.split(rl_list[0],'#') " - "for it:rl " - "found=findkeyi(e,it) " - "if found == nil " - "return false " - "end " - "e=e[found] " - "end " - // # check if condition is true - "if rl_list[1] " - // # did we find a function - "if !rl_list[1](e,rl_list[2]) " - // # condition is not met - "return false " - "end " - "end " - "f(e,ev) " - "return true " - "end " - // Run rules, i.e. check each individual rule - // Returns true if at least one rule matched, false if none - "tasmota.exec_rules = def (ev_json) " - "var ev = json.load(ev_json) " - "var ret = false " - "if ev == nil " - "log('BRY: ERROR, bad json: '+ev_json, 3) " - "end " - "for r:tasmota_rules.keys() " - "ret = tasmota.try_rule(ev,r,tasmota_rules[r]) || ret " - "end " - "return ret " - "end " - // Not sure how to run `tasmota.exec_rules` from C code, so alias with `_exec_rules()`` - "def _exec_rules(e) return tasmota.exec_rules(e) end " - - // Timers - "tasmota_timers=[] " - "tasmota.timer = def (delay,f) tasmota_timers.push([tasmota.millis(delay),f]) end " - - "def _run_deferred() " - "var i=0 " - "while i