mirror of https://github.com/arendst/Tasmota.git
Merge pull request #13423 from s-hadinger/berry_python_compat
Berry add module ``python_compat`` to be closer to Python syntax
This commit is contained in:
commit
9b8f4e2a16
|
@ -3,8 +3,9 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased] - Development
|
||||
|
||||
## [10.0.0.0]
|
||||
|
||||
## [10.0.0.1]
|
||||
### Added
|
||||
- Berry add module ``python_compat`` to be closer to Python syntax
|
||||
|
||||
## [Released]
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ be_extern_native_module(introspect);
|
|||
be_extern_native_module(strict);
|
||||
|
||||
/* Tasmota specific */
|
||||
be_extern_native_module(python_compat);
|
||||
be_extern_native_module(persist);
|
||||
be_extern_native_module(light);
|
||||
be_extern_native_module(gpio);
|
||||
|
@ -80,6 +81,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
|||
#endif
|
||||
/* user-defined modules register start */
|
||||
|
||||
&be_native_module(python_compat),
|
||||
&be_native_module(path),
|
||||
&be_native_module(persist),
|
||||
&be_native_module(gpio),
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/********************************************************************
|
||||
* Berry python compatibility module
|
||||
*
|
||||
* `import python_compat`
|
||||
*******************************************************************/
|
||||
#include "be_constobj.h"
|
||||
|
||||
/********************************************************************
|
||||
** Solidified function: _anonymous_
|
||||
********************************************************************/
|
||||
be_local_closure(_anonymous_, /* name */
|
||||
be_nested_proto(
|
||||
3, /* nstack */
|
||||
1, /* argc */
|
||||
0, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
0, /* has sup protos */
|
||||
NULL, /* no sub protos */
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 5]) { /* constants */
|
||||
/* K0 */ be_nested_string("global", 503252654, 6),
|
||||
/* K1 */ be_nested_string("True", -841064955, 4),
|
||||
/* K2 */ be_nested_string("False", -1753917960, 5),
|
||||
/* K3 */ be_nested_string("None", 810547195, 4),
|
||||
/* K4 */ be_nested_string("b", -418632219, 1),
|
||||
}),
|
||||
(be_nested_const_str("_anonymous_", 1957281476, 11)),
|
||||
(be_nested_const_str("python_compat.be", -225667571, 16)),
|
||||
( &(const binstruction[10]) { /* code */
|
||||
0xA4060000, // 0000 IMPORT R1 K0
|
||||
0x50080200, // 0001 LDBOOL R2 1 0
|
||||
0x90060202, // 0002 SETMBR R1 K1 R2
|
||||
0x50080000, // 0003 LDBOOL R2 0 0
|
||||
0x90060402, // 0004 SETMBR R1 K2 R2
|
||||
0x4C080000, // 0005 LDNIL R2
|
||||
0x90060602, // 0006 SETMBR R1 K3 R2
|
||||
0x60080015, // 0007 GETGBL R2 G21
|
||||
0x90060802, // 0008 SETMBR R1 K4 R2
|
||||
0x80040000, // 0009 RET 1 R0
|
||||
})
|
||||
)
|
||||
);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/********************************************************************
|
||||
** Solidified module: python_compat
|
||||
********************************************************************/
|
||||
be_local_module(python_compat,
|
||||
"python_compat",
|
||||
be_nested_map(1,
|
||||
( (struct bmapnode*) &(const bmapnode[]) {
|
||||
{ be_nested_key("init", 380752755, 4, -1), be_const_closure(_anonymous__closure) },
|
||||
}))
|
||||
);
|
||||
BE_EXPORT_VARIABLE be_define_const_native_module(python_compat, NULL);
|
||||
/********************************************************************/
|
|
@ -877,6 +877,30 @@ static void primary_expr(bparser *parser, bexpdesc *e)
|
|||
}
|
||||
}
|
||||
|
||||
/* parse a single string literal as parameter */
|
||||
static void call_single_string_expr(bparser *parser, bexpdesc *e)
|
||||
{
|
||||
bexpdesc arg;
|
||||
bfuncinfo *finfo = parser->finfo;
|
||||
int base;
|
||||
|
||||
/* func 'string_literal' */
|
||||
check_var(parser, e);
|
||||
if (e->type == ETMEMBER) {
|
||||
push_error(parser, "method not allowed for string prefix");
|
||||
}
|
||||
|
||||
base = be_code_nextreg(finfo, e); /* allocate a new base reg if not at top already */
|
||||
simple_expr(parser, &arg);
|
||||
be_code_nextreg(finfo, &arg); /* move result to next reg */
|
||||
|
||||
be_code_call(finfo, base, 1); /* only one arg */
|
||||
if (e->type != ETREG) {
|
||||
e->type = ETREG;
|
||||
e->v.idx = base;
|
||||
}
|
||||
}
|
||||
|
||||
static void suffix_expr(bparser *parser, bexpdesc *e)
|
||||
{
|
||||
primary_expr(parser, e);
|
||||
|
@ -891,6 +915,9 @@ static void suffix_expr(bparser *parser, bexpdesc *e)
|
|||
case OptLSB: /* '[' index */
|
||||
index_expr(parser, e);
|
||||
break;
|
||||
case TokenString:
|
||||
call_single_string_expr(parser, e); /* " string literal */
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -990,6 +990,7 @@
|
|||
//#define USE_WEBCAM // Add support for webcam
|
||||
|
||||
#define USE_BERRY // Enable Berry scripting language
|
||||
#define USE_BERRY_PYTHON_COMPAT // Enable by default `import python_compat`
|
||||
#define USE_BERRY_TIMEOUT 4000 // Timeout in ms, will raise an exception if running time exceeds this timeout
|
||||
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
|
||||
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
|
||||
|
|
|
@ -26,65 +26,18 @@
|
|||
\*********************************************************************************************/
|
||||
|
||||
const char berry_prog[] =
|
||||
"import persist "
|
||||
// create a 'ntv' module to allow functions to be registered in a safe namespace
|
||||
// "ntv = module('ntv') "
|
||||
|
||||
// auto-import modules
|
||||
// // import alias
|
||||
#ifdef USE_BERRY_PYTHON_COMPAT
|
||||
// enable python syntax compatibility mode
|
||||
"import python_compat "
|
||||
#endif
|
||||
// persistance module
|
||||
"import persist "
|
||||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
"import energy "
|
||||
#endif
|
||||
|
||||
|
||||
// // Force gc and return allocated memory
|
||||
// "def gc() "
|
||||
// "import gc "
|
||||
// "gc.collect() "
|
||||
// "return gc.allocated() "
|
||||
// // "end "
|
||||
// // simple wrapper to load a file
|
||||
// // prefixes '/' if needed, and simpler to use than `compile()`
|
||||
// "def load(f) "
|
||||
// "import string "
|
||||
// "try "
|
||||
// // check that the file ends with '.be' of '.bec'
|
||||
// "var fl = string.split(f,'.') "
|
||||
// "if (size(fl) <= 1 || (fl[-1] != 'be' && fl[-1] != 'bec')) "
|
||||
// "raise \"file extension is not '.be' or '.bec'\" "
|
||||
// "end "
|
||||
// "var native = f[size(f)-1] == 'c' "
|
||||
// // add prefix if needed
|
||||
// "if f[0] != '/' f = '/' + f end "
|
||||
// // load - works the same for .be and .bec
|
||||
// "var c = compile(f,'file') "
|
||||
// // save the compiled bytecode
|
||||
// "if !native "
|
||||
// "try "
|
||||
// "self.save(f+'c', c) "
|
||||
// "except .. as e "
|
||||
// "self.log(string.format('BRY: could not save compiled file %s (%s)',f+'c',e)) "
|
||||
// "end "
|
||||
// "end "
|
||||
// // call the compiled code
|
||||
// "c() "
|
||||
// "self.log(string.format(\"BRY: sucessfully loaded '%s'\",f)) "
|
||||
// "except .. as e "
|
||||
// "raise \"io_error\",string.format(\"Could not load file '%s'\",f) "
|
||||
// "end "
|
||||
|
||||
// "end "
|
||||
|
||||
|
||||
// // Monkey patch `Driver` class - To be continued
|
||||
// "class Driver2 : Driver "
|
||||
// "def add_cmd(c, f) "
|
||||
// "var tasmota = self.get_tasmota() "
|
||||
// "tasmota.add_cmd(c, / cmd, idx, payload, payload_json -> f(self, cmd, idx, payload, payload_json)) "
|
||||
// "end "
|
||||
// "end "
|
||||
// "Driver = Driver2 "
|
||||
|
||||
// Instantiate tasmota object
|
||||
"tasmota = Tasmota() "
|
||||
"def log(m,l) tasmota.log(m,l) end "
|
||||
|
@ -97,29 +50,6 @@ const char berry_prog[] =
|
|||
|
||||
#endif // USE_LVGL
|
||||
|
||||
// Wire class
|
||||
// "class Wire : Wire_ntv "
|
||||
// // read bytes as `bytes()` object
|
||||
// "def read_bytes(addr,reg,size) "
|
||||
// "self._begin_transmission(addr) "
|
||||
// "self._write(reg) "
|
||||
// "self._end_transmission(false) "
|
||||
// "self._request_from(addr,size) "
|
||||
// "var ret=bytes(size) "
|
||||
// "while (self._available()) "
|
||||
// "ret..self._read() "
|
||||
// "end "
|
||||
// "return ret "
|
||||
// "end "
|
||||
// // write bytes from `bytes` object
|
||||
// "def write_bytes(addr,reg,b) "
|
||||
// "self._begin_transmission(addr) "
|
||||
// "self._write(reg) "
|
||||
// "self._write(b) "
|
||||
// "self._end_transmission() "
|
||||
// "end "
|
||||
// "end "
|
||||
|
||||
#ifdef USE_I2C
|
||||
"tasmota.wire1 = Wire(1) "
|
||||
"tasmota.wire2 = Wire(2) "
|
||||
|
|
Loading…
Reference in New Issue