@@ -30,6 +30,13 @@ export class Expression {
3030 public ternaryOps : Record < string , OperatorFunction > ;
3131 public functions : Record < string , OperatorFunction > ;
3232
33+ /**
34+ * Creates a new Expression instance. Usually created via Parser.parse().
35+ *
36+ * @param tokens - The compiled instruction tokens
37+ * @param parser - The parser instance that created this expression
38+ * @internal
39+ */
3340 constructor ( tokens : Instruction [ ] , parser : ParserLike ) {
3441 this . tokens = tokens ;
3542 this . parser = parser ;
@@ -39,11 +46,35 @@ export class Expression {
3946 this . functions = parser . functions ;
4047 }
4148
49+ /**
50+ * Returns a simplified version of this expression.
51+ * Attempts to pre-compute parts of the expression that don't depend on variables.
52+ *
53+ * @param values - Optional object containing known variable values for simplification
54+ * @returns A new simplified Expression instance
55+ * @example
56+ * ```typescript
57+ * const expr = parser.parse('2 + 3 + x');
58+ * const simplified = expr.simplify(); // Results in '5 + x'
59+ * ```
60+ */
4261 simplify ( values ?: Values ) : Expression {
4362 values = values || { } ;
4463 return new Expression ( simplify ( this . tokens , this . unaryOps , this . binaryOps , this . ternaryOps , values ) , this . parser ) ;
4564 }
4665
66+ /**
67+ * Substitutes a variable with another expression.
68+ *
69+ * @param variable - The variable name to substitute
70+ * @param expr - The expression or expression string to substitute with
71+ * @returns A new Expression instance with the substitution applied
72+ * @example
73+ * ```typescript
74+ * const expr = parser.parse('x + y');
75+ * const substituted = expr.substitute('x', '2 * z'); // Results in '2 * z + y'
76+ * ```
77+ */
4778 substitute ( variable : string , expr : string | Expression ) : Expression {
4879 if ( ! ( expr instanceof Expression ) ) {
4980 expr = this . parser . parse ( String ( expr ) ) ;
@@ -52,32 +83,99 @@ export class Expression {
5283 return new Expression ( substitute ( this . tokens , variable , expr ) , this . parser ) ;
5384 }
5485
86+ /**
87+ * Evaluates the expression with the given variable values.
88+ *
89+ * @param values - Object containing variable values
90+ * @returns The computed result of the expression
91+ * @throws {VariableError } When the expression references undefined variables
92+ * @throws {EvaluationError } When runtime evaluation fails
93+ * @example
94+ * ```typescript
95+ * const expr = parser.parse('2 + 3 * x');
96+ * const result = expr.evaluate({ x: 4 }); // Returns 14
97+ * ```
98+ */
5599 evaluate ( values ?: Values ) : any {
56100 values = values || { } ;
57101 return evaluate ( this . tokens , this , values ) ;
58102 }
59103
104+ /**
105+ * Returns a string representation of the expression.
106+ *
107+ * @returns The expression as a human-readable string
108+ * @example
109+ * ```typescript
110+ * const expr = parser.parse('2 + 3 * x');
111+ * console.log(expr.toString()); // "2 + 3 * x"
112+ * ```
113+ */
60114 toString ( ) : string {
61115 return expressionToString ( this . tokens , false ) ;
62116 }
63117
118+ /**
119+ * Returns an array of all symbols (variables and functions) used in the expression.
120+ *
121+ * @param options - Options for symbol extraction
122+ * @param options.withMembers - Whether to include member access chains
123+ * @returns Array of symbol names
124+ * @example
125+ * ```typescript
126+ * const expr = parser.parse('x + sin(y) + obj.prop');
127+ * const symbols = expr.symbols(); // ['x', 'sin', 'y', 'obj', 'prop']
128+ * const symbolsWithMembers = expr.symbols({ withMembers: true }); // ['x', 'sin', 'y', 'obj.prop']
129+ * ```
130+ */
64131 symbols ( options ?: SymbolOptions ) : string [ ] {
65132 options = options || { } ;
66133 const vars : string [ ] = [ ] ;
67134 getSymbols ( this . tokens , vars , options ) ;
68135 return vars ;
69136 }
70137
138+ /**
139+ * Returns an array of variables used in the expression (excludes function names).
140+ *
141+ * @param options - Options for variable extraction
142+ * @param options.withMembers - Whether to include member access chains
143+ * @returns Array of variable names
144+ * @example
145+ * ```typescript
146+ * const expr = parser.parse('x + sin(y) + obj.prop');
147+ * const variables = expr.variables(); // ['x', 'y', 'obj', 'prop'] (sin is excluded as it's a function)
148+ * ```
149+ */
71150 variables ( options ?: SymbolOptions ) : string [ ] {
72151 options = options || { } ;
73152 const vars : string [ ] = [ ] ;
74153 getSymbols ( this . tokens , vars , options ) ;
75- const functions = this . functions ;
154+ const { functions } = this ;
76155 return vars . filter ( function ( name ) {
77156 return ! ( name in functions ) ;
78157 } ) ;
79158 }
80159
160+ /**
161+ * Compiles the expression into a JavaScript function.
162+ * The resulting function can be called with arguments corresponding to variables in the expression.
163+ *
164+ * @param param - The parameter name for the generated function
165+ * @param variables - Optional pre-computed variable values for optimization
166+ * @returns A JavaScript function that evaluates the expression
167+ * @example
168+ * ```typescript
169+ * const expr = parser.parse('2 + 3 * x');
170+ * const fn = expr.toJSFunction('x');
171+ * const result = fn(4); // Returns 14
172+ *
173+ * // Multiple parameters
174+ * const expr2 = parser.parse('x + y * z');
175+ * const fn2 = expr2.toJSFunction('vars');
176+ * const result2 = fn2({ x: 1, y: 2, z: 3 }); // Returns 7
177+ * ```
178+ */
81179 toJSFunction ( param : string , variables ?: Values ) : ( ...args : any [ ] ) => any {
82180 const expr = this ;
83181 const f = new Function ( param , 'with(this.functions) with (this.ternaryOps) with (this.binaryOps) with (this.unaryOps) { return ' + expressionToString ( this . simplify ( variables ) . tokens , true ) + '; }' ) ;
0 commit comments