From f91ad24934aca0c14279a5ed86020e802ad3e8de Mon Sep 17 00:00:00 2001 From: David Crocker Date: Sun, 7 Mar 2021 14:07:51 +0000 Subject: More work on variables and parameters --- src/GCodes/GCodeBuffer/ExpressionParser.cpp | 29 +++++++++++++++++++++++++++++ src/GCodes/GCodeBuffer/ExpressionParser.h | 3 +++ src/GCodes/GCodeBuffer/GCodeBuffer.cpp | 10 ++++++++++ src/GCodes/GCodeBuffer/GCodeBuffer.h | 3 ++- src/GCodes/GCodeMachineState.cpp | 4 ++-- src/GCodes/Variable.h | 3 +++ src/Platform/RepRap.h | 5 ++++- 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.cpp b/src/GCodes/GCodeBuffer/ExpressionParser.cpp index 344810e3..48f5c027 100644 --- a/src/GCodes/GCodeBuffer/ExpressionParser.cpp +++ b/src/GCodes/GCodeBuffer/ExpressionParser.cpp @@ -1031,6 +1031,23 @@ ExpressionValue ExpressionParser::ParseIdentifierExpression(bool evaluate, bool // If we are not evaluating then the object expression doesn't have to exist, so don't retrieve it because that might throw an error if (evaluate) { + // Check for a parameter, local or global variable + if (StringStartsWith(id.c_str(), "param.")) + { + return GetVariableValue(gb.GetVariables(), id.c_str() + strlen("param."), true); + } + + if (StringStartsWith(id.c_str(), "global.")) + { + return GetVariableValue(gb.GetVariables(), id.c_str() + strlen("global."), false); + } + + if (StringStartsWith(id.c_str(), "user.")) + { + return GetVariableValue(reprap.globalVariables, id.c_str() + strlen("user."), false); + } + + // Else assume an object model value ExpressionValue value = reprap.GetObjectValue(context, nullptr, id.c_str()); if (context.ObsoleteFieldQueried() && obsoleteField.IsEmpty()) { @@ -1041,6 +1058,18 @@ ExpressionValue ExpressionParser::ParseIdentifierExpression(bool evaluate, bool return ExpressionValue(nullptr); } +// Get the value of a variable +ExpressionValue ExpressionParser::GetVariableValue(VariableSet& vars, const char *name, bool parameter) THROWS(GCodeException) +{ + const Variable* var = vars.Lookup(name); + if (var != nullptr && (!parameter || var->GetScope() < 0)) + { + return var->GetValue(); + } + + throw ConstructParseException("Unknown variable"); +} + // Parse a quoted string, given that the current character is double-quote // This is almost a copy of InternalGetQuotedString in class StringParser ExpressionValue ExpressionParser::ParseQuotedString() THROWS(GCodeException) diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.h b/src/GCodes/GCodeBuffer/ExpressionParser.h index f48679fc..3dd5f236 100644 --- a/src/GCodes/GCodeBuffer/ExpressionParser.h +++ b/src/GCodes/GCodeBuffer/ExpressionParser.h @@ -13,6 +13,8 @@ #include #include +class VariableSet; + class ExpressionParser { public: @@ -41,6 +43,7 @@ private: ExpressionValue ParseIdentifierExpression(bool evaluate, bool applyLengthOperator) THROWS(GCodeException) pre(readPointer >= 0; isalpha(gb.buffer[readPointer])); ExpressionValue ParseQuotedString() THROWS(GCodeException); + ExpressionValue GetVariableValue(VariableSet& vars, const char *name, bool parameter) THROWS(GCodeException); void ConvertToFloat(ExpressionValue& val, bool evaluate) const THROWS(GCodeException); void ConvertToBool(ExpressionValue& val, bool evaluate) const THROWS(GCodeException); diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp index 21e6c1f2..1feac192 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp @@ -1016,4 +1016,14 @@ void GCodeBuffer::SetParameters(int codeRunning) noexcept PARSER_OPERATION(SetParameters(machineState, codeRunning)); } +VariableSet& GCodeBuffer::GetVariables() const noexcept +{ + GCodeMachineState *mc = machineState; + while (mc->localPush && mc->GetPrevious() != nullptr) + { + mc = mc->GetPrevious(); + } + return mc->variables; +} + // End diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h index 25931cc4..65acf25f 100644 --- a/src/GCodes/GCodeBuffer/GCodeBuffer.h +++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h @@ -49,7 +49,7 @@ public: void Init() noexcept; // Set it up to parse another G-code void Diagnostics(MessageType mtype) noexcept; // Write some debug info - bool Put(char c) noexcept SPEED_CRITICAL; // Add a character to the end + bool Put(char c) noexcept SPEED_CRITICAL; // Add a character to the end #if HAS_LINUX_INTERFACE void PutBinary(const uint32_t *data, size_t len) noexcept; // Add an entire binary G-Code, overwriting any existing content #endif @@ -224,6 +224,7 @@ public: bool WasMotionCommanded() const noexcept { return motionCommanded; } void SetParameters(int codeRunning) noexcept; + VariableSet& GetVariables() const noexcept; Mutex mutex; diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp index e0868f08..bae9873b 100644 --- a/src/GCodes/GCodeMachineState.cpp +++ b/src/GCodes/GCodeMachineState.cpp @@ -20,7 +20,7 @@ GCodeMachineState::GCodeMachineState() noexcept selectedPlane(0), drivesRelative(false), axesRelative(false), doingFileMacro(false), waitWhileCooling(false), runningM501(false), runningM502(false), volumetricExtrusion(false), g53Active(false), runningSystemMacro(false), usingInches(false), - waitingForAcknowledgement(false), messageAcknowledged(false), + waitingForAcknowledgement(false), messageAcknowledged(false), localPush(false), #if HAS_LINUX_INTERFACE lastCodeFromSbc(false), macroStartedByCode(false), fileFinished(false), #endif @@ -45,7 +45,7 @@ GCodeMachineState::GCodeMachineState(GCodeMachineState& prev, bool withinSameFil selectedPlane(prev.selectedPlane), drivesRelative(prev.drivesRelative), axesRelative(prev.axesRelative), doingFileMacro(prev.doingFileMacro), waitWhileCooling(prev.waitWhileCooling), runningM501(prev.runningM501), runningM502(prev.runningM502), volumetricExtrusion(false), g53Active(false), runningSystemMacro(prev.runningSystemMacro), usingInches(prev.usingInches), - waitingForAcknowledgement(false), messageAcknowledged(false), + waitingForAcknowledgement(false), messageAcknowledged(false), localPush(withinSameFile), #if HAS_LINUX_INTERFACE lastCodeFromSbc(prev.lastCodeFromSbc), macroStartedByCode(prev.macroStartedByCode), fileFinished(prev.fileFinished), #endif diff --git a/src/GCodes/Variable.h b/src/GCodes/Variable.h index d6074f52..9054514e 100644 --- a/src/GCodes/Variable.h +++ b/src/GCodes/Variable.h @@ -25,6 +25,9 @@ public: Variable(const char *str, ExpressionValue pVal, int8_t pScope) noexcept; ~Variable(); + ExpressionValue GetValue() const { return val; } + int8_t GetScope() const { return scope; } + private: Variable *next; StringHandle name; diff --git a/src/Platform/RepRap.h b/src/Platform/RepRap.h index b3227255..9e07bf3a 100644 --- a/src/Platform/RepRap.h +++ b/src/Platform/RepRap.h @@ -27,6 +27,7 @@ Licence: GPL #include "RTOSIface/RTOSIface.h" #include "GCodes/GCodeResult.h" #include +#include #if SUPPORT_CAN_EXPANSION # include @@ -177,7 +178,7 @@ public: static uint32_t DoDivide(uint32_t a, uint32_t b) noexcept; // helper function for diagnostic tests static void GenerateBusFault() noexcept; // helper function for diagnostic tests static float SinfCosf(float angle) noexcept; // helper function for diagnostic tests - static float FastSqrtf(float f) noexcept; // helper function for diagnostic tests + static float FastSqrtf(float f) noexcept; // helper function for diagnostic tests void KickHeatTaskWatchdog() noexcept { heatTaskIdleTicks = 0; } @@ -196,6 +197,8 @@ public: void ToolsUpdated() noexcept { ++toolsSeq; } void VolumesUpdated() noexcept { ++volumesSeq; } + VariableSet globalVariables; + protected: DECLARE_OBJECT_MODEL OBJECT_MODEL_ARRAY(boards) -- cgit v1.2.3