Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ExpressionParser.h « GCodeBuffer « GCodes « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 25ad7470bf903aa7b8d885f977b86ca1214a94f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * ExpressionParser.h
 *
 *  Created on: 6 Mar 2020
 *      Author: David
 */

#ifndef SRC_GCODES_GCODEBUFFER_EXPRESSIONPARSER_H_
#define SRC_GCODES_GCODEBUFFER_EXPRESSIONPARSER_H_

#include <RepRapFirmware.h>
#include <ObjectModel/ObjectModel.h>
#include <GCodes/GCodeException.h>

class VariableSet;

class ExpressionParser
{
public:
	ExpressionParser(const GCodeBuffer& p_gb, const char *text, const char *textLimit, int p_column = -1) noexcept;

	ExpressionValue Parse(bool evaluate = true) THROWS(GCodeException);
	bool ParseBoolean() THROWS(GCodeException);
	float ParseFloat() THROWS(GCodeException);
	int32_t ParseInteger() THROWS(GCodeException);
	uint32_t ParseUnsigned() THROWS(GCodeException);
	DriverId ParseDriverId() THROWS(GCodeException);

	// These 4 functions may be removed when we support array-valued expressions more generally
	void ParseFloatArray(float arr[], size_t& length) THROWS(GCodeException);
	void ParseIntArray(int32_t arr[], size_t& length) THROWS(GCodeException);
	void ParseUnsignedArray(uint32_t arr[], size_t& length) THROWS(GCodeException);
	void ParseDriverIdArray(DriverId arr[], size_t& length) THROWS(GCodeException);

	void SkipWhiteSpace() noexcept;
	void CheckForExtraCharacters() THROWS(GCodeException);
	const char *GetEndptr() const noexcept { return currentp; }

private:
	[[noreturn]] void __attribute__((noinline)) ThrowParseException(const char *str) const THROWS(GCodeException);
	[[noreturn]] void __attribute__((noinline)) ThrowParseException(const char *str, const char *param) const THROWS(GCodeException);
	[[noreturn]] void __attribute__((noinline)) ThrowParseException(const char *str, uint32_t param) const THROWS(GCodeException);

	void ParseInternal(ExpressionValue& val, bool evaluate, uint8_t priority) THROWS(GCodeException);
	void ParseExpectKet(ExpressionValue& rslt, bool evaluate, char expectedKet) THROWS(GCodeException);
	void __attribute__((noinline)) ParseNumber(ExpressionValue& rslt) noexcept
		pre(readPointer >= 0; isdigit(gb.buffer[readPointer]));
	void __attribute__((noinline)) ParseIdentifierExpression(ExpressionValue& rslt, bool evaluate, bool applyLengthOperator, bool applyExists) THROWS(GCodeException)
		pre(readPointer >= 0; isalpha(gb.buffer[readPointer]));
	void __attribute__((noinline)) ParseQuotedString(ExpressionValue& rslt) THROWS(GCodeException);

	void ParseArray(size_t& length, function_ref<void(size_t index)> processElement) THROWS(GCodeException);

	void GetVariableValue(ExpressionValue& rslt, const VariableSet *vars, const char *name, bool parameter, bool wantExists) THROWS(GCodeException);

	void ConvertToFloat(ExpressionValue& val, bool evaluate) const THROWS(GCodeException);
	void ConvertToBool(ExpressionValue& val, bool evaluate) const THROWS(GCodeException);
	void ConvertToString(ExpressionValue& val, bool evaluate) noexcept;
	void ConvertToDriverId(ExpressionValue& val, bool evaluate) const THROWS(GCodeException);

	void CheckStack(uint32_t calledFunctionStackUsage) const THROWS(GCodeException);

	// The following must be declared 'noinline' because it allocates a large buffer on the stack and its caller is recursive
	static void __attribute__((noinline)) StringConcat(ExpressionValue &val, ExpressionValue &val2) noexcept;

	void BalanceNumericTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) const THROWS(GCodeException);
	void BalanceTypes(ExpressionValue& val1, ExpressionValue& val2, bool evaluate) THROWS(GCodeException);
	static bool TypeHasNoLiterals(TypeCode t) noexcept;

	int GetColumn() const noexcept;
	char CurrentCharacter() const noexcept;
	void AdvancePointer() noexcept { ++currentp; }		// could check that we havebn't reached endp but we should stop before that happens

	const char *currentp;
	const char * const startp;
	const char * const endp;
	const GCodeBuffer& gb;
	int column;
	String<MaxVariableNameLength> obsoleteField;
};

#endif /* SRC_GCODES_GCODEBUFFER_EXPRESSIONPARSER_H_ */