From 15ab5030cdbd85fed3c8c9190868a2cfbd4dbcef Mon Sep 17 00:00:00 2001 From: rusEfi Date: Sun, 5 Oct 2014 09:03:00 -0500 Subject: [PATCH] auto-sync --- firmware/controllers/core/fl_stack.h | 5 +- .../controllers/core/logic_expression.cpp | 51 ++++++++++++++----- firmware/controllers/core/logic_expression.h | 35 ++++++++----- firmware/rusefi.cpp | 2 +- unit_tests/main.cpp | 2 +- unit_tests/test_logic_expression.cpp | 50 +++++++++++++++++- 6 files changed, 115 insertions(+), 30 deletions(-) diff --git a/firmware/controllers/core/fl_stack.h b/firmware/controllers/core/fl_stack.h index dd66e41743..02d07c654c 100644 --- a/firmware/controllers/core/fl_stack.h +++ b/firmware/controllers/core/fl_stack.h @@ -46,7 +46,10 @@ void FLStack::push(T value) { template T FLStack::pop() { - return values[--index]; + if(index==0) { + firmwareError("FLStack is empty"); + } + return values[--index]; } template diff --git a/firmware/controllers/core/logic_expression.cpp b/firmware/controllers/core/logic_expression.cpp index 2f1be543bc..0e89d684b9 100644 --- a/firmware/controllers/core/logic_expression.cpp +++ b/firmware/controllers/core/logic_expression.cpp @@ -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 diff --git a/firmware/controllers/core/logic_expression.h b/firmware/controllers/core/logic_expression.h index 185d2f60dd..ec7700d9e3 100644 --- a/firmware/controllers/core/logic_expression.h +++ b/firmware/controllers/core/logic_expression.h @@ -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_ */ diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index ac4d3f8d5f..054bfc077d 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -241,5 +241,5 @@ void firmwareError(const char *fmt, ...) { } int getRusEfiVersion(void) { - return 20141004; + return 20141005; } diff --git a/unit_tests/main.cpp b/unit_tests/main.cpp index 3185994289..6eba285de4 100644 --- a/unit_tests/main.cpp +++ b/unit_tests/main.cpp @@ -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); } diff --git a/unit_tests/test_logic_expression.cpp b/unit_tests/test_logic_expression.cpp index 68427aa4f3..2101ef732d 100644 --- a/unit_tests/test_logic_expression.cpp +++ b/unit_tests/test_logic_expression.cpp @@ -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); + }