OpenShot Library | OpenShotAudio 0.2.2
juce_Expression.h
1
2/** @weakgroup juce_core-maths
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 A class for dynamically evaluating simple numeric expressions.
33
34 This class can parse a simple C-style string expression involving floating point
35 numbers, named symbols and functions. The basic arithmetic operations of +, -, *, /
36 are supported, as well as parentheses, and any alphanumeric identifiers are
37 assumed to be named symbols which will be resolved when the expression is
38 evaluated.
39
40 Expressions which use identifiers and functions require a subclass of
41 Expression::Scope to be supplied when evaluating them, and this object
42 is expected to be able to resolve the symbol names and perform the functions that
43 are used.
44
45 @tags{Core}
46*/
48{
49public:
50 //==============================================================================
51 /** Creates a simple expression with a value of 0. */
52 Expression();
53
54 /** Destructor. */
56
57 /** Creates a copy of an expression. */
58 Expression (const Expression&);
59
60 /** Copies another expression. */
61 Expression& operator= (const Expression&);
62
63 /** Move constructor */
64 Expression (Expression&&) noexcept;
65
66 /** Move assignment operator */
67 Expression& operator= (Expression&&) noexcept;
68
69 /** Creates a simple expression with a specified constant value. */
70 explicit Expression (double constant);
71
72 /** Attempts to create an expression by parsing a string.
73 Any errors are returned in the parseError argument provided.
74 */
75 Expression (const String& stringToParse, String& parseError);
76
77 /** Returns a string version of the expression. */
78 String toString() const;
79
80 /** Returns an expression which is an addition operation of two existing expressions. */
81 Expression operator+ (const Expression&) const;
82 /** Returns an expression which is a subtraction operation of two existing expressions. */
83 Expression operator- (const Expression&) const;
84 /** Returns an expression which is a multiplication operation of two existing expressions. */
85 Expression operator* (const Expression&) const;
86 /** Returns an expression which is a division operation of two existing expressions. */
87 Expression operator/ (const Expression&) const;
88 /** Returns an expression which performs a negation operation on an existing expression. */
89 Expression operator-() const;
90
91 /** Returns an Expression which is an identifier reference. */
92 static Expression symbol (const String& symbol);
93
94 /** Returns an Expression which is a function call. */
95 static Expression function (const String& functionName, const Array<Expression>& parameters);
96
97 /** Returns an Expression which parses a string from a character pointer, and updates the pointer
98 to indicate where it finished.
99
100 The pointer is incremented so that on return, it indicates the character that follows
101 the end of the expression that was parsed.
102
103 If there's a syntax error in parsing, the parseError argument will be set
104 to a description of the problem.
105 */
106 static Expression parse (String::CharPointerType& stringToParse, String& parseError);
107
108 //==============================================================================
109 /** When evaluating an Expression object, this class is used to resolve symbols and
110 perform functions that the expression uses.
111 */
113 {
114 public:
115 Scope();
116 virtual ~Scope();
117
118 /** Returns some kind of globally unique ID that identifies this scope. */
119 virtual String getScopeUID() const;
120
121 /** Returns the value of a symbol.
122 If the symbol is unknown, this can throw an Expression::EvaluationError exception.
123 The member value is set to the part of the symbol that followed the dot, if there is
124 one, e.g. for "foo.bar", symbol = "foo" and member = "bar".
125 @throws Expression::EvaluationError
126 */
127 virtual Expression getSymbolValue (const String& symbol) const;
128
129 /** Executes a named function.
130 If the function name is unknown, this can throw an Expression::EvaluationError exception.
131 @throws Expression::EvaluationError
132 */
133 virtual double evaluateFunction (const String& functionName,
134 const double* parameters, int numParameters) const;
135
136 /** Used as a callback by the Scope::visitRelativeScope() method.
137 You should never create an instance of this class yourself, it's used by the
138 expression evaluation code.
139 */
141 {
142 public:
143 virtual ~Visitor() = default;
144 virtual void visit (const Scope&) = 0;
145 };
146
147 /** Creates a Scope object for a named scope, and then calls a visitor
148 to do some kind of processing with this new scope.
149
150 If the name is valid, this method must create a suitable (temporary) Scope
151 object to represent it, and must call the Visitor::visit() method with this
152 new scope.
153 */
154 virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const;
155 };
156
157 /** Evaluates this expression, without using a Scope.
158 Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan,
159 min, max are available.
160 To find out about any errors during evaluation, use the other version of this method which
161 takes a String parameter.
162 */
163 double evaluate() const;
164
165 /** Evaluates this expression, providing a scope that should be able to evaluate any symbols
166 or functions that it uses.
167 To find out about any errors during evaluation, use the other version of this method which
168 takes a String parameter.
169 */
170 double evaluate (const Scope& scope) const;
171
172 /** Evaluates this expression, providing a scope that should be able to evaluate any symbols
173 or functions that it uses.
174 */
175 double evaluate (const Scope& scope, String& evaluationError) const;
176
177 /** Attempts to return an expression which is a copy of this one, but with a constant adjusted
178 to make the expression resolve to a target value.
179
180 E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return
181 the expression "x + 3". Obviously some expressions can't be reversed in this way, in which
182 case they might just be adjusted by adding a constant to the original expression.
183
184 @throws Expression::EvaluationError
185 */
186 Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const;
187
188 /** Represents a symbol that is used in an Expression. */
189 struct Symbol
190 {
191 Symbol (const String& scopeUID, const String& symbolName);
192 bool operator== (const Symbol&) const noexcept;
193 bool operator!= (const Symbol&) const noexcept;
194
195 String scopeUID; /**< The unique ID of the Scope that contains this symbol. */
196 String symbolName; /**< The name of the symbol. */
197 };
198
199 /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */
200 Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const;
201
202 /** Returns true if this expression makes use of the specified symbol.
203 If a suitable scope is supplied, the search will dereference and recursively check
204 all symbols, so that it can be determined whether this expression relies on the given
205 symbol at any level in its evaluation. If the scope parameter is null, this just checks
206 whether the expression contains any direct references to the symbol.
207
208 @throws Expression::EvaluationError
209 */
210 bool referencesSymbol (const Symbol& symbol, const Scope& scope) const;
211
212 /** Returns true if this expression contains any symbols. */
213 bool usesAnySymbols() const;
214
215 /** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */
216 void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const;
217
218 //==============================================================================
219 /** Expression type.
220 @see Expression::getType()
221 */
222 enum Type
223 {
224 constantType,
225 functionType,
226 operatorType,
227 symbolType
228 };
229
230 /** Returns the type of this expression. */
231 Type getType() const noexcept;
232
233 /** If this expression is a symbol, function or operator, this returns its identifier. */
234 String getSymbolOrFunction() const;
235
236 /** Returns the number of inputs to this expression.
237 @see getInput
238 */
239 int getNumInputs() const;
240
241 /** Retrieves one of the inputs to this expression.
242 @see getNumInputs
243 */
244 Expression getInput (int index) const;
245
246private:
247 //==============================================================================
248 class Term;
249 struct Helpers;
250 ReferenceCountedObjectPtr<Term> term;
251
252 explicit Expression (Term*);
253};
254
255} // namespace juce
256
257/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:60
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
Used as a callback by the Scope::visitRelativeScope() method.
When evaluating an Expression object, this class is used to resolve symbols and perform functions tha...
A class for dynamically evaluating simple numeric expressions.
Type
Expression type.
A smart-pointer class which points to a reference-counted object.
The JUCE String class!
Definition: juce_String.h:43
#define JUCE_API
This macro is added to all JUCE public class declarations.
Represents a symbol that is used in an Expression.
String symbolName
The name of the symbol.
String scopeUID
The unique ID of the Scope that contains this symbol.