Exemple #1
0
        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]);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
 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];
 }
Exemple #4
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));
        }
Exemple #5
0
        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");
            }
        }
Exemple #6
0
 public static IinputFunnyConverter GetInputConverter(FunnyType funnyType)
 => GetInputConverter(funnyType, 0);
Exemple #7
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);
        }