Berry add module ``python_compat`` to be closer to Python syntax

This commit is contained in:
Stephan Hadinger 2021-10-20 19:04:18 +02:00
parent ab118b5b1c
commit 9f7a52633a
6 changed files with 98 additions and 79 deletions

View File

@ -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]

View File

@ -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),

View File

@ -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);
/********************************************************************/

View File

@ -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;
}

View File

@ -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

View File

@ -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) "