fome-fw/firmware/controllers/core/logic_expression.cpp

154 lines
2.5 KiB
C++
Raw Normal View History

2014-10-03 12:05:03 -07:00
/**
* @file logic_expression.cpp
*
* @date Oct 3, 2014
* @author Andrey Belomutskiy, (c) 2012-2014
*/
#include "main.h"
#include "logic_expression.h"
LEElement::LEElement() {
action = LE_UNDEFINED;
next = NULL;
}
//void LEElement::init(le_action_e action, int iValue) {
// this->action = action;
// this->iValue = iValue;
//}
void LEElement::init(le_action_e action) {
this->action = action;
}
void LEElement::init(le_action_e action, float fValue) {
this->action = action;
this->fValue = fValue;
}
LECalculator::LECalculator() {
2014-10-03 15:03:01 -07:00
reset();
}
void LECalculator::reset() {
2014-10-03 12:05:03 -07:00
first = NULL;
2014-10-03 15:03:01 -07:00
stack.reset();
2014-10-03 12:05:03 -07:00
}
2014-10-03 14:03:00 -07:00
static bool float2bool(float v) {
return v != 0;
}
2014-10-03 12:05:03 -07:00
2014-10-03 14:03:00 -07:00
void LECalculator::doJob(LEElement *element) {
switch (element->action) {
2014-10-03 12:05:03 -07:00
2014-10-03 14:03:00 -07:00
case LE_NUMERIC_VALUE:
2014-10-03 12:05:03 -07:00
stack.push(element->fValue);
2014-10-03 14:03:00 -07:00
break;
case LE_OPERATOR_AND: {
float v1 = stack.pop();
float v2 = stack.pop();
stack.push(float2bool(v1) && float2bool(v2));
}
break;
case LE_OPERATOR_OR: {
float v1 = stack.pop();
float v2 = stack.pop();
stack.push(float2bool(v1) || float2bool(v2));
}
break;
case LE_OPERATOR_LESS: {
float v1 = stack.pop();
float v2 = stack.pop();
stack.push(v1 < v2);
}
break;
case LE_OPERATOR_MORE: {
float v1 = stack.pop();
float v2 = stack.pop();
stack.push(v1 > v2);
}
break;
case LE_OPERATOR_LESS_OR_EQUAL: {
float v1 = stack.pop();
float v2 = stack.pop();
2014-10-03 12:05:03 -07:00
2014-10-03 14:03:00 -07:00
stack.push(v1 <= v2);
}
break;
case LE_OPERATOR_MORE_OR_EQUAL: {
float v1 = stack.pop();
float v2 = stack.pop();
stack.push(v1 >= v2);
}
break;
default:
firmwareError("Not implemented: %d", element->action);
}
}
2014-10-03 12:05:03 -07:00
2014-10-03 14:03:00 -07:00
float LECalculator::getValue() {
LEElement *element = first;
stack.reset();
while (element != NULL) {
doJob(element);
2014-10-03 12:05:03 -07:00
element = element->next;
}
return stack.pop();
}
void LECalculator::add(LEElement *element) {
if (first == NULL) {
first = element;
} else {
LEElement *last = first;
while (last->next != NULL) {
last = last->next;
}
last->next = element;
}
}
2014-10-03 15:03:01 -07:00
LEElementPool::LEElementPool() {
reset();
}
void LEElementPool::reset() {
index = 0;
}
LEElement *LEElementPool::next() {
return &pool[index++];
}
2014-10-04 08:03:38 -07:00
const char *processToken(const char *line, char *buffer) {
while (line[0] != 0 && line[0] == ' ') {
line++;
}
if (line[0] == 0) {
return NULL;
}
int tokenLen = indexOf(line, ' ');
if (tokenLen == -1) {
// no space - the whole remaining line is the token
strcpy(buffer, line);
return line + strlen(buffer);
}
strncpy(buffer, line, tokenLen);
buffer[tokenLen] = 0;
line += tokenLen;
return line;
}