mirror of https://github.com/arendst/Tasmota.git
Berry improve operator detection in rules
This commit is contained in:
parent
3e7cb8460c
commit
5c4aab6dc1
|
@ -4,6 +4,7 @@
|
||||||
* To use: `import tasmota`
|
* To use: `import tasmota`
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include "be_constobj.h"
|
#include "be_constobj.h"
|
||||||
|
#include "be_mapping.h"
|
||||||
#include "be_ctypes.h"
|
#include "be_ctypes.h"
|
||||||
|
|
||||||
extern struct TasmotaGlobal_t TasmotaGlobal;
|
extern struct TasmotaGlobal_t TasmotaGlobal;
|
||||||
|
@ -55,6 +56,7 @@ extern int l_getswitch(bvm *vm);
|
||||||
|
|
||||||
extern int l_i2cenabled(bvm *vm);
|
extern int l_i2cenabled(bvm *vm);
|
||||||
|
|
||||||
|
extern int32_t tasm_find_op(const char* hay, bbool second_phase); BE_FUNC_CTYPE_DECLARE(tasm_find_op, "i", "-sb");
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
** Solidified function: add_driver
|
** Solidified function: add_driver
|
||||||
|
@ -152,22 +154,22 @@ be_local_closure(Tasmota_find_op, /* name */
|
||||||
( &(const bvalue[ 6]) { /* constants */
|
( &(const bvalue[ 6]) { /* constants */
|
||||||
/* K0 */ be_nested_str(string),
|
/* K0 */ be_nested_str(string),
|
||||||
/* K1 */ be_nested_str(_X3D_X3C_X3E_X21),
|
/* K1 */ be_nested_str(_X3D_X3C_X3E_X21),
|
||||||
/* K2 */ be_nested_str(chars_in_string),
|
/* K2 */ be_nested_str(_find_op),
|
||||||
/* K3 */ be_const_int(0),
|
/* K3 */ be_const_int(0),
|
||||||
/* K4 */ be_nested_str(split),
|
/* K4 */ be_nested_str(split),
|
||||||
/* K5 */ be_const_int(1),
|
/* K5 */ be_const_int(1),
|
||||||
}),
|
}),
|
||||||
&be_const_str_find_op,
|
&be_const_str_find_op,
|
||||||
&be_const_str_solidified,
|
&be_const_str_solidified,
|
||||||
( &(const binstruction[42]) { /* code */
|
( &(const binstruction[41]) { /* code */
|
||||||
0xA40A0000, // 0000 IMPORT R2 K0
|
0xA40A0000, // 0000 IMPORT R2 K0
|
||||||
0x580C0001, // 0001 LDCONST R3 K1
|
0x580C0001, // 0001 LDCONST R3 K1
|
||||||
0x8C100102, // 0002 GETMET R4 R0 K2
|
0x8C100102, // 0002 GETMET R4 R0 K2
|
||||||
0x5C180200, // 0003 MOVE R6 R1
|
0x5C180200, // 0003 MOVE R6 R1
|
||||||
0x5C1C0600, // 0004 MOVE R7 R3
|
0x501C0000, // 0004 LDBOOL R7 0 0
|
||||||
0x7C100600, // 0005 CALL R4 3
|
0x7C100600, // 0005 CALL R4 3
|
||||||
0x28140903, // 0006 GE R5 R4 K3
|
0x28140903, // 0006 GE R5 R4 K3
|
||||||
0x78160019, // 0007 JMPF R5 #0022
|
0x78160018, // 0007 JMPF R5 #0021
|
||||||
0x8C140504, // 0008 GETMET R5 R2 K4
|
0x8C140504, // 0008 GETMET R5 R2 K4
|
||||||
0x5C1C0200, // 0009 MOVE R7 R1
|
0x5C1C0200, // 0009 MOVE R7 R1
|
||||||
0x5C200800, // 000A MOVE R8 R4
|
0x5C200800, // 000A MOVE R8 R4
|
||||||
|
@ -176,32 +178,31 @@ be_local_closure(Tasmota_find_op, /* name */
|
||||||
0x941C0B05, // 000D GETIDX R7 R5 K5
|
0x941C0B05, // 000D GETIDX R7 R5 K5
|
||||||
0x8C200102, // 000E GETMET R8 R0 K2
|
0x8C200102, // 000E GETMET R8 R0 K2
|
||||||
0x5C280E00, // 000F MOVE R10 R7
|
0x5C280E00, // 000F MOVE R10 R7
|
||||||
0x5C2C0600, // 0010 MOVE R11 R3
|
0x502C0200, // 0010 LDBOOL R11 1 0
|
||||||
0x50300200, // 0011 LDBOOL R12 1 0
|
0x7C200600, // 0011 CALL R8 3
|
||||||
0x7C200800, // 0012 CALL R8 4
|
0x5C101000, // 0012 MOVE R4 R8
|
||||||
0x5C101000, // 0013 MOVE R4 R8
|
0x28200903, // 0013 GE R8 R4 K3
|
||||||
0x28200903, // 0014 GE R8 R4 K3
|
0x7822000B, // 0014 JMPF R8 #0021
|
||||||
0x7822000B, // 0015 JMPF R8 #0022
|
0x8C200504, // 0015 GETMET R8 R2 K4
|
||||||
0x8C200504, // 0016 GETMET R8 R2 K4
|
0x5C280E00, // 0016 MOVE R10 R7
|
||||||
0x5C280E00, // 0017 MOVE R10 R7
|
0x5C2C0800, // 0017 MOVE R11 R4
|
||||||
0x5C2C0800, // 0018 MOVE R11 R4
|
0x7C200600, // 0018 CALL R8 3
|
||||||
0x7C200600, // 0019 CALL R8 3
|
0x94241103, // 0019 GETIDX R9 R8 K3
|
||||||
0x94241103, // 001A GETIDX R9 R8 K3
|
0x94281105, // 001A GETIDX R10 R8 K5
|
||||||
0x94281105, // 001B GETIDX R10 R8 K5
|
0x602C0012, // 001B GETGBL R11 G18
|
||||||
0x602C0012, // 001C GETGBL R11 G18
|
0x7C2C0000, // 001C CALL R11 0
|
||||||
0x7C2C0000, // 001D CALL R11 0
|
0x40301606, // 001D CONNECT R12 R11 R6
|
||||||
0x40301606, // 001E CONNECT R12 R11 R6
|
0x40301609, // 001E CONNECT R12 R11 R9
|
||||||
0x40301609, // 001F CONNECT R12 R11 R9
|
0x4030160A, // 001F CONNECT R12 R11 R10
|
||||||
0x4030160A, // 0020 CONNECT R12 R11 R10
|
0x80041600, // 0020 RET 1 R11
|
||||||
0x80041600, // 0021 RET 1 R11
|
0x60140012, // 0021 GETGBL R5 G18
|
||||||
0x60140012, // 0022 GETGBL R5 G18
|
0x7C140000, // 0022 CALL R5 0
|
||||||
0x7C140000, // 0023 CALL R5 0
|
0x40180A01, // 0023 CONNECT R6 R5 R1
|
||||||
0x40180A01, // 0024 CONNECT R6 R5 R1
|
0x4C180000, // 0024 LDNIL R6
|
||||||
0x4C180000, // 0025 LDNIL R6
|
0x40180A06, // 0025 CONNECT R6 R5 R6
|
||||||
0x40180A06, // 0026 CONNECT R6 R5 R6
|
0x4C180000, // 0026 LDNIL R6
|
||||||
0x4C180000, // 0027 LDNIL R6
|
0x40180A06, // 0027 CONNECT R6 R5 R6
|
||||||
0x40180A06, // 0028 CONNECT R6 R5 R6
|
0x80040A00, // 0028 RET 1 R5
|
||||||
0x80040A00, // 0029 RET 1 R5
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -1717,63 +1718,6 @@ be_local_closure(Tasmota_load, /* name */
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
|
||||||
** Solidified function: chars_in_string
|
|
||||||
********************************************************************/
|
|
||||||
be_local_closure(Tasmota_chars_in_string, /* name */
|
|
||||||
be_nested_proto(
|
|
||||||
10, /* nstack */
|
|
||||||
4, /* argc */
|
|
||||||
2, /* varg */
|
|
||||||
0, /* has upvals */
|
|
||||||
NULL, /* no upvals */
|
|
||||||
0, /* has sup protos */
|
|
||||||
NULL, /* no sub protos */
|
|
||||||
1, /* has constants */
|
|
||||||
( &(const bvalue[ 2]) { /* constants */
|
|
||||||
/* K0 */ be_const_int(0),
|
|
||||||
/* K1 */ be_const_int(1),
|
|
||||||
}),
|
|
||||||
&be_const_str_chars_in_string,
|
|
||||||
&be_const_str_solidified,
|
|
||||||
( &(const binstruction[31]) { /* code */
|
|
||||||
0x780E0001, // 0000 JMPF R3 #0003
|
|
||||||
0x50100200, // 0001 LDBOOL R4 1 0
|
|
||||||
0x70020000, // 0002 JMP #0004
|
|
||||||
0x50100000, // 0003 LDBOOL R4 0 0
|
|
||||||
0x58140000, // 0004 LDCONST R5 K0
|
|
||||||
0x6018000C, // 0005 GETGBL R6 G12
|
|
||||||
0x5C1C0200, // 0006 MOVE R7 R1
|
|
||||||
0x7C180200, // 0007 CALL R6 1
|
|
||||||
0x14180A06, // 0008 LT R6 R5 R6
|
|
||||||
0x781A0012, // 0009 JMPF R6 #001D
|
|
||||||
0x50180000, // 000A LDBOOL R6 0 0
|
|
||||||
0x581C0000, // 000B LDCONST R7 K0
|
|
||||||
0x6020000C, // 000C GETGBL R8 G12
|
|
||||||
0x5C240400, // 000D MOVE R9 R2
|
|
||||||
0x7C200200, // 000E CALL R8 1
|
|
||||||
0x14200E08, // 000F LT R8 R7 R8
|
|
||||||
0x78220006, // 0010 JMPF R8 #0018
|
|
||||||
0x94200205, // 0011 GETIDX R8 R1 R5
|
|
||||||
0x94240407, // 0012 GETIDX R9 R2 R7
|
|
||||||
0x1C201009, // 0013 EQ R8 R8 R9
|
|
||||||
0x78220000, // 0014 JMPF R8 #0016
|
|
||||||
0x50180200, // 0015 LDBOOL R6 1 0
|
|
||||||
0x001C0F01, // 0016 ADD R7 R7 K1
|
|
||||||
0x7001FFF3, // 0017 JMP #000C
|
|
||||||
0x20200806, // 0018 NE R8 R4 R6
|
|
||||||
0x78220000, // 0019 JMPF R8 #001B
|
|
||||||
0x80040A00, // 001A RET 1 R5
|
|
||||||
0x00140B01, // 001B ADD R5 R5 K1
|
|
||||||
0x7001FFE7, // 001C JMP #0005
|
|
||||||
0x5419FFFE, // 001D LDINT R6 -1
|
|
||||||
0x80040C00, // 001E RET 1 R6
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
/*******************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
** Solidified function: cmd
|
** Solidified function: cmd
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
@ -2655,7 +2599,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
||||||
|
|
||||||
get_power, func(l_getpower)
|
get_power, func(l_getpower)
|
||||||
set_power, func(l_setpower)
|
set_power, func(l_setpower)
|
||||||
get_switch, func(l_getswitch) // depraceted
|
get_switch, func(l_getswitch) // deprecated
|
||||||
get_switches, func(l_getswitch)
|
get_switches, func(l_getswitch)
|
||||||
|
|
||||||
i2c_enabled, func(l_i2cenabled)
|
i2c_enabled, func(l_i2cenabled)
|
||||||
|
@ -2664,7 +2608,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
||||||
add_fast_loop, closure(Tasmota_add_fast_loop_closure)
|
add_fast_loop, closure(Tasmota_add_fast_loop_closure)
|
||||||
remove_fast_loop, closure(Tasmota_remove_fast_loop_closure)
|
remove_fast_loop, closure(Tasmota_remove_fast_loop_closure)
|
||||||
cmd, closure(Tasmota_cmd_closure)
|
cmd, closure(Tasmota_cmd_closure)
|
||||||
chars_in_string, closure(Tasmota_chars_in_string_closure)
|
_find_op, ctype_func(tasm_find_op) // new C version for finding a rule operator
|
||||||
find_key_i, closure(Tasmota_find_key_i_closure)
|
find_key_i, closure(Tasmota_find_key_i_closure)
|
||||||
find_op, closure(Tasmota_find_op_closure)
|
find_op, closure(Tasmota_find_op_closure)
|
||||||
add_rule, closure(Tasmota_add_rule_closure)
|
add_rule, closure(Tasmota_add_rule_closure)
|
||||||
|
|
|
@ -74,28 +74,6 @@ class Tasmota
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# add `chars_in_string(s:string,c:string) -> int``
|
|
||||||
# looks for any char in c, and return the position of the first char
|
|
||||||
# or -1 if not found
|
|
||||||
# inv is optional and inverses the behavior, i.e. look for chars not in the list
|
|
||||||
def chars_in_string(s,c,inv)
|
|
||||||
var inverted = inv ? true : false
|
|
||||||
var i = 0
|
|
||||||
while i < size(s)
|
|
||||||
# for i:0..size(s)-1
|
|
||||||
var found = false
|
|
||||||
var j = 0
|
|
||||||
while j < size(c)
|
|
||||||
# for j:0..size(c)-1
|
|
||||||
if s[i] == c[j] found = true end
|
|
||||||
j += 1
|
|
||||||
end
|
|
||||||
if inverted != found return i end
|
|
||||||
i += 1
|
|
||||||
end
|
|
||||||
return -1
|
|
||||||
end
|
|
||||||
|
|
||||||
# find a key in map, case insensitive, return actual key or nil if not found
|
# find a key in map, case insensitive, return actual key or nil if not found
|
||||||
def find_key_i(m,keyi)
|
def find_key_i(m,keyi)
|
||||||
import string
|
import string
|
||||||
|
@ -115,12 +93,12 @@ class Tasmota
|
||||||
def find_op(item)
|
def find_op(item)
|
||||||
import string
|
import string
|
||||||
var op_chars = '=<>!'
|
var op_chars = '=<>!'
|
||||||
var pos = self.chars_in_string(item, op_chars)
|
var pos = self._find_op(item, false) # initial run
|
||||||
if pos >= 0
|
if pos >= 0
|
||||||
var op_split = string.split(item,pos)
|
var op_split = string.split(item,pos)
|
||||||
var op_left = op_split[0]
|
var op_left = op_split[0]
|
||||||
var op_rest = op_split[1]
|
var op_rest = op_split[1]
|
||||||
pos = self.chars_in_string(op_rest, op_chars, true)
|
pos = self._find_op(op_rest, true)
|
||||||
if pos >= 0
|
if pos >= 0
|
||||||
var op_split2 = string.split(op_rest,pos)
|
var op_split2 = string.split(op_rest,pos)
|
||||||
var op_middle = op_split2[0]
|
var op_middle = op_split2[0]
|
||||||
|
|
|
@ -400,6 +400,59 @@ extern "C" {
|
||||||
be_raise(vm, kTypeError, nullptr);
|
be_raise(vm, kTypeError, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find for an operator in the string
|
||||||
|
// takes a string, an offset to start the search from, and works in 2 modes.
|
||||||
|
// mode1 (false): loog for the first char of an operato
|
||||||
|
// mode2 (true): finds the last char of the operator
|
||||||
|
int32_t tasm_find_op(const char* hay, bbool second_phase) {
|
||||||
|
const char *c = hay; // starting point
|
||||||
|
int32_t ret = 0;
|
||||||
|
if (!second_phase) {
|
||||||
|
// search for `=`, `==`, `!=`, `!==`, `<`, `<=`, `>`, `>=`
|
||||||
|
while (*c) {
|
||||||
|
switch (c[0]) {
|
||||||
|
case '=':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
return ret; // anything starting with `=`, `<` or `>` is a valid operator
|
||||||
|
case '!':
|
||||||
|
if (c[1] == '=') {
|
||||||
|
return ret; // needs to start with `!=`
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return -1; // no operator found
|
||||||
|
} else {
|
||||||
|
switch (c[0]) {
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '=':
|
||||||
|
if (c[1] != '=') { return ret + 1; } // `<` or `>` or `=`
|
||||||
|
else { return ret + 2; } // `<=` or `>=` or `==`
|
||||||
|
case '!':
|
||||||
|
if (c[1] != '=') { return -1; } // this is invalid if isolated `!`
|
||||||
|
if (c[2] != '=') { return ret + 2; } // `!=`
|
||||||
|
else { return ret + 3; } // `!==`
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
# test patterns
|
||||||
|
assert(tasmota._find_op("aaa#bbc==23",false) == 7)
|
||||||
|
assert(tasmota._find_op("==23",true) == 2)
|
||||||
|
assert(tasmota._find_op("aaa#bbc!23",false) == -1)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
// web append with decimal conversion
|
// web append with decimal conversion
|
||||||
int32_t l_webSend(bvm *vm);
|
int32_t l_webSend(bvm *vm);
|
||||||
int32_t l_webSend(bvm *vm) {
|
int32_t l_webSend(bvm *vm) {
|
||||||
|
|
Loading…
Reference in New Issue