public static bool CanBeConverted(FunnyType from, FunnyType to) { while (true) { if (to.IsText) { return(true); } if (to.BaseType == from.BaseType) { switch (to.BaseType) { case BaseFunnyType.ArrayOf: @from = @from.ArrayTypeSpecification.FunnyType; to = to.ArrayTypeSpecification.FunnyType; continue; //Check for Fun and struct types is quite expensive, so there is no big reason to write optimized code case BaseFunnyType.Fun: return(GetConverterOrNull(@from, to) != null); case BaseFunnyType.Struct: return(GetConverterOrNull(@from, to) != null); } } return(PrimitiveConvertMap[(int)from.BaseType, (int)to.BaseType]); } }
public static Func <object, object> GetConverterOrThrow(FunnyType from, FunnyType to, Interval interval) { var res = GetConverterOrNull(from, to); if (res == null) { throw ErrorFactory.ImpossibleCast(from, to, interval); } return(res); }
public VarInfo( bool isOutput, FunnyType type, string name, bool isStrictTyped, VarAttribute[] attributes = null) { IsStrictTyped = isStrictTyped; IsOutput = isOutput; Type = type; Name = name; Attributes = attributes ?? new VarAttribute[0]; }
public static object GetDefaultValueOrNull(this FunnyType type) { var defaultValue = DefaultPrimitiveValues[(int)type.BaseType]; if (defaultValue != null) { return(defaultValue); } if (type.ArrayTypeSpecification == null) { return(null); } var arr = type.ArrayTypeSpecification; if (arr.FunnyType.BaseType == BaseFunnyType.Char) { return(TextFunArray.Empty); } return(new ImmutableFunArray(new object[0], arr.FunnyType)); }
private static IinputFunnyConverter GetInputConverter(FunnyType funnyType, int reqDeepthCheck) { if (reqDeepthCheck > 100) { throw new ArgumentException("Too nested input object"); } switch (funnyType.BaseType) { case BaseFunnyType.Char: case BaseFunnyType.Bool: case BaseFunnyType.UInt8: case BaseFunnyType.UInt16: case BaseFunnyType.UInt32: case BaseFunnyType.UInt64: case BaseFunnyType.Int16: case BaseFunnyType.Int32: case BaseFunnyType.Int64: case BaseFunnyType.Real: return(new PrimitiveTypeInputFunnyConverter(funnyType)); case BaseFunnyType.ArrayOf: if (funnyType.IsText) { return(new StringTypeInputFunnyConverter()); } var elementConverter = GetInputConverter(funnyType.ArrayTypeSpecification.FunnyType, reqDeepthCheck + 1); return(new ClrArrayInputTypeFunnyConverter(elementConverter)); case BaseFunnyType.Any: return(new DynamicTypeInputFunnyConverter()); case BaseFunnyType.Empty: case BaseFunnyType.Fun: case BaseFunnyType.Generic: case BaseFunnyType.Struct: default: throw new NotSupportedException($"type {funnyType} is not supported for input convertion"); } }
public static IinputFunnyConverter GetInputConverter(FunnyType funnyType) => GetInputConverter(funnyType, 0);
public static Func <object, object> GetConverterOrNull(FunnyType from, FunnyType to) { if (to.IsText) { return(ToText); } if (to.BaseType == BaseFunnyType.Any) { return(NoConvertion); } if (from.IsNumeric()) { switch (to.BaseType) { case BaseFunnyType.UInt8: return(ToUInt8); case BaseFunnyType.UInt16: return(ToUInt16); case BaseFunnyType.UInt32: return(ToUInt32); case BaseFunnyType.UInt64: return(ToUInt64); case BaseFunnyType.Int16: return(ToInt16); case BaseFunnyType.Int32: return(ToInt32); case BaseFunnyType.Int64: return(ToInt64); case BaseFunnyType.Real: return(ToReal); case BaseFunnyType.ArrayOf: case BaseFunnyType.Fun: case BaseFunnyType.Generic: case BaseFunnyType.Any: break; default: throw new ArgumentOutOfRangeException(); } } if (from.BaseType != to.BaseType) { return(null); } if (from.BaseType == BaseFunnyType.ArrayOf) { if (to == FunnyType.ArrayOf(FunnyType.Anything)) { return(o => o); } var elementConverter = GetConverterOrNull( from.ArrayTypeSpecification.FunnyType, to.ArrayTypeSpecification.FunnyType); if (elementConverter == null) { return(null); } return(o => { var origin = (IFunArray)o; var array = new object[origin.Count]; int index = 0; foreach (var e in origin) { array[index] = elementConverter(e); index++; } return new ImmutableFunArray(array, to.ArrayTypeSpecification.FunnyType); }); } if (from.BaseType == BaseFunnyType.Fun) { var fromInputs = from.FunTypeSpecification.Inputs; var toInputs = to.FunTypeSpecification.Inputs; if (fromInputs.Length != toInputs.Length) { return(null); } var inputConverters = new Func <object, object> [fromInputs.Length]; for (int i = 0; i < fromInputs.Length; i++) { var fromInput = fromInputs[i]; var toInput = toInputs[i]; var inputConverter = GetConverterOrNull(toInput, fromInput); if (inputConverter == null) { return(null); } inputConverters[i] = inputConverter; } var outputConverter = GetConverterOrNull(from.FunTypeSpecification.Output, to.FunTypeSpecification.Output); if (outputConverter == null) { return(null); } object Converter(object input) => new ConcreteFunctionWithConvertation( origin: (IConcreteFunction)input, resultType: to.FunTypeSpecification, inputConverters: inputConverters, outputConverter: outputConverter); return(Converter); } if (from.BaseType == BaseFunnyType.Struct) { foreach (var field in to.StructTypeSpecification) { if (!from.StructTypeSpecification.TryGetValue(field.Key, out var fromFieldType)) { return(null); } if (!field.Value.Equals(fromFieldType)) { return(null); } } return(NoConvertion); } return(null); }