From c024ef6673b95f8bd5b0bd455bdf20c2b214ec77 Mon Sep 17 00:00:00 2001 From: biver Date: Fri, 25 Feb 2022 21:51:20 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20&(=D0=B8)=20=D0=B8=20|(=D0=B8=D0=BB=D0=B8)=20?= =?UTF-8?q?=D0=B2=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/IoTScenario.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index 4551d091..e22e83d2 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -153,6 +153,13 @@ public: else val.valD = 3.4E+38; break; + case '|': + val.valD = lhs->valD || rhs->valD; + break; + case '&': + val.valD = lhs->valD && rhs->valD; + break; + default: break; } @@ -652,17 +659,19 @@ public: IoTScenario::IoTScenario() { // Задаём стандартные бинарные операторы. // 1 - наименьший приоритет. - BinopPrecedence['='] = 1; - BinopPrecedence[tok_equal] = 3; // == - BinopPrecedence[tok_notequal] = 4; // != - BinopPrecedence[tok_lesseq] = 5; // <= - BinopPrecedence[tok_greateq] = 6; // >= - BinopPrecedence['<'] = 10; - BinopPrecedence['>'] = 10; - BinopPrecedence['+'] = 20; - BinopPrecedence['-'] = 20; - BinopPrecedence['/'] = 35; - BinopPrecedence['*'] = 40; // highest. + BinopPrecedence['='] = 1; + BinopPrecedence['|'] = 5; + BinopPrecedence['&'] = 6; + BinopPrecedence[tok_equal] = 10; // == + BinopPrecedence[tok_notequal] = 11; // != + BinopPrecedence[tok_lesseq] = 15; // <= + BinopPrecedence[tok_greateq] = 16; // >= + BinopPrecedence['<'] = 20; + BinopPrecedence['>'] = 21; + BinopPrecedence['+'] = 25; + BinopPrecedence['-'] = 26; + BinopPrecedence['/'] = 27; + BinopPrecedence['*'] = 28; // highest. } IoTScenario::~IoTScenario() {} \ No newline at end of file From f5de7299ec632b6d2c96739ebb2506e3917ac767 Mon Sep 17 00:00:00 2001 From: biver Date: Fri, 25 Feb 2022 22:44:04 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BF=D1=80=D0=B8=D0=B7=D0=BD=D0=B0=D0=BA=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=B5=D1=80=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/classes/IoTItem.h | 1 + src/classes/IoTItem.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 05a23ffc..337a9911 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -28,6 +28,7 @@ class IoTItem { IoTValue value; // хранение основного значения, котрое обновляется из сценария, execute(), loop() или doByInterval() bool iAmDead = false; // признак необходимости удалить объект из базы + bool iAmLocal = true; // признак локальной переменной virtual IoTGpio* getGpioDriver(); virtual void setValue(IoTValue Value); diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index 0dbedc9b..ab2de760 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -109,6 +109,7 @@ void IoTItem::setValue(IoTValue Value) { externalVariable::externalVariable(String parameters) : IoTItem(parameters) { prevMillis = millis(); // запоминаем текущее значение таймера для выполения doByInterval после int сек + iAmLocal = false; // указываем, что это сущность прилетела из сети Serial.printf("Call from externalVariable: parameters %s %d\n", parameters.c_str(), _interval); } From d047ebf453865e626a81f68119dd51fe0cd82dcc Mon Sep 17 00:00:00 2001 From: biver Date: Sat, 26 Feb 2022 10:50:40 +0300 Subject: [PATCH 3/3] exec --- src/classes/IoTScenario.cpp | 77 ++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index e22e83d2..96247bac 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -31,7 +31,7 @@ ExprAST::~ExprAST() {} IoTValue* ExprAST::exec() {return nullptr;} int ExprAST::setValue(IoTValue *val) {return 0;} // 0 - установка значения не поддерживается наследником bool ExprAST::hasEventIdName(String eventIdName) {return false;} // по умолчанию все узлы не связаны с ИД события, для которого выполняется сценарий -struct IoTValue zeroIotVal; +//struct IoTValue zeroIotVal; /// NumberExprAST - Класс узла выражения для числовых литералов (Например, "1.0"). class NumberExprAST : public ExprAST { @@ -61,24 +61,31 @@ public: class VariableExprAST : public ExprAST { String Name; IoTItem* Item; // ссылка на объект модуля (прямой доступ к идентификатору указанному в сценарии), если получилось найти модуль по ID + bool ItemIsLocal = false; public: - VariableExprAST(const String &name, IoTItem* item) : Name(name), Item(item) {} + VariableExprAST(const String &name, IoTItem* item) : Name(name), Item(item) { + if (item) ItemIsLocal = item->iAmLocal; + } int setValue(IoTValue *val) { - if (Item) { - //Item->value = *val; // устанавливаем значение в связанном Item модуля напрямую - Item->setValue(*val); - } + if (!ItemIsLocal) Item = findIoTItem(Name); + if (Item) Item->setValue(*val); + else return 0; + return 1; } IoTValue* exec() { - if (Item->value.isDecimal) - Serial.printf("Call from VariableExprAST: %s = %f\n", Name.c_str(), Item->value.valD); - else Serial.printf("Call from VariableExprAST: %s = %s\n", Name.c_str(), Item->value.valS.c_str()); - - return &(Item->value); + if (!ItemIsLocal) Item = findIoTItem(Name); + if (Item) { + if (Item->value.isDecimal) + Serial.printf("Call from VariableExprAST: %s = %f\n", Name.c_str(), Item->value.valD); + else Serial.printf("Call from VariableExprAST: %s = %s\n", Name.c_str(), Item->value.valS.c_str()); + return &(Item->value); + } + + return nullptr; // Item не найден. } }; @@ -109,6 +116,8 @@ public: Serial.printf("Call from BinaryExprAST: %s\n", printStr.c_str()); + if (RHS == nullptr || LHS == nullptr) return nullptr; + IoTValue* rhs = RHS->exec(); // получаем значение правого операнда для возможного использования в операции присваивания if (Op == '=' && LHS->setValue(rhs)) { // если установка значения не поддерживается, т.е. слева не переменная, то работаем по другим комбинациям далее @@ -189,22 +198,27 @@ class CallExprAST : public ExprAST { std::vector Args; IoTItem *Item; // ссылка на объект модуля (прямой доступ к идентификатору указанному в сценарии), если получилось найти модуль по ID IoTValue ret; // хранение возвращаемого значения, т.к. возврат по ссылке осуществляется + bool ItemIsLocal = false; public: CallExprAST(const String &callee, String &cmd, std::vector &args, IoTItem *item) - : Callee(callee), Cmd(cmd), Args(args), Item(item) {} + : Callee(callee), Cmd(cmd), Args(args), Item(item) { + if (item) ItemIsLocal = item->iAmLocal; + } IoTValue* exec() { - if (Item) { - std::vector ArgsAsIoTValue; - for (unsigned int i = 0; i < Args.size(); i++) { - IoTValue *tmp = Args[i]->exec(); - if (tmp != nullptr) ArgsAsIoTValue.push_back(*tmp); - else ArgsAsIoTValue.push_back(zeroIotVal); - } - ret = Item->execute(Cmd, ArgsAsIoTValue); // вызываем команду из модуля напрямую с передачей всех аргументов - } else ret = zeroIotVal; - + if (!ItemIsLocal) Item = findIoTItem(Callee); + if (!Item) return nullptr; //ret = zeroIotVal; + + std::vector ArgsAsIoTValue; + for (unsigned int i = 0; i < Args.size(); i++) { + if (Args[i] == nullptr) return nullptr; + IoTValue *tmp = Args[i]->exec(); + if (tmp != nullptr) ArgsAsIoTValue.push_back(*tmp); + else return nullptr; //ArgsAsIoTValue.push_back(zeroIotVal); + } + ret = Item->execute(Cmd, ArgsAsIoTValue); // вызываем команду из модуля напрямую с передачей всех аргументов + if (ret.isDecimal) Serial.printf("Call from CallExprAST ID = %s, Command = %s, exec result = %f\n", Callee.c_str(), Cmd.c_str(), ret.valD); else Serial.printf("Call from CallExprAST ID = %s, Command = %s, exec result = %s\n", Callee.c_str(), Cmd.c_str(), ret.valS.c_str()); return &ret; @@ -241,11 +255,16 @@ public: if (!cond_ret) { Serial.printf("Call from IfExprAST: Skip If\n"); - return &zeroIotVal; + return nullptr; //&zeroIotVal; } - if (cond_ret->isDecimal && cond_ret->valD) res_ret = Then->exec(); - else if (Else) res_ret = Else->exec(); + if (cond_ret->isDecimal && cond_ret->valD) { + if (Then == nullptr) return nullptr; + res_ret = Then->exec(); + } else { + if (Else == nullptr) return nullptr; + res_ret = Else->exec(); + } if (!res_ret) Serial.printf("Call from IfExprAST: Cond result = %f, no body result\n", cond_ret->valD); else if (res_ret->isDecimal) Serial.printf("Call from IfExprAST: Cond result = %f, result = %f\n", cond_ret->valD, res_ret->valD); @@ -275,6 +294,7 @@ public: IoTValue* lastExecValue = nullptr; for (unsigned int i = 0; i < BracketsList.size(); i++) { + if (BracketsList[i] == nullptr) return nullptr; lastExecValue = BracketsList[i]->exec(); } @@ -442,8 +462,11 @@ public: } if (CurTok != '(') { // Обычная переменная. - if (tmpItem) return new VariableExprAST(IdName, tmpItem); - else return new StringExprAST("id " + IdName + " not_found"); + // if (tmpItem) return new VariableExprAST(IdName, tmpItem); + // else return new StringExprAST("id " + IdName + " not_found"); + + // создаем экземпляр переменной в любом случае, даж если не нашли (tmpItem = nulptr), т.к. переменная может придти из сети позже + return new VariableExprAST(IdName, tmpItem); } // Вызов функции.