protected OperatorImplementation AddUnary(ExpressionType op, Type commonType, UnaryOperatorMethod unaryMethod) { var key = new OperatorDispatchKey(op, commonType); var impl = new OperatorImplementation(key, commonType, null, unaryMethod, null, null); OperatorImplementations[key] = impl; return(impl); }
private OperatorImplementation FindBaseImplementation(ExpressionType op, Type commonType) { var baseKey = new OperatorDispatchKey(op, commonType, commonType); OperatorImplementation baseImpl; OperatorImplementations.TryGetValue(baseKey, out baseImpl); return(baseImpl); }
protected OperatorImplementation AddConverter(Type fromType, Type toType, UnaryOperatorMethod method) { var key = new OperatorDispatchKey(ExpressionType.ConvertChecked, fromType, toType); var impl = new OperatorImplementation(key, toType, method); OperatorImplementations[key] = impl; return(impl); }
public OperatorImplementation(OperatorDispatchKey key, Type type, UnaryOperatorMethod method) { Key = key; CommonType = type; Arg1Converter = method; Arg2Converter = null; ResultConverter = null; BaseBinaryMethod = null; }
protected OperatorImplementation AddBinary(ExpressionType op, Type commonType, BinaryOperatorMethod binaryMethod, UnaryOperatorMethod resultConverter) { var key = new OperatorDispatchKey(op, commonType, commonType); var impl = new OperatorImplementation(key, commonType, binaryMethod, null, null, resultConverter); OperatorImplementations[key] = impl; return(impl); }
public OperatorImplementation(OperatorDispatchKey key, Type resultType, BinaryOperatorMethod baseBinaryMethod, UnaryOperatorMethod arg1Converter, UnaryOperatorMethod arg2Converter, UnaryOperatorMethod resultConverter) { Key = key; CommonType = resultType; Arg1Converter = arg1Converter; Arg2Converter = arg2Converter; ResultConverter = resultConverter; BaseBinaryMethod = baseBinaryMethod; SetupEvaluationMethod(); }
protected OperatorImplementation CreateBinaryOperatorImplementation(ExpressionType op, Type arg1Type, Type arg2Type, Type commonType, BinaryOperatorMethod method, UnaryOperatorMethod resultConverter) { OperatorDispatchKey key = new OperatorDispatchKey(op, arg1Type, arg2Type); UnaryOperatorMethod arg1Converter = arg1Type == commonType ? null : GetConverter(arg1Type, commonType); UnaryOperatorMethod arg2Converter = arg2Type == commonType ? null : GetConverter(arg2Type, commonType); var impl = new OperatorImplementation(key, commonType, method, arg1Converter, arg2Converter, resultConverter); return(impl); }
public object ExecuteBinaryOperator(ExpressionType op, object arg1, object arg2, ref OperatorImplementation previousUsed) { Type arg1Type, arg2Type; try { arg1Type = arg1.GetType(); arg2Type = arg2.GetType(); } catch (NullReferenceException) { CheckUnassigned(arg1); CheckUnassigned(arg2); throw; } var currentImpl = previousUsed; if (currentImpl != null && (arg1Type != currentImpl.Key.Arg1Type || arg2Type != currentImpl.Key.Arg2Type)) { currentImpl = null; } OperatorDispatchKey key; if (currentImpl == null) { key = new OperatorDispatchKey(op, arg1Type, arg2Type); if (!OperatorImplementations.TryGetValue(key, out currentImpl)) { throw new ScriptException($"Op(<{arg1Type.Name}> <{op}> <{arg2Type.Name}>) not defined!"); } } try { previousUsed = currentImpl; return(currentImpl.EvaluateBinary(arg1, arg2)); } catch (OverflowException) { if (currentImpl.OverflowHandler == null) { throw; } previousUsed = currentImpl.OverflowHandler; return(ExecuteBinaryOperator(op, arg1, arg2, ref previousUsed)); } catch (IndexOutOfRangeException) { throw; } }
private UnaryOperatorMethod GetConverter(Type fromType, Type toType) { if (fromType == toType) { return(x => x); } var key = new OperatorDispatchKey(ExpressionType.ConvertChecked, fromType, toType); OperatorImplementation impl; if (!OperatorImplementations.TryGetValue(key, out impl)) { return(null); } return(impl.Arg1Converter); }