dy / subscript

Fast and tiny expression evaluator with minimal syntax.
ISC License
105 stars 4 forks source link

How to implement assignment operator (=)? #18

Closed martinjo closed 10 months ago

martinjo commented 10 months ago

I'm trying (desperatly 😢) to implement an assignment operator. I'd like to be able to update my context with the result of expressions.

This is what I have:

binary('=', 0);
operator('=', (left: any, right: any) => (ctx: any) => {
    // Make sure the left side is a variable reference
    if (typeof left !== 'string') {
        throw new Error('Left side of assignment must be a variable name');
    }

    // Evaluate the right side in the context
    right = compile(right);
    const value = right(ctx);
    // Assign the value in the context
    ctx[left] = value;
    // Return the value
    return value;
});

It works for simple expressions like contextVar = anotherContextVar

But as soon as I use a more complicated expression like contextVar = anotherContextVar + 2 it fails since my right varible will get an array of values 🤷‍♂️. I feel I'm making a simple mistake here, but I can't seem to figure it out. Any suggestions?

dy commented 10 months ago

I've fixed some mistakes in the readme. Here's the example you need: https://github.com/dy/subscript/blob/main/test/subscript.js#L447-L457 Please lmk if it works.

dy commented 10 months ago

Ok, I hope it helped. Thanks for the issue, please reopen if it doesn't work.

martinjo commented 10 months ago

Thanks so much for the help! I'll soon get around to try it :)

martinjo commented 10 months ago

When I try the code you link to with the following simple statement: 'localvar = 0' I get the following error:

TypeError: cur.charCodeAt is not a function at parse.space (parse.js:58:48) at expr (parse.js:34:16) at parse (parse.js:7:33) at subscript (subscript.js:8:27) at interpreter.ts:197:22 at operators. [as =] (compile.js:6:73) at compile (compile.js:2:95) at subscript.js:8:56 at evalSubscript (interpreter.ts:188:34) at evalCode (interpreter.ts:50:17)

I can see my function for '=' getting called with a = 'localvar' b = '["",0]' (using JSON.stringify(b))  What am I missing?

dy commented 10 months ago

There's something you do wrong. Please check this code, it works:


import subscript, { operator, binary, compile } from 'subscript.js'

  binary('=', 10, true)
  operator('=', (a, b) => {
    const calc = compile(b);
    return ctx => (ctx[a] = calc(ctx))
  })

  const fn = subscript('localvar = 0')
  let state = {}
  fn(state)
  state.localvar === 0 //true