Keval
Keval copied to clipboard
Incorrect behavior when mixing functions and operators
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..
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 :) )
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.
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.
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)
That would be great ! I don't have much time recently (working on other projects), so a bit of help is very welcome