auto-sync
This commit is contained in:
parent
d910d0a572
commit
15ab5030cd
|
@ -46,7 +46,10 @@ void FLStack<T, MAXSIZE>::push(T value) {
|
|||
|
||||
template<typename T, int MAXSIZE>
|
||||
T FLStack<T, MAXSIZE>::pop() {
|
||||
return values[--index];
|
||||
if(index==0) {
|
||||
firmwareError("FLStack is empty");
|
||||
}
|
||||
return values[--index];
|
||||
}
|
||||
|
||||
template<typename T, int MAXSIZE>
|
||||
|
|
|
@ -18,14 +18,18 @@ static LENameOrdinalPair leAnd(LE_OPERATOR_AND, "and");
|
|||
static LENameOrdinalPair leOr(LE_OPERATOR_OR, "or");
|
||||
static LENameOrdinalPair leMore(LE_OPERATOR_MORE, ">");
|
||||
static LENameOrdinalPair leMoreOrEqual(LE_OPERATOR_MORE_OR_EQUAL, ">=");
|
||||
static LENameOrdinalPair leNot(LE_OPERATOR_NOT, "not");
|
||||
|
||||
static LENameOrdinalPair leRpm(LE_METHOD_RPM, "rpm");
|
||||
static LENameOrdinalPair leFan(LE_METHOD_FAN, "fan");
|
||||
static LENameOrdinalPair leCoolant(LE_METHOD_COOLANT, "coolant");
|
||||
static LENameOrdinalPair leFanOnSetting(LE_METHOD_FAN_ON_SETTING, "fan_on_setting");
|
||||
static LENameOrdinalPair leFanOffSetting(LE_METHOD_FAN_OFF_SETTING, "fan_off_setting");
|
||||
|
||||
LENameOrdinalPair::LENameOrdinalPair(le_action_e action, const char *name) {
|
||||
this->next = NULL;
|
||||
this->action = action;
|
||||
this->name = name;
|
||||
if (LE_FIRST != NULL) {
|
||||
LE_FIRST->next = this;
|
||||
}
|
||||
this->next = LE_FIRST;
|
||||
LE_FIRST = this;
|
||||
}
|
||||
|
||||
|
@ -82,38 +86,48 @@ void LECalculator::doJob(LEElement *element) {
|
|||
}
|
||||
break;
|
||||
case LE_OPERATOR_LESS: {
|
||||
float v1 = stack.pop();
|
||||
// elements on stack are in reverse order
|
||||
float v2 = stack.pop();
|
||||
float v1 = stack.pop();
|
||||
|
||||
stack.push(v1 < v2);
|
||||
}
|
||||
break;
|
||||
case LE_OPERATOR_NOT: {
|
||||
float v = stack.pop();
|
||||
stack.push(!float2bool(v));
|
||||
}
|
||||
break;
|
||||
case LE_OPERATOR_MORE: {
|
||||
float v1 = stack.pop();
|
||||
// elements on stack are in reverse order
|
||||
float v2 = stack.pop();
|
||||
float v1 = stack.pop();
|
||||
|
||||
stack.push(v1 > v2);
|
||||
}
|
||||
break;
|
||||
case LE_OPERATOR_LESS_OR_EQUAL: {
|
||||
float v1 = stack.pop();
|
||||
// elements on stack are in reverse order
|
||||
float v2 = stack.pop();
|
||||
float v1 = stack.pop();
|
||||
|
||||
stack.push(v1 <= v2);
|
||||
}
|
||||
break;
|
||||
case LE_OPERATOR_MORE_OR_EQUAL: {
|
||||
float v1 = stack.pop();
|
||||
// elements on stack are in reverse order
|
||||
float v2 = stack.pop();
|
||||
float v1 = stack.pop();
|
||||
|
||||
stack.push(v1 >= v2);
|
||||
}
|
||||
break;
|
||||
case LE_UNDEFINED:
|
||||
firmwareError("Undefined not expected here");
|
||||
break;
|
||||
default:
|
||||
firmwareError("Not implemented: %d", element->action);
|
||||
|
||||
stack.push(getLEValue(NULL, element->action));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float LECalculator::getValue() {
|
||||
|
@ -180,7 +194,7 @@ le_action_e parseAction(const char * line) {
|
|||
LENameOrdinalPair *pair = LE_FIRST;
|
||||
while (pair != NULL) {
|
||||
if (strEqualCaseInsensitive(pair->name, line)) {
|
||||
// return pair->action;
|
||||
return pair->action;
|
||||
}
|
||||
pair = pair->next;
|
||||
}
|
||||
|
@ -210,6 +224,13 @@ LEElement * parseExpression(LEElementPool *pool, const char * line) {
|
|||
n->init(LE_NUMERIC_VALUE, atoff(parsingBuffer));
|
||||
} else {
|
||||
le_action_e action = parseAction(parsingBuffer);
|
||||
if (action == LE_UNDEFINED) {
|
||||
/**
|
||||
* Cannot recognize token
|
||||
*/
|
||||
warning((obd_code_e) 0, "unrecognized [%s]", parsingBuffer);
|
||||
return NULL;
|
||||
}
|
||||
n->init(action);
|
||||
}
|
||||
|
||||
|
@ -223,3 +244,9 @@ LEElement * parseExpression(LEElementPool *pool, const char * line) {
|
|||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
#if EFI_PROD_CODE || EFI_SIMULATOR
|
||||
float getLEValue(Engine *engine, le_action_e action) {
|
||||
return NAN;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -10,24 +10,29 @@
|
|||
|
||||
#include "rusefi_enums.h"
|
||||
#include "fl_stack.h"
|
||||
#include "engine.h"
|
||||
|
||||
typedef enum {
|
||||
|
||||
LE_UNDEFINED = 0 ,
|
||||
LE_NUMERIC_VALUE = 1,
|
||||
LE_OPERATOR_LESS = 2,
|
||||
LE_OPERATOR_MORE = 3,
|
||||
LE_OPERATOR_LESS_OR_EQUAL = 4,
|
||||
LE_OPERATOR_MORE_OR_EQUAL = 5,
|
||||
LE_OPERATOR_AND = 6,
|
||||
LE_OPERATOR_OR = 7,
|
||||
LE_OPERATOR_NOT = 8,
|
||||
|
||||
LE_METHOD_RPM = 100,
|
||||
LE_METHOD_COOLANT = 101,
|
||||
LE_METHOD_FAN = 102,
|
||||
LE_METHOD_TIME_SINCE_BOOT = 103,
|
||||
LE_METHOD_FAN_ON_SETTING = 104,
|
||||
LE_METHOD_FAN_OFF_SETTING = 105,
|
||||
|
||||
Force_4b_le_action = ENUM_SIZE_HACK,
|
||||
|
||||
LE_UNDEFINED,
|
||||
LE_NUMERIC_VALUE,
|
||||
LE_OPERATOR_LESS,
|
||||
LE_OPERATOR_MORE,
|
||||
LE_OPERATOR_LESS_OR_EQUAL,
|
||||
LE_OPERATOR_MORE_OR_EQUAL,
|
||||
LE_OPERATOR_AND,
|
||||
LE_OPERATOR_OR,
|
||||
|
||||
LE_METHOD_RPM,
|
||||
LE_METHOD_COOLANT,
|
||||
LE_METHOD_FAN,
|
||||
LE_METHOD_TIME_SINCE_BOOT,
|
||||
|
||||
} le_action_e;
|
||||
|
||||
class LEElement {
|
||||
|
@ -86,4 +91,6 @@ bool isNumeric(const char* line);
|
|||
le_action_e parseAction(const char * line);
|
||||
LEElement * parseExpression(LEElementPool *pool, const char * line);
|
||||
|
||||
float getLEValue(Engine *engine, le_action_e action);
|
||||
|
||||
#endif /* LOGIC_EXPRESSION_H_ */
|
||||
|
|
|
@ -241,5 +241,5 @@ void firmwareError(const char *fmt, ...) {
|
|||
}
|
||||
|
||||
int getRusEfiVersion(void) {
|
||||
return 20141004;
|
||||
return 20141005;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ uint64_t getTimeNowNt(void) {
|
|||
|
||||
void assertEqualsM(const char *msg, float expected, float actual) {
|
||||
if (cisnan(actual) && !cisnan(expected)) {
|
||||
printf("Unexpected: %s %.4f while expected %.4f\r\n", msg, actual, expected);
|
||||
printf("Assert failed: %s %.4f while expected %.4f\r\n", msg, actual, expected);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,21 @@
|
|||
#include "test_logic_expression.h"
|
||||
#include "logic_expression.h"
|
||||
#include "cli_registry.h"
|
||||
#include "engine.h"
|
||||
|
||||
static float mockCoolant;
|
||||
static float mockFan;
|
||||
|
||||
float getLEValue(Engine *engine, le_action_e action) {
|
||||
switch(action) {
|
||||
case LE_METHOD_FAN:
|
||||
return mockFan;
|
||||
case LE_METHOD_COOLANT:
|
||||
return mockCoolant;
|
||||
default:
|
||||
firmwareError("No value for %d", action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void testParsing(void) {
|
||||
|
@ -37,7 +52,7 @@ static void testParsing(void) {
|
|||
LEElementPool pool;
|
||||
|
||||
LEElement *element;
|
||||
element = parseExpression(&pool, "1 3 AND");
|
||||
element = parseExpression(&pool, "1 3 AND not");
|
||||
assertTrue(element != NULL);
|
||||
|
||||
assertEquals(element->action, LE_NUMERIC_VALUE);
|
||||
|
@ -50,10 +65,23 @@ static void testParsing(void) {
|
|||
element = element->next;
|
||||
assertEquals(element->action, LE_OPERATOR_AND);
|
||||
|
||||
element = element->next;
|
||||
assertEquals(element->action, LE_OPERATOR_NOT);
|
||||
|
||||
element = element->next;
|
||||
assertTrue(element == NULL);
|
||||
}
|
||||
|
||||
static void testExpression(const char *line, float expected) {
|
||||
LEElementPool pool;
|
||||
pool.reset();
|
||||
LEElement * element = parseExpression(&pool, line);
|
||||
assertTrueM("Not NULL expected", element != NULL);
|
||||
LECalculator c;
|
||||
c.add(element);
|
||||
assertEqualsM(line, expected, c.getValue());
|
||||
}
|
||||
|
||||
void testLogicExpressions(void) {
|
||||
printf("*************************************************** testLogicExpressions\r\n");
|
||||
|
||||
|
@ -105,8 +133,28 @@ void testLogicExpressions(void) {
|
|||
e = pool.next();
|
||||
e->init(LE_OPERATOR_OR);
|
||||
|
||||
pool.reset();
|
||||
LEElement *element;
|
||||
element = parseExpression(&pool, "fan no_such_method");
|
||||
assertTrueM("NULL expected", element == NULL);
|
||||
|
||||
|
||||
/**
|
||||
* fan = (not fan && coolant > 90) OR (fan && coolant > 85)
|
||||
* fan = fan NOT coolant 90 AND more fan coolant 85 more AND OR
|
||||
*/
|
||||
|
||||
|
||||
mockFan = 0;
|
||||
mockCoolant = 100;
|
||||
|
||||
testExpression("coolant", 100);
|
||||
testExpression("fan", 0);
|
||||
testExpression("fan not", 1);
|
||||
testExpression("coolant 90 >", 1);
|
||||
testExpression("fan not coolant 90 > and", 1);
|
||||
|
||||
|
||||
testExpression("fan NOT coolant 90 > AND fan coolant 85 > AND OR", 1);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue