Skip to content
Dave DeLong edited this page Aug 31, 2012 · 3 revisions

Evaluation is part of the expression's logic, but it uses the Math Evaluator quite extensively.

Evaluating numbers

Evaluating a number expression is trivial. It simply returns the underlying NSNumber object.

Evaluating variables

Evaluating a variable is also relatively straight-forward. First, the variable is looked up in the passed substitutions dictionary. If no replacement is found, then an error is generated and evaluation aborts.

Otherwise, the object is examined:

  • if the substitution value is another expression, that expression is evaluated and its return value becomes the variables value.
  • if the substitution value is a string, that string is evaluated as an expression, and its return value becomes the variables value
  • if the substitution value is a number, the number is used directly
  • any other substitution value generates an error

Evaluating functions

Evaluating a function is where the math evaluator is used. The expression asks the evaluator for a DDMathFunction (a block) that matches the name of the function. If no match is found, a failure method is invoked on the evaluator (-functionExpressionFailedToResolve:error:), which generates an error and aborts evaluation.

Otherwise, the DDMathFunction is invoked with four arguments:

  1. the array of DDExpression objects that are the arguments to the function
  2. the substitution dictionary
  3. the math evaluator
  4. the NSError** (for reporting errors)

The return value of the DDMathFunction should be another DDExpression object, although some leniency is allowed: NSNumbers are returned directly and NSStrings are parsed and evaluated to extract a numerical value.

Angle Measurement Mode

The math evaluator allows you to specify the unit in which angles are measured. The two options are DDAngleMeasurementModeRadians (the default) and DDAngleMeasurementModeDegrees.

When the measurement mode is in radians, the following is true:

sin(π/2) = 1
asin(0.7071067811865475) = .785398163
sin(45) = 0.8509035245341184

However, the when measurement mode is in degrees, the evaluation changes:

sin(π/2) = 0.02741213359204429
asin(0.7071067811865475) = 45
sin(45) = 0.7071067811865475

Lazy Resolution

DDMathEvaluator has two properties that allow you to lazily resolve functions and variables: functionResolver and variableResolver.

Function Resolution

Lazy function resolution can be very handy when using DDMathParser to process user-generated input. For example, you can use lazy function resolution to process a string like this:

"age/2 + 7"

According to the rules of argumentless functions, this will be parsed as:

(age() / 2) + 7

The advantage of this is that users do not need to understand the syntax for variables and their need for the leading $ character.

By specifying the appropriate block for the functionResolver, you can process these functions as if they were variables. The Demo in the repository contains an example of a function resolver.

Variable Resolution

Like with functions, you can specify a block to lazily resolve unknown variables. The block, however, is much simpler: it takes a single string argument (the name of the variable) and returns an NSNumber.