Keval icon indicating copy to clipboard operation
Keval copied to clipboard

Incorrect behavior when mixing functions and operators

Open simonsample opened this issue 2 years ago • 3 comments

Hi! I have the following code snippet:

val evaluator = Keval {
  includeDefault()
  function {
    name = "if"
    arity = 3
    implementation = { args -> if (args[2]==1.0) args[1] else args[0] }
  }
  println(evaluator.eval("if((1*1),4,5))
  println(evaluator.eval("if(1*1,4,5))
}

The first expression evaluates to 4 (as expected), the second one evaluates to 1 (not expected). Do you agree that this is a bug?

Another thought: the argument order confused me a bit, I was expecting args[0] to be the leftmost argument of the function, but it is the other way around..

simonsample avatar Apr 24 '22 20:04 simonsample

I was looking for an even simpler example: eval("max(5*6,7)") evaluates to 42 (which is in general a good answer, but not the one I expect here :) )

simonsample avatar Apr 24 '22 20:04 simonsample

Damn, thanks ! Regarding the arguments order, this is such a dumb bug haha. I know exactly what the problem is (I pop the syntax tree from the end, which is obviously wrong), I'm probably going to fix this later that day.

As for the other one, I'll look into it, but I currently have no real idea why it acts so. This may take a little longer.

notKamui avatar Apr 26 '22 07:04 notKamui

I should have posted this a while ago ; but this issue is gonna take longer to fix than i thought. The order one is fixed, but the argument ambiguity is due to an unfixable problem with the shunting yard algorithm. I already planned for a rework of the backend with a proper grammar engine for a long time now, but I didn't find the time to do it. This shouldn't be a problem anymore and is gonna my next focus for this library. This is gonna enable unary operators too, probably.

notKamui avatar Jun 04 '22 10:06 notKamui

I believe there is a way to solve the bug without replacing parser.

The idea is to keep some semantical context while transforming the list of tokens in string form to nodes form.

I'll try to implement it tomorrow or in two days. It will require (, ) and , to be a illegal operator name. I believe now it is technically possible to create operators with those names, but the parser will ignore those operators. So technically it will be an API breaking change (from ignoring those cases, it will be an exception)

Holo314 avatar Feb 09 '23 18:02 Holo314

That would be great ! I don't have much time recently (working on other projects), so a bit of help is very welcome

notKamui avatar Feb 10 '23 09:02 notKamui