OpenShot Library | OpenShotAudio  0.2.1
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 
27 namespace 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 {
49 public:
50  //==============================================================================
51  /** Creates a simple expression with a value of 0. */
52  Expression();
53 
54  /** Destructor. */
55  ~Expression();
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  */
140  class Visitor
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 
246 private:
247  //==============================================================================
248  class Term;
249  struct Helpers;
251 
252  explicit Expression (Term*);
253 };
254 
255 } // namespace juce
256 
257 /** @}*/
#define JUCE_API
This macro is added to all JUCE public class declarations.
When evaluating an Expression object, this class is used to resolve symbols and perform functions tha...
The JUCE String class!
Definition: juce_String.h:42
String scopeUID
The unique ID of the Scope that contains this symbol.
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
A class for dynamically evaluating simple numeric expressions.
Used as a callback by the Scope::visitRelativeScope() method.
String symbolName
The name of the symbol.
Type
Expression type.
Represents a symbol that is used in an Expression.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...