public OperatorImplementationTable CreateOperatorImplementationsTable() { var table = new OperatorImplementationTable(); foreach (var entry in _baseOperatorImplementations) { table.Add(entry.Key, entry.Value); } return(table); }
/* * public virtual FunctionBindingInfo GetFunctionBindingInfo(string name, AstNodeList parameters) { * return FunctionBindings.Find(name, parameters.Count); * } * //Utility methods for adding library functions * public FunctionBindingInfo AddFunction(string name, int paramCount) { * return null; * } * public FunctionBindingInfo AddFunction(string name, int paramCount, FunctionFlags flags) { * FunctionBindingInfo info = new FunctionBindingInfo(name, paramCount, null, flags); * FunctionBindings.Add(name, info); * return info; * } */ #region Operator implementations // When an implementation for exact type pair is not found, we find implementation for base type and create // implementation for exact types using type converters public virtual OperatorImplementation AddOperatorImplementation(OperatorImplementationTable implementations, OperatorDispatchKey forKey) { Type baseType = GetBaseTypeForExpression(forKey.OpSymbol, forKey.Arg1Type, forKey.Arg2Type); if (baseType == null) { return(null); } TypeConverter arg1Converter = GetConverter(forKey.Arg1Type, baseType); TypeConverter arg2Converter = GetConverter(forKey.Arg2Type, baseType); //Get base method for the operator and common type var baseKey = OperatorDispatchKey.CreateFromTypes(forKey.OpSymbol, baseType, baseType); OperatorImplementation baseImpl; if (!_baseOperatorImplementations.TryGetValue(baseKey, out baseImpl)) { throw new Exception(string.Format(Resources.ErrOpNotDefinedForTypes, forKey.OpSymbol, forKey.Arg1Type, forKey.Arg2Type)); } var impl = new OperatorImplementation(forKey, baseType, baseImpl.BaseMethod, arg1Converter, arg2Converter, baseImpl.ResultConverter); implementations[forKey] = impl; return(impl); }
public DynamicCallDispatcher(EvaluationContext context) { _context = context; _runtime = _context.Runtime; OperatorImplementations = _runtime.CreateOperatorImplementationsTable(); }
public virtual void InitOperatorImplementations() { _baseOperatorImplementations = new OperatorImplementationTable(); // note that arithmetics on byte, sbyte, int16, uint16 are performed in Int32 format (the way it's done in c# I guess) // so the result is always Int32 // we don't force the result back to original type - I don't think it's necessary // For each operator, we add a series of implementation methods for same-type operands. They are saved as DispatchRecords in // operator dispatchers. This happens at initialization time. Dispatch records for mismatched argument types (ex: int + double) // are created on-the-fly at execution time. string op; op = "+"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x + (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x + (byte)y); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x + (Int16)y); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x + (UInt16)y); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x + (Int32)y)); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x + (UInt32)y)); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x + (Int64)y)); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x + (UInt64)y)); AddImplementation(op, typeof(Single), (x, y) => (Single)x + (Single)y); AddImplementation(op, typeof(double), (x, y) => (double)x + (double)y); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x + (BigInteger)y); AddImplementation(op, typeof(Complex), (x, y) => (Complex)x + (Complex)y); AddImplementation(op, typeof(string), (x, y) => (string)x + (string)y); op = "-"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x - (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x - (byte)y); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x - (Int16)y); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x - (UInt16)y); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x - (Int32)y)); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x - (UInt32)y)); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x - (Int64)y)); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x - (UInt64)y)); AddImplementation(op, typeof(Single), (x, y) => (Single)x - (Single)y); AddImplementation(op, typeof(double), (x, y) => (double)x - (double)y); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x - (BigInteger)y); AddImplementation(op, typeof(Complex), (x, y) => (Complex)x - (Complex)y); op = "*"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x * (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x * (byte)y); AddImplementation(op, typeof(Int16), (x, y) => checked ((Int16)x * (Int16)y)); AddImplementation(op, typeof(UInt16), (x, y) => checked ((UInt16)x * (UInt16)y)); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x * (Int32)y)); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x * (UInt32)y)); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x * (Int64)y)); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x * (UInt64)y)); AddImplementation(op, typeof(Single), (x, y) => (Single)x * (Single)y); AddImplementation(op, typeof(double), (x, y) => (double)x * (double)y); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x * (BigInteger)y); AddImplementation(op, typeof(Complex), (x, y) => (Complex)x * (Complex)y); op = "/"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x / (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x / (byte)y); AddImplementation(op, typeof(Int16), (x, y) => checked ((Int16)x / (Int16)y)); AddImplementation(op, typeof(UInt16), (x, y) => checked ((UInt16)x / (UInt16)y)); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x / (Int32)y)); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x / (UInt32)y)); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x / (Int64)y)); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x / (UInt64)y)); AddImplementation(op, typeof(Single), (x, y) => (Single)x / (Single)y); AddImplementation(op, typeof(double), (x, y) => (double)x / (double)y); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x / (BigInteger)y); AddImplementation(op, typeof(Complex), (x, y) => (Complex)x / (Complex)y); op = "&"; AddImplementation(op, typeof(bool), (x, y) => (bool)x & (bool)y); AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x & (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x & (byte)y); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x & (Int16)y); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x & (UInt16)y); AddImplementation(op, typeof(Int32), (x, y) => (Int32)x & (Int32)y); AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x & (UInt32)y); AddImplementation(op, typeof(Int64), (x, y) => (Int64)x & (Int64)y); AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x & (UInt64)y); op = "|"; AddImplementation(op, typeof(bool), (x, y) => (bool)x | (bool)y); AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x | (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x | (byte)y); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x | (Int16)y); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x | (UInt16)y); AddImplementation(op, typeof(Int32), (x, y) => (Int32)x | (Int32)y); AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x | (UInt32)y); AddImplementation(op, typeof(Int64), (x, y) => (Int64)x | (Int64)y); AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x | (UInt64)y); op = "^"; //XOR AddImplementation(op, typeof(bool), (x, y) => (bool)x ^ (bool)y); AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x ^ (sbyte)y); AddImplementation(op, typeof(byte), (x, y) => (byte)x ^ (byte)y); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x ^ (Int16)y); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x ^ (UInt16)y); AddImplementation(op, typeof(Int32), (x, y) => (Int32)x ^ (Int32)y); AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x ^ (UInt32)y); AddImplementation(op, typeof(Int64), (x, y) => (Int64)x ^ (Int64)y); AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x ^ (UInt64)y); //Note that && and || are special forms, not binary operators op = "<"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x < (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x < (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x < (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x < (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x < (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x < (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x < (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x < (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x < (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x < (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x < (BigInteger)y, BoolResultConverter); op = ">"; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x > (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x > (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x > (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x > (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x > (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x > (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x > (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x > (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x > (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x > (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x > (BigInteger)y, BoolResultConverter); op = "<="; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x <= (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x <= (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x <= (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x <= (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x <= (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x <= (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x <= (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x <= (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x <= (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x <= (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x <= (BigInteger)y, BoolResultConverter); op = ">="; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x >= (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x >= (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x >= (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x >= (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x >= (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x >= (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x >= (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x >= (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x >= (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x >= (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x >= (BigInteger)y, BoolResultConverter); op = "=="; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x == (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x == (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x == (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x == (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x == (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x == (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x == (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x == (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x == (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x == (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x == (BigInteger)y, BoolResultConverter); op = "!="; AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x != (sbyte)y, BoolResultConverter); AddImplementation(op, typeof(byte), (x, y) => (byte)x != (byte)y, BoolResultConverter); AddImplementation(op, typeof(Int16), (x, y) => (Int16)x != (Int16)y, BoolResultConverter); AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x != (UInt16)y, BoolResultConverter); AddImplementation(op, typeof(Int32), (x, y) => checked ((Int32)x != (Int32)y), BoolResultConverter); AddImplementation(op, typeof(UInt32), (x, y) => checked ((UInt32)x != (UInt32)y), BoolResultConverter); AddImplementation(op, typeof(Int64), (x, y) => checked ((Int64)x != (Int64)y), BoolResultConverter); AddImplementation(op, typeof(UInt64), (x, y) => checked ((UInt64)x != (UInt64)y), BoolResultConverter); AddImplementation(op, typeof(Single), (x, y) => (Single)x != (Single)y, BoolResultConverter); AddImplementation(op, typeof(double), (x, y) => (double)x != (double)y, BoolResultConverter); AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x != (BigInteger)y, BoolResultConverter); }//method