Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Substitute() nested variables #248

Open
acarbonellb opened this issue Mar 18, 2021 · 2 comments
Open

Substitute() nested variables #248

acarbonellb opened this issue Mar 18, 2021 · 2 comments

Comments

@acarbonellb
Copy link

Hello!

Just wondering if there is a way to use substitute to resolve object property references. For example:

// having:
const exp = parser.parse('variable1 + myObject.variable2 + variable3')

// what I want to do is:
const resolved = exp.substitute('myObject.variable2', 1234)
resolved.toString() // 'variable1 + 1234 + variable3'

However, seems like the substitute mechanism is not able to interpolate it.
Hope you can help me on this. Thanks!

@silentmatt
Copy link
Owner

The substitute function doesn't support that, but you could use simplify, which will evaluate what it can, and leave the rest of the expression alone.

const exp = parser.parse('variable1 + myObject.variable2 + variable3')
const resolved = exp.simplify({ myObject: { variable2: 1234 } })
resolved.toString() // '((variable1 + 1234) + variable3)'

The substitute and simplify functions are similar, but substitute is primarily intended for replacing variables with expressions, where simplify is more like partial evaluation, which is necessary in order to evaluate the .variable2 sub-expression. Supporting that does seem like a good possible enhancement though, so I'll leave this open for now to consider adding it.

@acarbonellb
Copy link
Author

acarbonellb commented Mar 21, 2021

Hey @silentmatt thanks for the reply. I know about simplify but it does not fit my use case. To give more context, what I'm trying to do is to fully "resolve" an expression, just before evaluating it, for debugging and historic purposes. Ideally, what I'm after is something that would behave like "expression.substituteAll(variables?: object)" – Conceptually, of course. I've made it up.

To achieve this behaviour what I'm doing right now is to iterate over the expression variables() and resolve one by one on top of each new Expression returned by substitute(). And when I'm done iterating I call toString() on the final Expression, which is fully resolved because each iteration was accumulative. Like this:

const context = { a: 1, b: 2, c: 3 };
const expression = parser.parse('a + b + c');

const resolved = exp
  .variables() // ['a', 'b', 'c']
  .reduce((prevExp, v) => prevExp.substitute(v, context[v]), expression)
  .toString();

console.log(resolved); // '1 + 2 + 3'

This works great unless we have expressions with object references, like I was mentioning in the first post.
Is there any way to achieve the ideal substituteAll() behaviour I was talking about?
Thank you for helping!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants