Berry language improved Tasmota integration

This commit is contained in:
Stephan Hadinger 2021-02-13 12:01:45 +01:00
parent 42c5af1b70
commit 2220b2d3e3
23 changed files with 1081 additions and 461 deletions

View File

@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Support for Eastron SDM72D-M three phase 100A Modbus energy meter (#10862)
- Support for Frysk language translations by Christiaan Heerze
- ESP8266 Fallback to ``*.bin.gz`` binary when OTA upload of ``*.bin`` binary fails
- Berry language improved Tasmota integration
## [9.2.0.6] 20210210
### Changed

View File

@ -1,125 +1,128 @@
extern const bcstring be_const_str_count;
extern const bcstring be_const_str_rad;
extern const bcstring be_const_str_str;
extern const bcstring be_const_str_import;
extern const bcstring be_const_str_opt_connect;
extern const bcstring be_const_str_open;
extern const bcstring be_const_str_codedump;
extern const bcstring be_const_str_imax;
extern const bcstring be_const_str_item;
extern const bcstring be_const_str_splitext;
extern const bcstring be_const_str___upper__;
extern const bcstring be_const_str_byte;
extern const bcstring be_const_str_isfile;
extern const bcstring be_const_str_issubclass;
extern const bcstring be_const_str_iter;
extern const bcstring be_const_str_classname;
extern const bcstring be_const_str_cos;
extern const bcstring be_const_str_number;
extern const bcstring be_const_str_true;
extern const bcstring be_const_str_hex;
extern const bcstring be_const_str_range;
extern const bcstring be_const_str_cosh;
extern const bcstring be_const_str_exp;
extern const bcstring be_const_str_exit;
extern const bcstring be_const_str_list;
extern const bcstring be_const_str_path;
extern const bcstring be_const_str_dot_p;
extern const bcstring be_const_str___iterator__;
extern const bcstring be_const_str_dump;
extern const bcstring be_const_str_deinit;
extern const bcstring be_const_str_size;
extern const bcstring be_const_str_false;
extern const bcstring be_const_str_clock;
extern const bcstring be_const_str_floor;
extern const bcstring be_const_str_module;
extern const bcstring be_const_str_tostring;
extern const bcstring be_const_str_type;
extern const bcstring be_const_str_upvname;
extern const bcstring be_const_str_opt_add;
extern const bcstring be_const_str___lower__;
extern const bcstring be_const_str_pi;
extern const bcstring be_const_str_assert;
extern const bcstring be_const_str_ceil;
extern const bcstring be_const_str_setitem;
extern const bcstring be_const_str_except;
extern const bcstring be_const_str_pow;
extern const bcstring be_const_str_sin;
extern const bcstring be_const_str_traceback;
extern const bcstring be_const_str_calldepth;
extern const bcstring be_const_str_classof;
extern const bcstring be_const_str_init;
extern const bcstring be_const_str_sinh;
extern const bcstring be_const_str_split;
extern const bcstring be_const_str_raise;
extern const bcstring be_const_str_map;
extern const bcstring be_const_str_srand;
extern const bcstring be_const_str_allocated;
extern const bcstring be_const_str_asin;
extern const bcstring be_const_str_int;
extern const bcstring be_const_str_lower;
extern const bcstring be_const_str_var;
extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_deg;
extern const bcstring be_const_str_setrange;
extern const bcstring be_const_str_time;
extern const bcstring be_const_str_real;
extern const bcstring be_const_str_end;
extern const bcstring be_const_str_isdir;
extern const bcstring be_const_str_;
extern const bcstring be_const_str_getcwd;
extern const bcstring be_const_str_attrdump;
extern const bcstring be_const_str_copy;
extern const bcstring be_const_str_imin;
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_top;
extern const bcstring be_const_str_nil;
extern const bcstring be_const_str_push;
extern const bcstring be_const_str_remove;
extern const bcstring be_const_str_compile;
extern const bcstring be_const_str_atan;
extern const bcstring be_const_str_class;
extern const bcstring be_const_str_insert;
extern const bcstring be_const_str_pop;
extern const bcstring be_const_str_tanh;
extern const bcstring be_const_str_chdir;
extern const bcstring be_const_str_load;
extern const bcstring be_const_str_log;
extern const bcstring be_const_str_varname;
extern const bcstring be_const_str_find;
extern const bcstring be_const_str_isinstance;
extern const bcstring be_const_str_type;
extern const bcstring be_const_str_if;
extern const bcstring be_const_str_super;
extern const bcstring be_const_str_break;
extern const bcstring be_const_str_do;
extern const bcstring be_const_str_else;
extern const bcstring be_const_str_for;
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_resize;
extern const bcstring be_const_str_reverse;
extern const bcstring be_const_str_while;
extern const bcstring be_const_str_input;
extern const bcstring be_const_str_sqrt;
extern const bcstring be_const_str_elif;
extern const bcstring be_const_str_log10;
extern const bcstring be_const_str_print;
extern const bcstring be_const_str_continue;
extern const bcstring be_const_str_collect;
extern const bcstring be_const_str_clear;
extern const bcstring be_const_str_rand;
extern const bcstring be_const_str_opt_neq;
extern const bcstring be_const_str_opt_eq;
extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_listdir;
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_sethook;
extern const bcstring be_const_str_tan;
extern const bcstring be_const_str_def;
extern const bcstring be_const_str_char;
extern const bcstring be_const_str_exists;
extern const bcstring be_const_str_join;
extern const bcstring be_const_str_as;
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_try;
extern const bcstring be_const_str_upper;
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_elif;

View File

@ -1,186 +1,190 @@
be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_rad);
be_define_const_str(rad, "rad", 1358899048u, 0, 3, &be_const_str_str);
be_define_const_str(str, "str", 3259748752u, 0, 3, &be_const_str_import);
be_define_const_str(import, "import", 288002260u, 66, 6, NULL);
be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str_open);
be_define_const_str(open, "open", 3546203337u, 0, 4, NULL);
be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, &be_const_str_imax);
be_define_const_str(imax, "imax", 3084515410u, 0, 4, &be_const_str_item);
be_define_const_str(item, "item", 2671260646u, 0, 4, &be_const_str_splitext);
be_define_const_str(splitext, "splitext", 2150391934u, 0, 8, NULL);
be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_byte);
be_define_const_str(byte, "byte", 1683620383u, 0, 4, &be_const_str_isfile);
be_define_const_str(isfile, "isfile", 3131505107u, 0, 6, &be_const_str_issubclass);
be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, &be_const_str_iter);
be_define_const_str(iter, "iter", 3124256359u, 0, 4, NULL);
be_define_const_str(classname, "classname", 1998589948u, 0, 9, &be_const_str_cos);
be_define_const_str(cos, "cos", 4220379804u, 0, 3, &be_const_str_number);
be_define_const_str(number, "number", 467038368u, 0, 6, NULL);
be_define_const_str(true, "true", 1303515621u, 61, 4, NULL);
be_define_const_str(hex, "hex", 4273249610u, 0, 3, &be_const_str_range);
be_define_const_str(range, "range", 4208725202u, 0, 5, NULL);
be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, &be_const_str_exp);
be_define_const_str(exp, "exp", 1923516200u, 0, 3, NULL);
be_define_const_str(exit, "exit", 3454868101u, 0, 4, &be_const_str_list);
be_define_const_str(list, "list", 217798785u, 0, 4, NULL);
be_define_const_str(path, "path", 2223459638u, 0, 4, NULL);
be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str___iterator__);
be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_dump);
be_define_const_str(dump, "dump", 3663001223u, 0, 4, NULL);
be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_size);
be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_false);
be_define_const_str(false, "false", 184981848u, 62, 5, NULL);
be_define_const_str(clock, "clock", 363073373u, 0, 5, &be_const_str_floor);
be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_module);
be_define_const_str(module, "module", 3617558685u, 0, 6, &be_const_str_tostring);
be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, &be_const_str_type);
be_define_const_str(type, "type", 1361572173u, 0, 4, &be_const_str_upvname);
be_define_const_str(upvname, "upvname", 3848760617u, 0, 7, NULL);
be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str___lower__);
be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_pi);
be_define_const_str(pi, "pi", 1213090802u, 0, 2, NULL);
be_define_const_str(assert, "assert", 2774883451u, 0, 6, NULL);
be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_setitem);
be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, &be_const_str_except);
be_define_const_str(except, "except", 950914032u, 69, 6, NULL);
be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_sin);
be_define_const_str(sin, "sin", 3761252941u, 0, 3, &be_const_str_traceback);
be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, NULL);
be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, &be_const_str_classof);
be_define_const_str(classof, "classof", 1796577762u, 0, 7, NULL);
be_define_const_str(init, "init", 380752755u, 0, 4, &be_const_str_sinh);
be_define_const_str(sinh, "sinh", 282220607u, 0, 4, &be_const_str_split);
be_define_const_str(split, "split", 2276994531u, 0, 5, &be_const_str_raise);
be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL);
be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_srand);
be_define_const_str(srand, "srand", 465518633u, 0, 5, NULL);
be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_asin);
be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_int);
be_define_const_str(int, "int", 2515107422u, 0, 3, &be_const_str_lower);
be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_var);
be_define_const_str(var, "var", 2317739966u, 64, 3, NULL);
be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_deg);
be_define_const_str(deg, "deg", 3327754271u, 0, 3, NULL);
be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, &be_const_str_time);
be_define_const_str(time, "time", 1564253156u, 0, 4, NULL);
be_define_const_str(real, "real", 3604983901u, 0, 4, NULL);
be_define_const_str(end, "end", 1787721130u, 56, 3, NULL);
be_define_const_str(isdir, "isdir", 2340917412u, 0, 5, NULL);
be_define_const_str(, "", 2166136261u, 0, 0, NULL);
be_define_const_str(getcwd, "getcwd", 652026575u, 0, 6, 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_imin);
be_define_const_str(imin, "imin", 2714127864u, 0, 4, &be_const_str_system);
be_define_const_str(system, "system", 1226705564u, 0, 6, &be_const_str_top);
be_define_const_str(top, "top", 2802900028u, 0, 3, &be_const_str_nil);
be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL);
be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_remove);
be_define_const_str(remove, "remove", 3683784189u, 0, 6, NULL);
be_define_const_str(compile, "compile", 1000265118u, 0, 7, NULL);
be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_class);
be_define_const_str(class, "class", 2872970239u, 57, 5, NULL);
be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_pop);
be_define_const_str(pop, "pop", 1362321360u, 0, 3, &be_const_str_tanh);
be_define_const_str(tanh, "tanh", 153638352u, 0, 4, NULL);
be_define_const_str(chdir, "chdir", 806634853u, 0, 5, &be_const_str_load);
be_define_const_str(load, "load", 3859241449u, 0, 4, &be_const_str_log);
be_define_const_str(log, "log", 1062293841u, 0, 3, &be_const_str_varname);
be_define_const_str(varname, "varname", 2273276445u, 0, 7, NULL);
be_define_const_str(find, "find", 3186656602u, 0, 4, &be_const_str_isinstance);
be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, &be_const_str_if);
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(super, "super", 4152230356u, 0, 5, &be_const_str_break);
be_define_const_str(break, "break", 3378807160u, 58, 5, &be_const_str_do);
be_define_const_str(do, "do", 1646057492u, 65, 2, &be_const_str_else);
be_define_const_str(else, "else", 3183434736u, 52, 4, &be_const_str_for);
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(concat, "concat", 4124019837u, 0, 6, &be_const_str_resize);
be_define_const_str(resize, "resize", 3514612129u, 0, 6, &be_const_str_reverse);
be_define_const_str(reverse, "reverse", 558918661u, 0, 7, NULL);
be_define_const_str(while, "while", 231090382u, 53, 5, NULL);
be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_sqrt);
be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, &be_const_str_elif);
be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL);
be_define_const_str(log10, "log10", 2346846000u, 0, 5, &be_const_str_print);
be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_continue);
be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL);
be_define_const_str(collect, "collect", 2399039025u, 0, 7, NULL);
be_define_const_str(clear, "clear", 1550717474u, 0, 5, &be_const_str_rand);
be_define_const_str(rand, "rand", 2711325910u, 0, 4, NULL);
be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_opt_eq);
be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, &be_const_str_acos);
be_define_const_str(acos, "acos", 1006755615u, 0, 4, NULL);
be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, &be_const_str_mkdir);
be_define_const_str(mkdir, "mkdir", 2883839448u, 0, 5, &be_const_str_sethook);
be_define_const_str(sethook, "sethook", 3963967276u, 0, 7, &be_const_str_tan);
be_define_const_str(tan, "tan", 2633446552u, 0, 3, &be_const_str_def);
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(char, "char", 2823553821u, 0, 4, &be_const_str_exists);
be_define_const_str(exists, "exists", 1002329533u, 0, 6, &be_const_str_join);
be_define_const_str(join, "join", 3374496889u, 0, 4, &be_const_str_as);
be_define_const_str(as, "as", 1579491469u, 67, 2, NULL);
be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_try);
be_define_const_str(try, "try", 2887626766u, 68, 3, NULL);
be_define_const_str(upper, "upper", 176974407u, 0, 5, &be_const_str_return);
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(elif, "elif", 3232090307u, 51, 4, NULL);
static const bstring* const m_string_table[] = {
(const bstring *)&be_const_str_count,
(const bstring *)&be_const_str_opt_connect,
(const bstring *)&be_const_str_codedump,
(const bstring *)&be_const_str___upper__,
(const bstring *)&be_const_str_classname,
(const bstring *)&be_const_str_true,
(const bstring *)&be_const_str_hex,
(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_exit,
(const bstring *)&be_const_str_path,
(const bstring *)&be_const_str_dot_p,
(const bstring *)&be_const_str_deinit,
(const bstring *)&be_const_str_clock,
(const bstring *)&be_const_str_opt_add,
(const bstring *)&be_const_str_assert,
(const bstring *)&be_const_str_ceil,
(const bstring *)&be_const_str_pow,
(const bstring *)&be_const_str_calldepth,
(const bstring *)&be_const_str_init,
NULL,
(const bstring *)&be_const_str_map,
(const bstring *)&be_const_str_allocated,
(const bstring *)&be_const_str_abs,
(const bstring *)&be_const_str_setrange,
(const bstring *)&be_const_str_real,
(const bstring *)&be_const_str_end,
(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_isdir,
(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_getcwd,
(const bstring *)&be_const_str_attrdump,
(const bstring *)&be_const_str_push,
(const bstring *)&be_const_str_compile,
(const bstring *)&be_const_str_atan,
(const bstring *)&be_const_str_insert,
(const bstring *)&be_const_str_chdir,
(const bstring *)&be_const_str_find,
NULL,
(const bstring *)&be_const_str_super,
(const bstring *)&be_const_str_concat,
(const bstring *)&be_const_str_while,
(const bstring *)&be_const_str_input,
(const bstring *)&be_const_str_log10,
(const bstring *)&be_const_str_collect,
(const bstring *)&be_const_str_clear,
(const bstring *)&be_const_str_opt_neq,
(const bstring *)&be_const_str_listdir,
(const bstring *)&be_const_str_char,
(const bstring *)&be_const_str_format,
(const bstring *)&be_const_str_upper
(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__
};
static const struct bconststrtab m_const_string_table = {
.size = 52,
.count = 104,
.size = 53,
.count = 107,
.table = m_string_table
};

View File

@ -1,21 +1,22 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_map_map) {
{ be_const_key(init, -1), be_const_func(m_init) },
{ be_const_key(remove, 7), be_const_func(m_remove) },
{ be_const_key(find, -1), be_const_func(m_find) },
{ be_const_key(insert, 8), be_const_func(m_insert) },
{ be_const_key(dot_p, 2), be_const_int(0) },
{ be_const_key(insert, -1), be_const_func(m_insert) },
{ be_const_key(remove, -1), be_const_func(m_remove) },
{ be_const_key(tostring, -1), be_const_func(m_tostring) },
{ be_const_key(iter, 5), be_const_func(m_iter) },
{ be_const_key(size, -1), be_const_func(m_size) },
{ be_const_key(tostring, 0), be_const_func(m_tostring) },
{ be_const_key(setitem, 3), be_const_func(m_setitem) },
{ be_const_key(iter, -1), be_const_func(m_iter) },
{ be_const_key(item, -1), be_const_func(m_item) },
{ be_const_key(dot_p, 1), be_const_int(0) },
{ be_const_key(keys, -1), be_const_func(m_keys) },
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
{ be_const_key(find, 0), be_const_func(m_find) },
{ be_const_key(init, -1), be_const_func(m_init) },
{ be_const_key(item, 1), be_const_func(m_item) },
};
static be_define_const_map(
be_class_map_map,
10
11
);
BE_EXPORT_VARIABLE be_define_const_class(

View File

@ -1,18 +1,20 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libstring_map) {
{ be_const_key(hex, 2), be_const_func(str_i2hex) },
{ be_const_key(byte, -1), be_const_func(str_byte) },
{ be_const_key(format, 5), be_const_func(str_format) },
{ be_const_key(find, -1), be_const_func(str_find) },
{ be_const_key(char, 1), be_const_func(str_char) },
{ be_const_key(split, -1), be_const_func(str_split) },
{ be_const_key(tolower, -1), be_const_func(str_tolower) },
{ be_const_key(count, -1), be_const_func(str_count) },
{ be_const_key(hex, -1), be_const_func(str_i2hex) },
{ be_const_key(split, 5), be_const_func(str_split) },
{ be_const_key(byte, -1), be_const_func(str_byte) },
{ be_const_key(char, 6), be_const_func(str_char) },
{ be_const_key(toupper, 1), be_const_func(str_toupper) },
{ be_const_key(find, -1), be_const_func(str_find) },
{ be_const_key(format, -1), be_const_func(str_format) },
};
static be_define_const_map(
m_libstring_map,
7
9
);
static be_define_const_module(

View File

@ -13,7 +13,7 @@
#define BE_GCOBJECT BE_STRING
#define gc_object(o) cast(bgcobject*, o)
#define gc_cast(o, t, T) ((o) && (o)->type == (t) ? (T*)(o) : NULL)
#define gc_cast(o, t, T) ((o) && pgm_read_byte(&(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) (((o)->marked & GC_FIXED) != 0)
#define gc_isfixed(o) ((pgm_read_byte(&(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) (((o)->marked & GC_CONST) != 0)
#define gc_exmark(o) (((o)->marked >> 4) & 0x0F)
#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_setexmark(o, k) ((o)->marked |= (k) << 4)
#define be_isgctype(t) ((t) >= BE_GCOBJECT)

View File

@ -105,7 +105,8 @@ static int next(blexer *lexer)
lr->s = s ? s : &eos;
--lr->len;
}
lexer->cursor = *lr->s++;
// lexer->cursor = *lr->s++; // SH
lexer->cursor = pgm_read_byte(lr->s++);
return lexer->cursor;
}

View File

@ -172,6 +172,37 @@ static int m_iter(bvm *vm)
be_return(vm);
}
static int keys_iter_closure(bvm *vm)
{
/* for better performance, we operate the upvalues
* directly without using by the stack. */
bntvclos *func = var_toobj(vm->cf->func);
bvalue *uv0 = be_ntvclos_upval(func, 0)->value; /* list value */
bvalue *uv1 = be_ntvclos_upval(func, 1)->value; /* iter value */
bmapiter iter = var_toobj(uv1);
bmapnode *next = be_map_next(var_toobj(uv0), &iter);
if (next == NULL) {
be_stop_iteration(vm);
be_return_nil(vm); /* will not be executed */
}
var_setobj(uv1, BE_COMPTR, iter); /* set upvale[1] (iter value) */
/* push next value to top */
var_setobj(vm->top, next->key.type, next->key.v.p);
be_incrtop(vm);
be_return(vm);
}
static int m_keys(bvm *vm)
{
be_pushntvclosure(vm, keys_iter_closure, 2);
be_getmember(vm, 1, ".p");
be_setupval(vm, -2, 0);
be_pushiter(vm, -1);
be_setupval(vm, -3, 1);
be_pop(vm, 2);
be_return(vm);
}
#if !BE_USE_PRECOMPILED_OBJECT
void be_load_maplib(bvm *vm)
{
@ -186,6 +217,7 @@ void be_load_maplib(bvm *vm)
{ "size", m_size },
{ "insert", m_insert },
{ "iter", m_iter },
{ "keys", m_keys },
{ NULL, NULL }
};
be_regclass(vm, "map", members);
@ -203,6 +235,7 @@ class be_class_map (scope: global, name: map) {
size, func(m_size)
insert, func(m_insert)
iter, func(m_iter)
keys, func(m_keys)
}
@const_object_info_end */
#include "../generate/be_fixed_be_class_map.h"

View File

@ -10,6 +10,37 @@
#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 */

View File

@ -31,7 +31,7 @@
#define FUNC_ANONYMOUS 2
/* get binary operator priority */
#define binary_op_prio(op) (binary_op_prio_tab[cast_int(op) - OptAdd])
#define binary_op_prio(op) (pgm_read_byte(&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)

View File

@ -44,9 +44,9 @@ int be_eqstr(bstring *s1, bstring *s2)
if (s1 == s2) { /* short string or the same string */
return 1;
}
slen = s1->slen;
slen = pgm_read_byte(&s1->slen);
/* long string */
if (slen == 255 && slen == s2->slen) {
if (slen == 255 && slen == pgm_read_byte(&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) + str->slen + 1);
be_free(vm, str, sizeof(bsstring) + pgm_read_byte(&str->slen) + 1);
}
/* FNV-1a Hash */
@ -97,7 +97,8 @@ 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)*str++) * 16777619u;
hash = (hash ^ (unsigned char)pgm_read_byte(str)) * 16777619u;
str++;
}
return hash;
}
@ -149,7 +150,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 == s->slen && !strncmp(str, s->s, len)) {
if (len == pgm_read_byte(&s->slen) && !strncmp(str, s->s, len)) {
return (bstring*)s;
}
}
@ -165,7 +166,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 == s->slen && !strncmp(str, sstr(s), len)) {
if (len == pgm_read_byte(&s->slen) && !strncmp(str, sstr(s), len)) {
return s;
}
}
@ -252,7 +253,7 @@ uint32_t be_strhash(const bstring *s)
return cast(bcstring*, s)->hash;
}
#if BE_USE_STR_HASH_CACHE
if (s->slen != 255) {
if (pgm_read_byte(&s->slen) != 255) {
return cast(bsstring*, s)->hash;
}
#endif
@ -265,7 +266,7 @@ const char* be_str2cstr(const bstring *s)
if (gc_isconst(s)) {
return cstr(s);
}
if (s->slen == 255) {
if (pgm_read_byte(&s->slen) == 255) {
return lstr(s);
}
return sstr(s);
@ -276,4 +277,4 @@ void be_str_setextra(bstring *s, int extra)
if (!gc_isconst(s)) {
s->extra = cast(bbyte, extra);
}
}
}

