nicklockwood / Expression

A cross-platform Swift library for evaluating mathematical expressions at runtime

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Overloading existing operators

nighthawk opened this issue · comments

I'm experimenting with using AnyExpression and its powerful support for custom data types and operators. This is working well, though I'm facing an issue when I want to use the same operator as defined by Expression (or AnyExpression) itself, but only use my overload for the custom data types and falling back to the default implementations otherwise.

Say, for example in have a "date" datatype which is really just Swift's Date, and I want to allow comparisons using <, <= and their friends, but if I define those as .infix("<") then this now works for my date types, but regular numeric expressions now fail.

I've tried following this from the README:

If you are using the init(impureSymbols:pureSymbols:) initializer, you can fall back to the standard library functions and operators by returning nil for unrecognized symbols.

However, I can't return nil at that stage, as I'd have to return nil from within the operator's SymbolEvaluator as it depends on the specific arguments.

Is this possible or do I have to reimplement the default behaviour in my custom operator?

There's not a super-elegant way to do this right now, but basically yes you'd need to reimplement the standard operator logic inside your own handlers. Here's an example:

let expression = AnyExpression(parsed) { symbol in
    switch symbol {
    case .infix("<"):
        return { args in
            switch (args[0], args[1]) {
            case let (lhs as Date, rhs as Date):
                return lhs < rhs
            case let (lhs as Double, rhs as Double):
                return lhs < rhs
            default:
                throw Expression.Error.message("Type mismatch")
            }
        }
    default:
        return nil
    }
}

Thank you for the quick response! I’ll go with that for now, but would be nice to have a more elegant way down the track where the duplication wouldn’t be necessary.