switch from float to expected<float> (#1862)

This commit is contained in:
Matthew Kennedy 2020-10-06 19:33:00 -07:00 committed by GitHub
parent 7b333e60ea
commit 22a55ce7e6
5 changed files with 37 additions and 46 deletions

View File

@ -140,7 +140,7 @@ void LECalculator::push(le_action_e action, float value) {
} }
} }
static float doBinaryBoolean(le_action_e action, float lhs, float rhs) { static FsioValue doBinaryBoolean(le_action_e action, float lhs, float rhs) {
bool v1 = float2bool(lhs); bool v1 = float2bool(lhs);
bool v2 = float2bool(rhs); bool v2 = float2bool(rhs);
@ -150,11 +150,11 @@ static float doBinaryBoolean(le_action_e action, float lhs, float rhs) {
case LE_OPERATOR_OR: case LE_OPERATOR_OR:
return v1 || v2; return v1 || v2;
default: default:
return NAN; return unexpected;
} }
} }
static float doBinaryNumeric(le_action_e action, float v1, float v2) { static FsioValue doBinaryNumeric(le_action_e action, float v1, float v2) {
// Process based on the action type // Process based on the action type
switch (action) { switch (action) {
case LE_OPERATOR_ADDITION: case LE_OPERATOR_ADDITION:
@ -178,36 +178,31 @@ static float doBinaryNumeric(le_action_e action, float v1, float v2) {
case LE_METHOD_MAX: case LE_METHOD_MAX:
return maxF(v1, v2); return maxF(v1, v2);
default: default:
return NAN; return unexpected;
} }
} }
/** /**
* @return true in case of error, false otherwise * @return true in case of error, false otherwise
*/ */
bool LECalculator::processElement(LEElement *element DECLARE_ENGINE_PARAMETER_SUFFIX) { FsioValue LECalculator::processElement(LEElement *element DECLARE_ENGINE_PARAMETER_SUFFIX) {
#if EFI_PROD_CODE #if EFI_PROD_CODE
efiAssert(CUSTOM_ERR_ASSERT, getCurrentRemainingStack() > 64, "FSIO logic", false); efiAssert(CUSTOM_ERR_ASSERT, getCurrentRemainingStack() > 64, "FSIO logic", unexpected);
#endif #endif
switch (element->action) { switch (element->action) {
// Literal values // Literal values
case LE_NUMERIC_VALUE: case LE_NUMERIC_VALUE:
push(element->action, element->fValue); return element->fValue;
break;
case LE_BOOLEAN_VALUE: case LE_BOOLEAN_VALUE:
push(element->action, element->fValue != 0); return element->fValue != 0;
break;
// Boolean input binary operators // Boolean input binary operators
case LE_OPERATOR_AND: case LE_OPERATOR_AND:
case LE_OPERATOR_OR: { case LE_OPERATOR_OR: {
float v1 = pop(LE_OPERATOR_OR); float v1 = pop(LE_OPERATOR_OR);
float v2 = pop(LE_OPERATOR_OR); float v2 = pop(LE_OPERATOR_OR);
auto result = doBinaryBoolean(element->action, v1, v2); return doBinaryBoolean(element->action, v1, v2);
push(element->action, result);
} }
break;
// Numeric input binary operators // Numeric input binary operators
case LE_OPERATOR_ADDITION: case LE_OPERATOR_ADDITION:
case LE_OPERATOR_SUBTRACTION: case LE_OPERATOR_SUBTRACTION:
@ -223,74 +218,64 @@ bool LECalculator::processElement(LEElement *element DECLARE_ENGINE_PARAMETER_SU
float v2 = pop(element->action); float v2 = pop(element->action);
float v1 = pop(element->action); float v1 = pop(element->action);
auto result = doBinaryNumeric(element->action, v1, v2); return doBinaryNumeric(element->action, v1, v2);
push(element->action, result);
} }
break;
// Boolean input unary operator // Boolean input unary operator
case LE_OPERATOR_NOT: { case LE_OPERATOR_NOT: {
float v = pop(LE_OPERATOR_NOT); float v = pop(LE_OPERATOR_NOT);
push(element->action, !float2bool(v)); return !float2bool(v) ? 1 : 0;
} }
break;
case LE_METHOD_IF: { case LE_METHOD_IF: {
// elements on stack are in reverse order // elements on stack are in reverse order
float vFalse = pop(LE_METHOD_IF); float vFalse = pop(LE_METHOD_IF);
float vTrue = pop(LE_METHOD_IF); float vTrue = pop(LE_METHOD_IF);
float vCond = pop(LE_METHOD_IF); float vCond = pop(LE_METHOD_IF);
push(element->action, vCond != 0 ? vTrue : vFalse); return vCond != 0 ? vTrue : vFalse;
} }
break;
case LE_METHOD_FSIO_SETTING: { case LE_METHOD_FSIO_SETTING: {
float humanIndex = pop(LE_METHOD_FSIO_SETTING); float humanIndex = pop(LE_METHOD_FSIO_SETTING);
int index = (int) humanIndex - 1; int index = (int) humanIndex - 1;
if (index >= 0 && index < FSIO_COMMAND_COUNT) { if (index >= 0 && index < FSIO_COMMAND_COUNT) {
push(element->action, CONFIG(fsio_setting)[index]); return CONFIG(fsio_setting)[index];
} else { } else {
push(element->action, NAN); return unexpected;
} }
} }
break;
case LE_METHOD_FSIO_TABLE: { case LE_METHOD_FSIO_TABLE: {
float i = pop(LE_METHOD_FSIO_TABLE); float i = pop(LE_METHOD_FSIO_TABLE);
float yValue = pop(LE_METHOD_FSIO_TABLE); float yValue = pop(LE_METHOD_FSIO_TABLE);
float xValue = pop(LE_METHOD_FSIO_TABLE); float xValue = pop(LE_METHOD_FSIO_TABLE);
int index = (int) i; int index = (int) i;
if (index < 1 || index > MAX_TABLE_INDEX) { if (index < 1 || index > MAX_TABLE_INDEX) {
push(element->action, NAN); return unexpected;
} else { } else {
if (index == 1) { if (index == 1) {
fsio8_Map3D_f32t *t = &fsioTable1; fsio8_Map3D_f32t *t = &fsioTable1;
push(element->action, t->getValue(xValue, yValue)); return t->getValue(xValue, yValue);
} else { } else {
fsio8_Map3D_u8t *t = fsio8t_tables[index]; fsio8_Map3D_u8t *t = fsio8t_tables[index];
push(element->action, t->getValue(xValue, yValue)); return t->getValue(xValue, yValue);
} }
} }
} }
break;
case LE_METHOD_FSIO_DIGITAL_INPUT: case LE_METHOD_FSIO_DIGITAL_INPUT:
// todo: implement code for digital input!!! // todo: implement code for digital input!!!
return true; return unexpected;
case LE_METHOD_FSIO_ANALOG_INPUT: case LE_METHOD_FSIO_ANALOG_INPUT:
{ {
int index = clampF(0, pop(LE_METHOD_FSIO_ANALOG_INPUT), FSIO_ANALOG_INPUT_COUNT - 1); int index = clampF(0, pop(LE_METHOD_FSIO_ANALOG_INPUT), FSIO_ANALOG_INPUT_COUNT - 1);
push(element->action, getVoltage("fsio", engineConfiguration->fsioAdc[index] PASS_ENGINE_PARAMETER_SUFFIX)); return getVoltage("fsio", engineConfiguration->fsioAdc[index] PASS_ENGINE_PARAMETER_SUFFIX);
} }
break;
case LE_METHOD_KNOCK: case LE_METHOD_KNOCK:
push(element->action, ENGINE(knockCount)); return ENGINE(knockCount);
break;
case LE_UNDEFINED: case LE_UNDEFINED:
warning(CUSTOM_UNKNOWN_FSIO, "FSIO undefined action"); warning(CUSTOM_UNKNOWN_FSIO, "FSIO undefined action");
return true; return unexpected;
default: default:
push(element->action, getEngineValue(element->action PASS_ENGINE_PARAMETER_SUFFIX)); return getEngineValue(element->action PASS_ENGINE_PARAMETER_SUFFIX);
} }
return false;
} }
float LECalculator::getValue2(float selfValue, LEElement *fistElementInList DECLARE_ENGINE_PARAMETER_SUFFIX) { float LECalculator::getValue2(float selfValue, LEElement *fistElementInList DECLARE_ENGINE_PARAMETER_SUFFIX) {
@ -318,11 +303,14 @@ float LECalculator::getValue(float selfValue DECLARE_ENGINE_PARAMETER_SUFFIX) {
if (element->action == LE_METHOD_SELF) { if (element->action == LE_METHOD_SELF) {
push(element->action, selfValue); push(element->action, selfValue);
} else { } else {
bool isError = processElement(element PASS_ENGINE_PARAMETER_SUFFIX); FsioValue result = processElement(element PASS_ENGINE_PARAMETER_SUFFIX);
if (isError) {
if (!result) {
// error already reported // error already reported
return NAN; return NAN;
} }
push(element->action, result.Value);
} }
element = element->next; element = element->next;
counter++; counter++;

View File

@ -63,6 +63,8 @@ typedef enum {
} le_action_e; } le_action_e;
using FsioValue = expected<float>;
class LEElement { class LEElement {
public: public:
LEElement(); LEElement();
@ -113,7 +115,7 @@ public:
int currentCalculationLogPosition; int currentCalculationLogPosition;
private: private:
void push(le_action_e action, float value); void push(le_action_e action, float value);
bool processElement(LEElement *element DECLARE_ENGINE_PARAMETER_SUFFIX); FsioValue processElement(LEElement *element DECLARE_ENGINE_PARAMETER_SUFFIX);
float pop(le_action_e action); float pop(le_action_e action);
LEElement *first; LEElement *first;
calc_stack_t stack; calc_stack_t stack;

View File

@ -113,8 +113,8 @@ static LEElement * mainRelayLogic;
static Logging *logger; static Logging *logger;
#if EFI_PROD_CODE || EFI_SIMULATOR #if EFI_PROD_CODE || EFI_SIMULATOR
float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { FsioValue getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
efiAssert(CUSTOM_ERR_ASSERT, engine!=NULL, "getLEValue", NAN); efiAssert(CUSTOM_ERR_ASSERT, engine!=NULL, "getLEValue", unexpected);
switch (action) { switch (action) {
case LE_METHOD_FAN: case LE_METHOD_FAN:
return enginePins.fanRelay.getLogicValue(); return enginePins.fanRelay.getLogicValue();
@ -162,7 +162,7 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
#include "fsio_getters.def" #include "fsio_getters.def"
default: default:
warning(CUSTOM_FSIO_UNEXPECTED, "FSIO ERROR no data for action=%d", action); warning(CUSTOM_FSIO_UNEXPECTED, "FSIO ERROR no data for action=%d", action);
return NAN; return unexpected;
} }
} }

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include "fsio_core.h" #include "fsio_core.h"
#include "expected.h"
#include "engine.h" #include "engine.h"
#include "table_helper.h" #include "table_helper.h"
#include "system_fsio.h" #include "system_fsio.h"
@ -29,8 +30,8 @@
typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, float, float> fsio8_Map3D_f32t; typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, float, float> fsio8_Map3D_f32t;
typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, uint8_t, float> fsio8_Map3D_u8t; typedef Map3D<FSIO_TABLE_8, FSIO_TABLE_8, uint8_t, float> fsio8_Map3D_u8t;
expected<float> getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX);
float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX);
/** /**
* set_fsio_output_pin 7 PE3 * set_fsio_output_pin 7 PE3
* set_rpn_expression 1 "rpm 0 fsio_setting <" * set_rpn_expression 1 "rpm 0 fsio_setting <"

View File

@ -15,7 +15,7 @@
#define TEST_POOL_SIZE 256 #define TEST_POOL_SIZE 256
float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) { FsioValue getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
switch(action) { switch(action) {
case LE_METHOD_FAN: case LE_METHOD_FAN:
return engine->fsioState.mockFan; return engine->fsioState.mockFan;
@ -36,7 +36,7 @@ float getEngineValue(le_action_e action DECLARE_ENGINE_PARAMETER_SUFFIX) {
#include "fsio_getters.def" #include "fsio_getters.def"
default: default:
firmwareError(OBD_PCM_Processor_Fault, "FSIO: No mock value for %d", action); firmwareError(OBD_PCM_Processor_Fault, "FSIO: No mock value for %d", action);
return NAN; return unexpected;
} }
} }