View File

@ -33,7 +33,7 @@ typedef struct {
} bcstring;
#define str_len(_s) \
((_s)->slen == 255 ? cast(blstring*, _s)->llen : (_s)->slen)
(pgm_read_byte(&(_s)->slen) == 255 ? cast(blstring*, _s)->llen : pgm_read_byte(&(_s)->slen))
#define str(_s) be_str2cstr(_s)
#define str_extra(_s) ((_s)->extra)

View File

@ -14,6 +14,7 @@
#include "be_mem.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
#define is_digit(c) ((c) >= '0' && (c) <= '9')
@ -175,7 +176,7 @@ const char* be_pushvfstr(bvm *vm, const char *format, va_list arg)
}
pushstr(vm, format, p - format);
concat2(vm);
switch (p[1]) {
switch (pgm_read_byte(&p[1])) {
case 's': {
const char *s = va_arg(arg, char*);
if (s == NULL) {
@ -338,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; *path != '\0'; ++path) {
if (*path == '/') {
for (p = path - 1; pgm_read_byte(path) != '\0'; ++path) {
if (pgm_read_byte(path) == '/') {
p = path;
}
}
@ -708,6 +709,34 @@ static int str_char(bvm *vm)
be_return_nil(vm);
}
// boolean to select whether we call toupper() or tolower()
static int str_touplower(bvm *vm, bbool up)
{
if (be_top(vm) && be_isstring(vm, 1)) {
const char *p, *s = be_tostring(vm, 1);
size_t len = (size_t)be_strlen(vm, 1);
char *buf, *q;
buf = q = be_pushbuffer(vm, len);
/* convert to lower case */
for (p = s; *p != '\0'; ++p, ++q) {
*q = up ? toupper(*p) : tolower(*p);
}
be_pushnstring(vm, buf, len); /* make escape string from buffer */
be_remove(vm, 2); /* remove buffer */
be_return(vm);
}
be_return_nil(vm);
}
static int str_tolower(bvm *vm) {
return str_touplower(vm, bfalse);
}
static int str_toupper(bvm *vm) {
return str_touplower(vm, btrue);
}
#if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(string) {
be_native_module_function("format", str_format),
@ -716,7 +745,9 @@ be_native_module_attr_table(string) {
be_native_module_function("find", str_find),
be_native_module_function("hex", str_i2hex),
be_native_module_function("byte", str_byte),
be_native_module_function("char", str_char)
be_native_module_function("char", str_char),
be_native_module_function("tolower", str_tolower),
be_native_module_function("toupper", str_toupper),
};
be_define_native_module(string, NULL);
@ -730,6 +761,8 @@ module string (scope: global, depend: BE_USE_STRING_MODULE) {
hex, func(str_i2hex)
byte, func(str_byte)
char, func(str_char)
tolower, func(str_tolower)
toupper, func(str_toupper)
}
@const_object_info_end */
#include "../generate/be_fixed_string.h"

View File

@ -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 (*mid == value) {
return mid[1];
if (pgm_read_word(mid) == value) {
return pgm_read_word(&mid[1]);
}
if (*mid < value) {
if (pgm_read_word(mid) < value) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return *low;
return pgm_read_word(low);
}
static int nextpow(int value)

View File

@ -19,6 +19,9 @@ be_extern_native_module(sys);
be_extern_native_module(debug);
be_extern_native_module(gc);
/* Tasmota specific */
be_extern_native_module(tasmota);
/* user-defined modules declare start */
/* user-defined modules declare end */
@ -52,6 +55,8 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#endif
/* user-defined modules register start */
&be_native_module(tasmota),
/* user-defined modules register end */
NULL /* do not remove */
};

View File

@ -16,44 +16,35 @@
/* standard input and output */
extern "C" {
void serial(const char *sp) {
char s[200];
snprintf_P(s, sizeof(s), "%s", sp);
Serial.printf(s);
Serial.flush();
}
void serial3(const char *sp, uint32_t a, uint32_t b, uint32_t c) {
char s[200];
snprintf_P(s, sizeof(s), "%s 0x%08X 0x%08X 0x%08X\n", sp, a, b, c);
Serial.printf(s);
Serial.flush();
}
void serial2s1(const char *sp, const char * a, const char * b, uint32_t c) {
char s[200];
snprintf_P(s, sizeof(s), "%s '%s' '%s' 0x%08X\n", sp, a, b, c);
Serial.printf(s);
Serial.flush();
int strncmp_PP(const char * str1P, const char * str2P, size_t size)
{
int result = 0;
while (size > 0)
{
char ch1 = pgm_read_byte(str1P++);
char ch2 = pgm_read_byte(str2P++);
result = ch1 - ch2;
if (result != 0 || ch2 == '\0')
{
break;
}
size--;
}
return result;
}
// int strncmp_PP(const char * str1P, const char * str2P, size_t size)
// {
// int result = 0;
// while (size > 0)
// {
// char ch1 = pgm_read_byte(str1P++);
// char ch2 = pgm_read_byte(str2P++);
// result = ch1 - ch2;
// if (result != 0 || ch2 == '\0')
// {
// break;
// }
// size--;
// }
// return result;
// }
//
char * strchr_P(const char *s, int c) {
do {
if (pgm_read_byte(s) == c) {
return (char*)s;
}
} while (pgm_read_byte(s++));
return (0);
}
}
BERRY_API void be_writebuffer(const char *buffer, size_t length)

View File

@ -0,0 +1,34 @@
/********************************************************************
* Tasmota lib
*
* To use: `import tasmota`
*******************************************************************/
#include "be_object.h"
extern int l_getFreeHeap(bvm *vm);
extern int l_publish(bvm *vm);
extern int l_cmd(bvm *vm);
extern int l_getoption(bvm *vm);
extern int l_millis(bvm *vm);
extern int l_timereached(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_function("getfreeheap", l_getFreeHeap),
be_native_module_function("publish", l_publish),
be_native_module_function("cmd", l_cmd),
be_native_module_function("getoption", l_getoption),
be_native_module_function("millis", l_millis),
be_native_module_function("timereached", l_timereached),
};
be_define_native_module(tasmota, 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

View File

@ -8,14 +8,14 @@
#ifndef BERRY_CONF_H
#define BERRY_CONF_H
#include <pgmspace.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void serial(const char *sp);
extern void serial3(const char *sp, uint32_t a, uint32_t b, uint32_t c);
extern void serial2s1(const char *sp, const char *a, const char *b, uint32_t c);
extern int strncmp_PP(const char * str1P, const char * str2P, size_t size);
extern char * strchr_P(const char *s, int c);
#ifdef __cplusplus
}
@ -54,7 +54,11 @@ extern "C" {
* runtime. Enable this macro can greatly optimize RAM usage.
* Default: 1
**/
#define BE_USE_PRECOMPILED_OBJECT 1
#ifdef ESP8266
#define BE_USE_PRECOMPILED_OBJECT 0
#else
#define BE_USE_PRECOMPILED_OBJECT 0 // will enable later when stabilized
#endif
/* Macro: BE_DEBUG_RUNTIME_INFO
* Set runtime error debugging information.
@ -157,7 +161,7 @@ extern "C" {
#define BE_USE_OS_MODULE 0
#define BE_USE_SYS_MODULE 0
#define BE_USE_DEBUG_MODULE 0
#define BE_USE_GC_MODULE 0
#define BE_USE_GC_MODULE 1
/* Macro: BE_EXPLICIT_XXX
* If these macros are defined, the corresponding function will

157
tasmota/berry/tasmota.be Normal file
View File

@ -0,0 +1,157 @@
import json import string
tasmota = module("tasmota")
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
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._operators="=<>!|"
# 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)
pos = charsinstring(item, tasmota._operators)
if pos>=0
op_split = string.split(item,pos)
#print(op_split)
op_left = op_split[0]
op_rest = op_split[1]
# iterate through operators
for op:tasmota._op
if string.find(op_rest,op[0]) == 0
op_func = op[1]
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
def findkeyi(m,keyi)
keyu=string.toupper(keyi)
if classof(m) == map
for k:m.keys()
if string.toupper(k)==keyu || keyi=='?'
return k
end
end
end
end
tasmota.try_rule = def (ev, rule, f)
rl_list = tasmota.find_op(rule)
e=ev
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
tasmota_rules={}
tasmota.rule = def(pat,f) tasmota_rules[pat] = f end
tasmota.exec_rules = def (ev_json)
ev = json.load(ev_json)
if ev == nil
log("ERROR, bad json: "+ev_json, 3)
end
ret = false
for r:tasmota_rules.keys()
ret = tasmota.try_rule(ev,r,tasmota_rules[r]) || ret
end
return ret
end
#- Test
#################################################################
def log(m) print(m) end
def my_rule(e,ev) log("e1="+str(e)+" e2="+str(ev)) end
tasmota.rule("ZBRECEIVED#?#LINKQUALITY", my_rule)
tasmota.rule("ZBRECEIVED#0x1234", my_rule)
tasmota.rule("ZBRECEIVED#?#LINKQUALITY<10", my_rule)
tasmota.rule("Dimmer>50", my_rule)
tasmota.rule("Dimmer=01", my_rule)
tasmota.rule("Color==022600", my_rule)
tasmota.exec_rules('{"Color":"022600"}')
tasmota.exec_rules('{"ZbReceived":{"0x1234":{"Device":"0x1234","LinkQuality":50}}}')
tasmota.exec_rules('{"Dimmer":10}')
# tasmota.rule("DIMMER", my_rule)
# tasmota.rule("DIMMER#DATA#DATA", my_rule)
# tasmota.exec_rules('{"Dimmer":{"Data":50}}')
-#
#-
tasmota.find_op("aaa")
tasmota.find_op("aaa>50")
-#
#-
# Example of backlog equivalent
def backlog(cmd_list)
delay_backlog = tasmota.getoption(34) # in milliseconds
delay = 0
for cmd:cmd_list
tasmota.timer(delay, /-> tasmota.cmd(cmd))
delay = delay + delay_backlog
end
end
br def backlog(cmd_list) delay_backlog = tasmota.getoption(34) delay = 0 for cmd:cmd_list tasmota.timer(delay, /-> tasmota.cmd(cmd)) delay = delay + delay_backlog end end
br backlog( [ "Power 0", "Status 4", "Power 1" ] )
-#

View File

@ -844,35 +844,67 @@ void CmndSetoption(void) {
CmndSetoptionBase(1);
}
// Code called by SetOption and by Berrt
bool SetoptionDecode(uint32_t index, uint32_t *ptype, uint32_t *pindex) {
if (index < 146) {
if (index <= 31) { // SetOption0 .. 31 = Settings.flag
*ptype = 2;
*pindex = index; // 0 .. 31
}
else if (index <= 49) { // SetOption32 .. 49 = Settings.param
*ptype = 1;
*pindex = index -32; // 0 .. 17 (= PARAM8_SIZE -1)
}
else if (index <= 81) { // SetOption50 .. 81 = Settings.flag3
*ptype = 3;
*pindex = index -50; // 0 .. 31
}
else if (index <= 113) { // SetOption82 .. 113 = Settings.flag4
*ptype = 4;
*pindex = index -82; // 0 .. 31
}
else { // SetOption114 .. 145 = Settings.flag5
*ptype = 5;
*pindex = index -114; // 0 .. 31
}
return true;
}
return false;
}
uint32_t GetOption(uint32_t index) {
uint32_t ptype;
uint32_t pindex;
if (SetoptionDecode(index, &ptype, &pindex)) {
if (1 == ptype) {
return Settings.param[pindex];
} else {
uint32_t flag = Settings.flag.data;
if (3 == ptype) {
flag = Settings.flag3.data;
}
else if (4 == ptype) {
flag = Settings.flag4.data;
}
else if (5 == ptype) {
flag = Settings.flag5.data;
}
return bitRead(flag, pindex);
}
} else {
return 0; // fallback
}
}
void CmndSetoptionBase(bool indexed) {
// Allow a command to access a single SetOption by it's command name
// indexed = 0 : No index will be returned attached to the command
// {"ClockDirection":"OFF"}
// indexed = 1 : The SetOption index will be returned with the command
// {"SetOption16":"OFF"}
if (XdrvMailbox.index < 146) {
uint32_t ptype;
uint32_t pindex;
if (XdrvMailbox.index <= 31) { // SetOption0 .. 31 = Settings.flag
ptype = 2;
pindex = XdrvMailbox.index; // 0 .. 31
}
else if (XdrvMailbox.index <= 49) { // SetOption32 .. 49 = Settings.param
ptype = 1;
pindex = XdrvMailbox.index -32; // 0 .. 17 (= PARAM8_SIZE -1)
}
else if (XdrvMailbox.index <= 81) { // SetOption50 .. 81 = Settings.flag3
ptype = 3;
pindex = XdrvMailbox.index -50; // 0 .. 31
}
else if (XdrvMailbox.index <= 113) { // SetOption82 .. 113 = Settings.flag4
ptype = 4;
pindex = XdrvMailbox.index -82; // 0 .. 31
}
else { // SetOption114 .. 145 = Settings.flag5
ptype = 5;
pindex = XdrvMailbox.index -114; // 0 .. 31
}
uint32_t ptype;
uint32_t pindex;
if (SetoptionDecode(XdrvMailbox.index, &ptype, &pindex)) {
if (XdrvMailbox.payload >= 0) {
if (1 == ptype) { // SetOption32 .. 49

View File

@ -370,10 +370,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_MAX };
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
"Thermostat|Chat|TCL";
"Thermostat|Chat|TCL|Berry";
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };

View File

@ -19,7 +19,6 @@
#ifdef USE_BERRY
// #ifdef ESP32
#define XDRV_52 52
@ -67,6 +66,7 @@ void (* const BerryCommand[])(void) PROGMEM = {
class BerrySupport {
public:
bvm *vm = nullptr; // berry vm
bool rules_busy = false; // are we already processing rules, avoid infinite loop
#ifdef USE_BERRY_ASYNC
// Alternate stack for the Berry VM
uint8_t *stack_alloc = nullptr; // stack malloc address
@ -99,25 +99,126 @@ void checkBeTop(void) {
/*********************************************************************************************\
* 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
*
\*********************************************************************************************/
// Berry: `log(string) -> nil`
// Logs the string at LOG_LEVEL_INFO (loglevel=2)
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);
AddLog(LOG_LEVEL_INFO, D_LOG_BERRY "LOG: %s", msg);
be_return(vm); // Return
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
}
be_return_nil(vm); // Return nil when something goes wrong
}
// Berry: `getFreeHeap() -> int`
// ESP object
int32_t l_getFreeHeap(bvm *vm) {
be_pushint(vm, ESP.getFreeHeap());
be_return(vm);
}
// Berry: `printStack() -> nul`
// print stack pointer
@ -128,7 +229,7 @@ int32_t l_getFreeHeap(bvm *vm) {
// }
// Yield
int32_t l_yield(bvm *vm) {
int32_t l_yield(struct bvm *vm) {
#ifdef USE_BERRY_ASYNC
if (berry.ta_cont_ok) { // if no ta_cont address, then ignore
if (setjmp(berry.vm_cont) == 0) { // record the current state
@ -157,25 +258,80 @@ int32_t l_yield(bvm *vm) {
// 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)) {
// AddLog(LOG_LEVEL_DEBUG, D_LOG_BERRY "Calling '%s'", fname);
be_pcall(berry.vm, 0);
be_pop(berry.vm, 1); // remove function object
} else {
// AddLog(LOG_LEVEL_DEBUG, D_LOG_BERRY "Function '%s' not found", fname);
be_pop(berry.vm, 1); // remove nil object
}
be_pop(berry.vm, 1); // remove function or nil object
checkBeTop();
}
void test_input(void) {
int i = 0;
AddLog(LOG_LEVEL_INFO, "test_input stack = 0x%08X", &i);
AddLog(LOG_LEVEL_INFO, PSTR("test_input stack = 0x%08X"), &i);
callBerryFunctionVoid("noop");
}
@ -217,7 +373,7 @@ int32_t callTrampoline(void *func) {
// ----------------------------------
// the call has completed normally, and `yield` was not called
berry.ta_cont_ok = false;
AddLog(LOG_LEVEL_INFO, "Trampo: old stack restored");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: old stack restored"));
// printStack();
} else {
// WARNING
@ -229,7 +385,7 @@ int32_t callTrampoline(void *func) {
// printStack();
berry.ta_cont_ok = true; // Berry can call back Tasmota thread
callBerryFunctionVoid("noop");
AddLog(LOG_LEVEL_INFO, "Trampo: after callBerryFunctionVoid");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: after callBerryFunctionVoid"));
// printStack();
longjmp(berry.ta_cont, -1);
// this part is unreachable (longjmp does not return)
@ -254,23 +410,153 @@ int32_t callTrampoline(void *func) {
*
\*********************************************************************************************/
const char berry_prog[] =
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\") "
// - def l_getFreeHeap() return 1234 end
// - def l_log(m) print(m) end
// Simulate Tasmota module
"class Tasmota "
"def getFreeHeap() return l_getFreeHeap() end "
// "def log(m) return l_log(m) end "
"end "
"tasmota = Tasmota() "
// auto-import modules
"import string "
"import json "
"import gc "
"import tasmota "
// import alias
"import tasmota as t "
"n = 1;"
"def every_second() n = n + 1; if (n % 100 == 10) log('foobar '+str(n)+' free_heap = '+str(tasmota.getFreeHeap())) end end; "
// 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) "
"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) "
"pos = charsinstring(item, tasmota._operators) "
"if pos>=0 "
"op_split = string.split(item,pos) "
// #print(op_split)
"op_left = op_split[0] "
"op_rest = op_split[1] "
// # iterate through operators
"for op:tasmota._op "
"if string.find(op_rest,op[0]) == 0 "
"op_func = op[1] "
"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) "
"rl_list = tasmota.find_op(rule) "
"e=ev "
"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) "
"ev = json.load(ev_json) "
"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() "
"i=0 "
"while i<tasmota_timers.size() "
"if tasmota.timereached(tasmota_timers[i][0]) "
"f=tasmota_timers[i][1] "
"tasmota_timers.remove(i) "
"f() "
"else "
"i=i+1 "
"end "
"end "
"end "
// trigger Garbage Collector
"gc.collect() "
// "n = 1;"
// "def every_second() n = n + 1; if (n % 100 == 10) log('foobar '+str(n)+' free_heap = '+str(tasmota.getfreeheap())) end end; "
;
/*********************************************************************************************\
@ -297,15 +583,14 @@ void BrReset(void) {
uint32_t heap_before = ESP.getFreeHeap();
berry.vm = be_vm_new(); /* create a virtual machine instance */
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_BERRY "Berry VM created, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry VM created, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
// Register functions
be_regfunc(berry.vm, "log", l_logInfo);
be_regfunc(berry.vm, "l_getFreeHeap", l_getFreeHeap);
be_regfunc(berry.vm, PSTR("log"), l_logInfo);
// be_regfunc(berry.vm, "printStack", l_printStack);
be_regfunc(berry.vm, "yield", l_yield);
be_regfunc(berry.vm, PSTR("yield"), l_yield);
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_BERRY "Berry function registered, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry function registered, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
ret_code1 = be_loadstring(berry.vm, berry_prog);
if (ret_code1 != 0) {
@ -313,12 +598,14 @@ void BrReset(void) {
be_pop(berry.vm, 2);
break;
}
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code loaded, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
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 consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
be_pop(berry.vm, 1);
// AddLog(LOG_LEVEL_INFO, PSTR("Get function"));
@ -372,29 +659,29 @@ void BrReset(void) {
#ifdef USE_BERRY_ASYNC
if (berry.vm_cont_ok) {
printStack();
AddLog(LOG_LEVEL_INFO, "Trampo: we need to complete vm exec 1");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: we need to complete vm exec 1"));
if (setjmp(berry.ta_cont) == 0) {
berry.ta_cont_ok = true;
berry.vm_cont_ok = false;
AddLog(LOG_LEVEL_INFO, "Trampo: call exec 1");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: call exec 1"));
longjmp(berry.vm_cont, 1);
}
berry.ta_cont_ok = false;
AddLog(LOG_LEVEL_INFO, "Trampo: returned from exec 1");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: returned from exec 1"));
}
printStack();
if (berry.vm_cont_ok) {
printStack();
AddLog(LOG_LEVEL_INFO, "Trampo: we need to complete vm exec 2");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: we need to complete vm exec 2"));
if (setjmp(berry.ta_cont) == 0) {
berry.ta_cont_ok = true;
berry.vm_cont_ok = false;
AddLog(LOG_LEVEL_INFO, "Trampo: call exec 2");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: call exec 2"));
longjmp(berry.vm_cont, 1);
}
berry.ta_cont_ok = false;
AddLog(LOG_LEVEL_INFO, "Trampo: returned from exec 2");
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: returned from exec 2"));
}
printStack();
#endif // USE_BERRY_ASYNC
@ -419,7 +706,6 @@ void BrReset(void) {
}
#endif // USE_BERRY_ASYNC
}
}
/*********************************************************************************************\
@ -436,16 +722,16 @@ void CmndBrRun(void) {
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), "return (%s)", XdrvMailbox.data);
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, "input", br_cmd, strlen(br_cmd));
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, "input", XdrvMailbox.data, strlen(XdrvMailbox.data));
ret_code = be_loadbuffer(berry.vm, PSTR("input"), XdrvMailbox.data, strlen(XdrvMailbox.data));
}
if (0 != ret_code) break;
@ -459,10 +745,10 @@ void CmndBrRun(void) {
} else {
ret_val = be_tostring(berry.vm, 0);
}
Response_P(PSTR("%s"), ret_val);
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("[%s] %s"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
Response_P(PSTR("{\"" D_PRFX_BR "\":\"[%s] %s\"}"), be_tostring(berry.vm, -2), be_tostring(berry.vm, -1));
be_pop(berry.vm, 2);
}
@ -490,20 +776,22 @@ bool Xdrv52(uint8_t function)
case FUNC_INIT:
BrReset();
break;
case FUNC_EVERY_50_MSECOND:
callBerryFunctionVoid(PSTR("_run_deferred"));
break;
case FUNC_EVERY_100_MSECOND:
// callBerryFunctionVoid("every_100ms");
// ScripterEvery100ms();
callBerryFunctionVoid(PSTR("every_100ms"));
break;
case FUNC_EVERY_SECOND:
// callBerryFunctionVoid("every_second");
// ScriptEverySecond();
callBerryFunctionVoid(PSTR("every_second"));
break;
case FUNC_COMMAND:
result = DecodeCommand(kBrCommands, BerryCommand);
break;
case FUNC_SET_POWER:
break;
// case FUNC_SET_POWER:
// break;
case FUNC_RULES_PROCESS:
result = callBerryRule();
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_ADD_BUTTON:
@ -512,19 +800,12 @@ bool Xdrv52(uint8_t function)
break;
case FUNC_WEB_ADD_HANDLER:
// Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
// Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
// Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);}, script_upload_start);
// Webserver->on("/exs", HTTP_GET, ScriptExecuteUploadSuccess);
break;
#endif // USE_WEBSERVER
case FUNC_SAVE_BEFORE_RESTART:
// if (bitRead(Settings.rule_enabled, 0)) {
// Run_Scripter(">R", 2, 0);
// Scripter_save_pvars();
// }
break;
case FUNC_MQTT_DATA:
// callBerryMqttData();
break;
case FUNC_WEB_SENSOR:
break;
@ -542,5 +823,4 @@ bool Xdrv52(uint8_t function)
return result;
}
// #endif // ESP32
#endif // USE_BERRY

View File

@ -1081,7 +1081,14 @@ void XsnsDriverState(void)
bool XdrvRulesProcess(void)
{
#ifdef USE_BERRY
// events are passed to both Rules engine AND Berry engine
bool rule_handled = XdrvCallDriver(10, FUNC_RULES_PROCESS);
bool berry_handled = XdrvCallDriver(52, FUNC_RULES_PROCESS);
return rule_handled || berry_handled;
#else
return XdrvCallDriver(10, FUNC_RULES_PROCESS);
#endif
}
#ifdef USE_DEBUG_DRIVER