auto-sync

This commit is contained in:
rusEfi 2014-10-05 09:03:00 -05:00
parent ca21cb349e
commit b2532d64ae
6 changed files with 115 additions and 30 deletions

View File

@ -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>

View File

@ -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

View File

@ -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_ */

View File

@ -241,5 +241,5 @@ void firmwareError(const char *fmt, ...) {
}
int getRusEfiVersion(void) {
return 20141004;
return 20141005;
}

View File

@ -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);
}

View File

@ -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);
}