tevelee / eval Goto Github PK
View Code? Open in Web Editor NEWEval is a lightweight interpreter framework written in Swift, evaluating expressions at runtime
Home Page: https://tevelee.github.io/Eval/
License: Apache License 2.0
Eval is a lightweight interpreter framework written in Swift, evaluating expressions at runtime
Home Page: https://tevelee.github.io/Eval/
License: Apache License 2.0
I built an expression library using Eval with about 50 operators (most of them taken from sample code – thanks a lot for that!) and noticed a curious drop in performance when defining a prefix function like not X
and then having an expression like nothing == true
where nothing
could potentially be a variable. The performance drop is quite significant in my case, where by having adding that not
prefix function slows down the overall evaluation by a factor of 5-6 compared to just having a !
prefix function.
I wonder if the evaluate
method of the interpreter could be improved by introducing at the appropriate place a check that a function name shouldn't be evaluated against a substring. Though that might be done on purpose for some use case. In that case an alternative would be to provide a PatternOptions
which allows telling the parser that this specific function keyword can't be a substring.
I can try to do those adjustments, though I'm not sure where to do them in the code. Any hints would be appreciated.
Some sample code which reproduces the slowdown (less than in my big library, but still by a factor of 3): https://gist.github.com/nighthawk/c7daa27285da406e5b2a71f8b789bf3f
Eval/Tests/EvalTests/IntegrationTests/Suffix.swift
Lines 22 to 27 in df80bd8
TODO
comment in df80bd8. It's been assigned to @undefined because they committed the code.With the following configuration, Eval is producing nil for the 4th expression. I'm not sure how to dig further into where the bug lies, but it's possibly confused by the nested function calls?
let number = DataType(type: Double.self, literals: [
Literal<Double> { value, _ in Double(value) },
]) { arg, _ in "\(arg)" }
let addition = Function<Double>(Variable<Double>("lhs") + Keyword("+") +
Variable<Double>("rhs")) { arguments, _, _ in
guard let lhs = arguments["lhs"] as? Double,
let rhs = arguments["rhs"] as? Double else { return nil }
return lhs + rhs
}
let foo = Function<Double>(Keyword("foo") + Keyword("(") + Variable<Double>("lhs") + Keyword(",") + Variable<Double>("rhs") + Keyword(")")) { arguments, _, _ in
guard let lhs = arguments["lhs"] as? Double,
let rhs = arguments["rhs"] as? Double else { return nil }
return lhs - rhs
}
let bar = Function<Double>(Keyword("bar") + Keyword("(") + Variable<Double>("value") + Keyword(")")) { arguments, _, _ in
guard let value = arguments["value"] as? Double else { return nil }
return value - 2
}
let interpreter = TypedInterpreter(dataTypes: [number], functions: [addition, foo, bar])
print(interpreter.evaluate("5 + 6") as? Double ?? "nil") // 11.0
print(interpreter.evaluate("foo(5, 6)") as? Double ?? "nil") // -1.0
print(interpreter.evaluate("bar(6)") as? Double ?? "nil") // 4.0
print(interpreter.evaluate("foo(5, 6 + bar(6))") as? Double ?? "nil") // nil
Hi,
For iOS and macOS projets it's will be great to make your component Carthage compatible
Take a look at these articles:
On your README.md
add on top and add section for the installation with Carthage.
I'm incorporating this library into a project where I want to let users create formulas that check against certain fields. This is mostly working, but I've hit a small roadblock when trying to create a x exists
suffix operator that basically checks x != nil
. This generally works, but fails in certain nesting conditions.
It might have to do something with operator precedence, as changing the order fixes one case but then causes another test case to fail. I'd appreciate some feedback on how to fix this or how to debug this.
The strange thing is that it works fine perfectly if it's a prefix operator (didset X
in my example), though I'd prefer the suffix variant.
The full code sample is here, which is a minor modification of the code from the template example in this repo: https://gist.github.com/nighthawk/060475d0ded20788e9269054e152d76d
Any help would be much appreciated!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.