Move out of mapping to increase performance

This commit is contained in:
Stephan Hadinger 2022-09-10 12:05:48 +02:00
parent 5c4aab6dc1
commit 13027cc623
2 changed files with 46 additions and 33 deletions

View File

@ -4,7 +4,6 @@
* To use: `import tasmota`
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#include "be_ctypes.h"
extern struct TasmotaGlobal_t TasmotaGlobal;
@ -55,8 +54,7 @@ extern int l_setpower(bvm *vm);
extern int l_getswitch(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");
extern int tasm_find_op(bvm *vm);
/********************************************************************
** Solidified function: add_driver
@ -2608,7 +2606,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
add_fast_loop, closure(Tasmota_add_fast_loop_closure)
remove_fast_loop, closure(Tasmota_remove_fast_loop_closure)
cmd, closure(Tasmota_cmd_closure)
_find_op, ctype_func(tasm_find_op) // new C version for finding a rule operator
_find_op, func(tasm_find_op) // new C version for finding a rule operator
find_key_i, closure(Tasmota_find_key_i_closure)
find_op, closure(Tasmota_find_op_closure)
add_rule, closure(Tasmota_add_rule_closure)

View File

@ -404,51 +404,66 @@ extern "C" {
// 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;
int32_t tasm_find_op(bvm *vm);
int32_t tasm_find_op(bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
bool second_phase = false;
int32_t ret = -1;
if (top >= 2 && be_isstring(vm, 2)) {
const char *c = be_tostring(vm, 2);
if (top >= 3) {
second_phase = be_tobool(vm, 3);
}
if (!second_phase) {
int32_t idx = 0;
// search for `=`, `==`, `!=`, `!==`, `<`, `<=`, `>`, `>=`
while (*c) {
while (*c && ret < 0) {
switch (c[0]) {
case '=':
case '<':
case '>':
return ret; // anything starting with `=`, `<` or `>` is a valid operator
ret = idx;
break; // anything starting with `=`, `<` or `>` is a valid operator
case '!':
if (c[1] == '=') {
return ret; // needs to start with `!=`
ret = idx; // needs to start with `!=`
}
break;
default:
break;
}
c++;
ret++;
idx++;
}
return -1; // no operator found
} else {
// second phase
switch (c[0]) {
case '<':
case '>':
case '=':
if (c[1] != '=') { return ret + 1; } // `<` or `>` or `=`
else { return ret + 2; } // `<=` or `>=` or `==`
if (c[1] != '=') { ret = 1; } // `<` or `>` or `=`
else { ret = 2; } // `<=` or `>=` or `==`
break;
case '!':
if (c[1] != '=') { return -1; } // this is invalid if isolated `!`
if (c[2] != '=') { return ret + 2; } // `!=`
else { return ret + 3; } // `!==`
if (c[1] != '=') { ; } // this is invalid if isolated `!`
if (c[2] != '=') { ret = 2; } // `!=`
else { ret = 3; } // `!==`
break;
default:
break;
}
return -1;
}
}
be_pushint(vm, ret);
be_return(vm);
}
/*
# test patterns
assert(tasmota._find_op("aaa#bbc==23",false) == 7)
assert(tasmota._find_op("==23",true) == 2)
assert(tasmota._find_op(">23",true) == 1)
assert(tasmota._find_op("aaa#bbc!23",false) == -1)
*/