mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
shuntingYard string addition, add tohex() function
This commit is contained in:
@@ -81,9 +81,12 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
} else if (strncmp(p, "abs", 3) == 0) {
|
} else if (strncmp(p, "abs", 3) == 0) {
|
||||||
p += 2;
|
p += 2;
|
||||||
tokens.emplace_back(Token::Type::Unary, "a", 5);
|
tokens.emplace_back(Token::Type::Unary, "a", 5);
|
||||||
|
} else if (strncmp(p, "ln", 2) == 0) {
|
||||||
|
p += 1;
|
||||||
|
tokens.emplace_back(Token::Type::Unary, "l", 5);
|
||||||
} else if (strncmp(p, "log", 3) == 0) {
|
} else if (strncmp(p, "log", 3) == 0) {
|
||||||
p += 2;
|
p += 2;
|
||||||
tokens.emplace_back(Token::Type::Unary, "l", 5);
|
tokens.emplace_back(Token::Type::Unary, "g", 5);
|
||||||
} else if (strncmp(p, "exp", 3) == 0) {
|
} else if (strncmp(p, "exp", 3) == 0) {
|
||||||
p += 2;
|
p += 2;
|
||||||
tokens.emplace_back(Token::Type::Unary, "e", 5);
|
tokens.emplace_back(Token::Type::Unary, "e", 5);
|
||||||
@@ -93,6 +96,9 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
} else if (strncmp(p, "pow", 3) == 0) {
|
} else if (strncmp(p, "pow", 3) == 0) {
|
||||||
p += 2;
|
p += 2;
|
||||||
tokens.emplace_back(Token::Type::Unary, "p", 5);
|
tokens.emplace_back(Token::Type::Unary, "p", 5);
|
||||||
|
} else if (strncmp(p, "tohex", 5) == 0) {
|
||||||
|
p += 4;
|
||||||
|
tokens.emplace_back(Token::Type::Unary, "x", 5);
|
||||||
} else if (strncmp(p, "hex", 3) == 0) {
|
} else if (strncmp(p, "hex", 3) == 0) {
|
||||||
p += 2;
|
p += 2;
|
||||||
tokens.emplace_back(Token::Type::Unary, "h", 5);
|
tokens.emplace_back(Token::Type::Unary, "h", 5);
|
||||||
@@ -102,7 +108,7 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
const auto s = std::string(b, p);
|
const auto s = std::string(b, p);
|
||||||
tokens.emplace_back(Token::Type::String, s, -2);
|
tokens.emplace_back(Token::Type::String, s, -3);
|
||||||
--p;
|
--p;
|
||||||
} else if (*p == '"') {
|
} else if (*p == '"') {
|
||||||
++p;
|
++p;
|
||||||
@@ -132,7 +138,7 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
const auto s = std::string(b, p);
|
const auto s = std::string(b, p);
|
||||||
tokens.emplace_back(Token::Type::Number, s, -4);
|
tokens.emplace_back(Token::Type::Number, s, -2);
|
||||||
--p;
|
--p;
|
||||||
} else {
|
} else {
|
||||||
Token::Type token = Token::Type::Operator;
|
Token::Type token = Token::Type::Operator;
|
||||||
@@ -203,7 +209,7 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
precedence = 1;
|
precedence = 1;
|
||||||
token = Token::Type::Compare;
|
token = Token::Type::Compare;
|
||||||
} else {
|
} else {
|
||||||
precedence = 1;
|
precedence = 2;
|
||||||
token = Token::Type::Unary;
|
token = Token::Type::Unary;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -359,9 +365,6 @@ std::string commands(std::string & expr, bool quotes = true) {
|
|||||||
if (e == std::string::npos) {
|
if (e == std::string::npos) {
|
||||||
e = expr.length();
|
e = expr.length();
|
||||||
}
|
}
|
||||||
while (e > 0 && expr[e - 1] == ' ') { // remove blanks from end
|
|
||||||
e--;
|
|
||||||
}
|
|
||||||
char cmd[COMMAND_MAX_LENGTH];
|
char cmd[COMMAND_MAX_LENGTH];
|
||||||
size_t l = e - f;
|
size_t l = e - f;
|
||||||
if (l >= sizeof(cmd) - 1) {
|
if (l >= sizeof(cmd) - 1) {
|
||||||
@@ -420,6 +423,14 @@ std::string to_string(double d) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// number to hex string
|
||||||
|
std::string to_hex(uint32_t i) {
|
||||||
|
char c[10];
|
||||||
|
snprintf(c, 10, "%02X", i);
|
||||||
|
std::string s = c;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
// RPN calculator
|
// RPN calculator
|
||||||
std::string calculate(const std::string & expr) {
|
std::string calculate(const std::string & expr) {
|
||||||
std::string expr_new = expr;
|
std::string expr_new = expr;
|
||||||
@@ -459,46 +470,57 @@ std::string calculate(const std::string & expr) {
|
|||||||
}
|
}
|
||||||
const auto rhs = stack.back();
|
const auto rhs = stack.back();
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
|
if (token.str[0] == '!') {
|
||||||
|
if (to_logic(rhs) < 0) {
|
||||||
|
}
|
||||||
|
if (to_logic(rhs) >= 0) {
|
||||||
|
stack.push_back(to_logic(rhs) == 0 ? "1" : "0");
|
||||||
|
} else if (isnum(rhs)) {
|
||||||
|
stack.push_back(std::stod(rhs) == 0 ? "1" : "0");
|
||||||
|
} else {
|
||||||
|
emsesp::EMSESP::logger().warning("missing operator");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto rhd = std::stod(rhs);
|
||||||
switch (token.str[0]) {
|
switch (token.str[0]) {
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
case 'm': // Special operator name for unary '-'
|
case 'm': // Special operator name for unary '-'
|
||||||
if (!isnum(rhs)) {
|
stack.push_back(to_string(-1 * rhd));
|
||||||
return "";
|
|
||||||
}
|
|
||||||
stack.push_back(to_string(-1 * std::stod(rhs)));
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
if (to_logic(rhs) < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
stack.push_back(to_logic(rhs) == 0 ? "1" : "0");
|
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
stack.push_back(to_string(std::stoi(rhs)));
|
stack.push_back(to_string(static_cast<int>(rhd)));
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
stack.push_back(to_string(std::round(std::stod(rhs))));
|
stack.push_back(to_string(std::round(rhd)));
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
stack.push_back(to_string(std::abs(std::stod(rhs))));
|
stack.push_back(to_string(std::abs(rhd)));
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
stack.push_back(to_string(std::exp(std::stod(rhs))));
|
stack.push_back(to_string(std::exp(rhd)));
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
stack.push_back(to_string(std::log(std::stod(rhs))));
|
stack.push_back(to_string(std::log(rhd)));
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
stack.push_back(to_string(std::log10(rhd)));
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
stack.push_back(to_string(std::sqrt(std::stod(rhs))));
|
stack.push_back(to_string(std::sqrt(rhd)));
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
stack.push_back(to_string(std::pow(std::stod(rhs), 2)));
|
stack.push_back(to_string(std::pow(rhd, 2)));
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
stack.push_back(to_string(std::stoi(rhs, 0, 16)));
|
stack.push_back(to_string(std::stoi(rhs, 0, 16)));
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
stack.push_back(to_hex(static_cast<int>(rhd)));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Token::Type::Compare: {
|
case Token::Type::Compare: {
|
||||||
@@ -585,38 +607,40 @@ std::string calculate(const std::string & expr) {
|
|||||||
} break;
|
} break;
|
||||||
case Token::Type::Operator: {
|
case Token::Type::Operator: {
|
||||||
// binary operators
|
// binary operators
|
||||||
if (stack.empty() || !isnum(stack.back())) {
|
if (stack.size() < 2) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const auto rhs = std::stod(stack.back());
|
const auto rhs = stack.back();
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
if (stack.empty() || !isnum(stack.back())) {
|
const auto lhs = stack.back();
|
||||||
return "";
|
stack.pop_back();
|
||||||
|
if (token.str[0] == '+' && (!isnum(rhs) || !isnum(lhs))) {
|
||||||
|
stack.push_back(lhs + rhs);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
const auto lhs = std::stod(stack.back());
|
auto lhd = std::stod(lhs);
|
||||||
stack.pop_back();
|
auto rhd = std::stod(rhs);
|
||||||
|
|
||||||
switch (token.str[0]) {
|
switch (token.str[0]) {
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '^':
|
||||||
stack.push_back(to_string(pow(lhs, rhs)));
|
stack.push_back(to_string(pow(lhd, rhd)));
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
stack.push_back(to_string(lhs * rhs));
|
stack.push_back(to_string(lhd * rhd));
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
stack.push_back(to_string(lhs / rhs));
|
stack.push_back(to_string(lhd / rhd));
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
stack.push_back(std::to_string(static_cast<int>(lhs) % static_cast<int>(rhs)));
|
stack.push_back(std::to_string(static_cast<int>(lhd) % static_cast<int>(rhd)));
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
stack.push_back(to_string(lhs + rhs));
|
stack.push_back(to_string(lhd + rhd));
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
stack.push_back(to_string(lhs - rhs));
|
stack.push_back(to_string(lhd - rhd));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
|||||||
if (entityItem.ram == 0 && entityItem.value_type == DeviceValueType::STRING) {
|
if (entityItem.ram == 0 && entityItem.value_type == DeviceValueType::STRING) {
|
||||||
entityItem.raw = new uint8_t[(size_t)entityItem.factor + 1];
|
entityItem.raw = new uint8_t[(size_t)entityItem.factor + 1];
|
||||||
entityItem.data = "";
|
entityItem.data = "";
|
||||||
|
entityItem.uom = 0;
|
||||||
} else if (entityItem.value_type == DeviceValueType::BOOL) {
|
} else if (entityItem.value_type == DeviceValueType::BOOL) {
|
||||||
entityItem.value = EMS_VALUE_DEFAULT_BOOL;
|
entityItem.value = EMS_VALUE_DEFAULT_BOOL;
|
||||||
entityItem.uom = 0;
|
entityItem.uom = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user