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++];
|
|
|
|
}
|