UNPKG

6.34 kBMarkdownView Raw
1# Expression parsing and evaluation
2
3Expressions can be parsed and evaluated in various ways:
4
5- Using the function [`math.evaluate(expr [,scope])`](#evaluate).
6- Using the function [`math.compile(expr)`](#compile).
7- Using the function [`math.parse(expr)`](#parse).
8- By creating a [parser](#parser), `math.parser()`, which contains a method
9 `evaluate` and keeps a scope with assigned variables in memory.
10
11
12## Evaluate
13
14Math.js comes with a function `math.evaluate` to evaluate expressions. Syntax:
15
16```js
17math.evaluate(expr)
18math.evaluate(expr, scope)
19math.evaluate([expr1, expr2, expr3, ...])
20math.evaluate([expr1, expr2, expr3, ...], scope)
21```
22
23Function `evaluate` accepts a single expression or an array with
24expressions as the first argument and has an optional second argument
25containing a scope with variables and functions. The scope is a regular
26JavaScript Object. The scope will be used to resolve symbols, and to write
27assigned variables or function.
28
29The following code demonstrates how to evaluate expressions.
30
31```js
32// evaluate expressions
33math.evaluate('sqrt(3^2 + 4^2)') // 5
34math.evaluate('sqrt(-4)') // 2i
35math.evaluate('2 inch to cm') // 5.08 cm
36math.evaluate('cos(45 deg)') // 0.7071067811865476
37
38// provide a scope
39let scope = {
40 a: 3,
41 b: 4
42}
43math.evaluate('a * b', scope) // 12
44math.evaluate('c = 2.3 + 4.5', scope) // 6.8
45scope.c // 6.8
46```
47
48
49## Compile
50
51Math.js contains a function `math.compile` which compiles expressions
52into JavaScript code. This is a shortcut for first [parsing](#parse) and then
53compiling an expression. The syntax is:
54
55```js
56math.compile(expr)
57math.compile([expr1, expr2, expr3, ...])
58```
59
60Function `compile` accepts a single expression or an array with
61expressions as the argument. Function `compile` returns an object with a function
62`evaluate([scope])`, which can be executed to evaluate the expression against an
63(optional) scope:
64
65```js
66const code = math.compile(expr) // compile an expression
67const result = code.evaluate([scope]) // evaluate the code with an optional scope
68```
69
70An expression needs to be compiled only once, after which the
71expression can be evaluated repeatedly and against different scopes.
72The optional scope is used to resolve symbols and to write assigned
73variables or functions. Parameter `scope` is a regular Object.
74
75Example usage:
76
77```js
78// parse an expression into a node, and evaluate the node
79const code1 = math.compile('sqrt(3^2 + 4^2)')
80code1.evaluate() // 5
81```
82
83
84## Parse
85
86Math.js contains a function `math.parse` to parse expressions into an
87[expression tree](expression_trees.md). The syntax is:
88
89```js
90math.parse(expr)
91math.parse([expr1, expr2, expr3, ...])
92```
93
94Function `parse` accepts a single expression or an array with
95expressions as the argument. Function `parse` returns a the root node of the tree,
96which can be successively compiled and evaluated:
97
98```js
99const node = math.parse(expr) // parse expression into a node tree
100const code = node.compile() // compile the node tree
101const result = code.evaluate([scope]) // evaluate the code with an optional scope
102```
103
104The API of nodes is described in detail on the page
105[Expression trees](expression_trees.md).
106
107An expression needs to be parsed and compiled only once, after which the
108expression can be evaluated repeatedly. On evaluation, an optional scope
109can be provided, which is used to resolve symbols and to write assigned
110variables or functions. Parameter `scope` is a regular Object.
111
112Example usage:
113
114```js
115// parse an expression into a node, and evaluate the node
116const node1 = math.parse('sqrt(3^2 + 4^2)')
117const code1 = node1.compile()
118code1.evaluate() // 5
119
120// provide a scope
121const node2 = math.parse('x^a')
122const code2 = node2.compile()
123let scope = {
124 x: 3,
125 a: 2
126}
127code2.evaluate(scope) // 9
128
129// change a value in the scope and re-evaluate the node
130scope.a = 3
131code2.evaluate(scope) // 27
132```
133
134Parsed expressions can be exported to text using `node.toString()`, and can
135be exported to LaTeX using `node.toTex()`. The LaTeX export can be used to
136pretty print an expression in the browser with a library like
137[MathJax](https://www.mathjax.org/). Example usage:
138
139```js
140// parse an expression
141const node = math.parse('sqrt(x/x+1)')
142node.toString() // returns 'sqrt((x / x) + 1)'
143node.toTex() // returns '\sqrt{ {\frac{x}{x} }+{1} }'
144```
145
146
147## Parser
148
149In addition to the static functions [`math.evaluate`](#evaluate) and
150[`math.parse`](#parse), math.js contains a parser with functions `evaluate` and
151`parse`, which automatically keeps a scope with assigned variables in memory.
152The parser also contains some convenience functions to get, set, and remove
153variables from memory.
154
155A parser can be created by:
156
157```js
158const parser = math.parser()
159```
160
161The parser contains the following functions:
162
163- `clear()`
164 Completely clear the parser's scope.
165- `evaluate(expr)`
166 Evaluate an expression. Returns the result of the expression.
167- `get(name)`
168 Retrieve a variable or function from the parser's scope.
169- `getAll()`
170 Retrieve a map with all defined a variables from the parser's scope.
171- `remove(name)`
172 Remove a variable or function from the parser's scope.
173- `set(name, value)`
174 Set a variable or function in the parser's scope.
175
176The following code shows how to create and use a parser.
177
178```js
179// create a parser
180const parser = math.parser()
181
182// evaluate expressions
183parser.evaluate('sqrt(3^2 + 4^2)') // 5
184parser.evaluate('sqrt(-4)') // 2i
185parser.evaluate('2 inch to cm') // 5.08 cm
186parser.evaluate('cos(45 deg)') // 0.7071067811865476
187
188// define variables and functions
189parser.evaluate('x = 7 / 2') // 3.5
190parser.evaluate('x + 3') // 6.5
191parser.evaluate('f(x, y) = x^y') // f(x, y)
192parser.evaluate('f(2, 3)') // 8
193
194// get and set variables and functions
195const x = parser.get('x') // x = 7
196const f = parser.get('f') // function
197const g = f(3, 3) // g = 27
198parser.set('h', 500)
199parser.evaluate('h / 2') // 250
200parser.set('hello', function (name) {
201 return 'hello, ' + name + '!'
202})
203parser.evaluate('hello("user")') // "hello, user!"
204
205// clear defined functions and variables
206parser.clear()
207```