Exemple #1
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object rhsResult = Rhs.Evaluate(context);
        bool   rhsBool   = TypeCoercer.CoerceToType <bool>(this, rhsResult);

        return(!rhsBool);
    }
Exemple #2
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object rhsResult = Rhs.Evaluate(context);
        float  rhsFloat  = TypeCoercer.CoerceToType <float>(this, rhsResult);

        return(-rhsFloat);
    }
Exemple #3
0
    private void AssignGenericDictionary <TKey, TValue>(IDictionary <TKey, TValue> dictionary, object key, object value)
    {
        TKey   coercedKey   = TypeCoercer.CoerceToType <TKey>(this, key);
        TValue coercedValue = TypeCoercer.CoerceToType <TValue>(this, value);

        dictionary[coercedKey] = coercedValue;
    }
Exemple #4
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object amount      = Rhs.Evaluate(context);
        float  floatAmount = TypeCoercer.CoerceToType <float>(this, amount);

        float floatCurrent = 0;

        // If the value doesn't already exists (and we can detect that) we start with zero.
        bool readCurrentValue = true;

        if (Lhs is ExistsSupport)
        {
            readCurrentValue = ((ExistsSupport)Lhs).Exists(context);
        }
        if (readCurrentValue)
        {
            object current = Lhs.Evaluate(context);
            floatCurrent = TypeCoercer.CoerceToType <float>(this, current);
        }

        float result = floatCurrent + floatAmount;

        ((AssignableToken)Lhs).Assign(context, result);

        return(result);
    }
        public object Evaluate(UnityELEvaluator context, ArgumentGroupToken group)
        {
            int arg1 = TypeCoercer.CoerceToType <int>(group, group.Children[0].Evaluate(context));
            int arg2 = TypeCoercer.CoerceToType <int>(group, group.Children[1].Evaluate(context));

            return(new TestObject(arg1, arg2));
        }
Exemple #6
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object rhsResult = Rhs.Evaluate(context);
        int    rhsInt    = TypeCoercer.CoerceToType <int>(this, rhsResult);

        return(~rhsInt);
    }
Exemple #7
0
    protected bool DoEvaluate(UnityELEvaluator context, object lhsResult)
    {
        Type lhsType = lhsResult?.GetType();

        // Otherwise the rhs must identify the type to match
        object rhsResult = Rhs.Evaluate(context);

        if (rhsResult == null)
        {
            return(false);
        }
        string rhsString = TypeCoercer.CoerceToType <string>(this, rhsResult);

        // Special handling for some primitives
        if (rhsString.Equals("int", StringComparison.InvariantCultureIgnoreCase) ||
            rhsString.Equals("integer", StringComparison.InvariantCultureIgnoreCase))
        {
            // Is it an int?
            if (typeof(int).Equals(lhsType))
            {
                return(true);
            }
            else if (typeof(float).Equals(lhsType))
            {
                // We use floats internally, so we allow them to be considered as 'ints' if it would
                // not result in the loss of any data
                float floatValue = (float)lhsResult;
                int   intValue   = (int)floatValue;

                return(intValue == floatValue);
            }
            else
            {
                return(false);
            }
        }
        else if (rhsString.Equals("float", StringComparison.InvariantCultureIgnoreCase))
        {
            // Allow floats or ints?
            return(typeof(float).Equals(lhsType) || typeof(int).Equals(lhsType));
        }
        else if (rhsString.Equals("bool", StringComparison.InvariantCultureIgnoreCase) ||
                 rhsString.Equals("boolean", StringComparison.InvariantCultureIgnoreCase))
        {
            return(typeof(bool).Equals(lhsType));
        }
        else if (lhsType != null)
        {
            // Otherwise we must match the end of the type name
            return(lhsType.FullName.EndsWith(rhsString, StringComparison.InvariantCultureIgnoreCase));
        }
        else
        {
            return(false);
        }
    }
Exemple #8
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object lhsResult = Lhs.Evaluate(context);
        object rhsResult = Rhs.Evaluate(context);

        float lhsFloat = TypeCoercer.CoerceToType <float>(this, lhsResult);
        float rhsFloat = TypeCoercer.CoerceToType <float>(this, rhsResult);

        return(FastExponent(lhsFloat, rhsFloat));
    }
Exemple #9
0
    private void AssignGenericList <TValue>(IList <TValue> list, int index, object value)
    {
        // Expand the list if needed
        while (index >= list.Count)
        {
            list.Add(default(TValue));
        }

        TValue coercedValue = TypeCoercer.CoerceToType <TValue>(this, value);

        list[index] = coercedValue;
    }
Exemple #10
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object host = Host.Evaluate(context);

        if (host == null)
        {
            return(null);
        }
        System.Type hostType = host.GetType();

        object key = Children[0].Evaluate(context);

        System.Type keyType = key?.GetType();

        // If the key is a string, we need to see if there is a property on the host that matches
        if (key is string)
        {
            PropertyInfo info = hostType.GetProperty((string)key);
            if (info != null)
            {
                return(info.GetValue(host));
            }
        }

        // Otherwise inspect the host to determine what to do
        if (host is IDictionary)
        {
            IDictionary dictionary = (IDictionary)host;
            if (dictionary.Contains(key))
            {
                return(dictionary[key]);
            }
            else
            {
                return(null);
            }
        }
        else if (host is IList)
        {
            IList list = (IList)host;
            int   i    = TypeCoercer.CoerceToType <int>(this, key);
            return(list[i]);
        }
        else if (host is Array)
        {
            Array array = (Array)host;
            int   i     = TypeCoercer.CoerceToType <int>(this, key);
            return(array.GetValue(i));
        }

        throw new ParserException(this, $"Unsupported host value type: {hostType}, or unknown property: {key}");
    }
Exemple #11
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object testResult = Test.Evaluate(context);
        bool   testBool   = TypeCoercer.CoerceToType <bool>(this, testResult);

        if (testBool)
        {
            return(ResultIfTrue.Evaluate(context));
        }
        else
        {
            return(ResultIfFalse.Evaluate(context));
        }
    }
        public object EvaluateForArgument(UnityELEvaluator context, string functionname, int argumentIndex, ArgumentGroupToken group)
        {
            if (functionname.Equals("myFunction"))
            {
                int arg1 = TypeCoercer.CoerceToType <int>(group, group.Children[0].Evaluate(context));
                int arg2 = TypeCoercer.CoerceToType <int>(group, group.Children[1].Evaluate(context));

                return(new TestObject2(arg1, arg2));
            }
            else
            {
                return(null);
            }
        }
Exemple #13
0
    public MethodInfo ResolveFunction(string name, Type[] parameterTypes)
    {
        MethodInfo bestMethod     = null;
        int        bestSimilarity = int.MaxValue;

        foreach (MethodInfo methodInfo in type.GetMethods())
        {
            if (!methodInfo.IsStatic)
            {
                continue;
            }

            if (methodInfo.Name.Equals(name))
            {
                ParameterInfo[] methodParameters = methodInfo.GetParameters();
                if (parameterTypes.Length != methodParameters.Length)
                {
                    continue;
                }

                int  similarity = 0;
                bool matched    = true;
                for (int i = 0; i < parameterTypes.Length; ++i)
                {
                    if (parameterTypes[i] == null)
                    {
                        continue;
                    }

                    Type methodParameterType = methodParameters[i].ParameterType;
                    if (!parameterTypes[i].Equals(methodParameterType))
                    {
                        matched = false;
                    }
                    similarity += TypeCoercer.GetTypeSimilarity(methodParameterType, parameterTypes[i]);
                }

                if (matched)
                {
                    return(methodInfo);
                }
                else if (similarity < bestSimilarity)
                {
                    bestMethod = methodInfo;
                }
            }
        }

        return(bestMethod);
    }
Exemple #14
0
    public override object Evaluate(UnityELEvaluator context)
    {
        FunctionDetails functionDetails = ResolveFunction(context);

        if (functionDetails.Function == null)
        {
            if (functionDetails.ResolutionFailedReason == null)
            {
                functionDetails.ResolutionFailedReason = $"Unable to resolve function: {functionDetails.Name} " +
                                                         $"(host={functionDetails.Host})"; //, namespace={functionDetails.Namespace})";
            }
            throw new NoSuchFunctionException(this, functionDetails.ResolutionFailedReason);
        }

        // Map parameters...
        MethodInfo    function   = functionDetails.Function;
        List <object> parameters = functionDetails.Parameters;

        ParameterInfo[] parameterInfos = function.GetParameters();
        if (parameterInfos.Length > 0)
        {
            // If there is a different number of arguments, see if the last argument is a params
            // and then wrap up the required number of arguments in an array (coercing as needed)
            ParameterInfo lastParam = parameterInfos[parameterInfos.Length - 1];
            if (lastParam.IsDefined(typeof(ParamArrayAttribute), false))
            {
                int   varargCount = parameters.Count - parameterInfos.Length + 1;
                Type  elementType = lastParam.ParameterType.GetElementType();
                Array varargs     = Array.CreateInstance(elementType, varargCount);
                for (int i = 0; i < varargCount; ++i)
                {
                    varargs.SetValue(TypeCoercer.CoerceToType(elementType, this,
                                                              parameters[parameters.Count - varargCount + i]), i);
                }

                parameters[parameterInfos.Length - 1] = varargs;
                parameters.RemoveRange(parameterInfos.Length,
                                       parameters.Count - parameterInfos.Length);
            }

            // Coerce the parameters if needed
            for (int i = 0; i < parameters.Count; ++i)
            {
                parameters[i] = TypeCoercer.CoerceToType(parameterInfos[i].ParameterType,
                                                         this, parameters[i]);
            }
        }

        return(function.Invoke(functionDetails.Host, parameters.ToArray()));
    }
Exemple #15
0
        public void DetectValidCoercions()
        {
            //Arrange
            var allCombinations = _testValues.Select(v => new { Value = v, Pairs = _testValues.Select(rhs => new { Value = v, Other = rhs }) });

            //Act
            //Here we are looking to detect what coercion is allowed - so we should count any coercion that changes the left hand type into the right hand type
            //as a disallowed conversion.
            var result = allCombinations.Select(tt => new
            {
                Left  = tt.Value,
                Valid = tt.Pairs
                        .Where(p => TypeCoercer.TryCoerceLeftOnly(p.Value, p.Other, out var newMine, out _) && newMine.GetType() == p.Other.GetType()) //i.e. where coercion works
                        .Select(p => p.Other.GetType())
            });                                                                                                                                        //i.e. all successful conversions where the left hand type was not changed.
Exemple #16
0
        public object Evaluate(UnityELEvaluator context, ArgumentGroupToken group)
        {
            // Assume its a vector if there are three arguments
            if (group.Children.Count == 3)
            {
                float x = TypeCoercer.CoerceToType <float>(group, group.Children[0].Evaluate(context));
                float y = TypeCoercer.CoerceToType <float>(group, group.Children[1].Evaluate(context));
                float z = TypeCoercer.CoerceToType <float>(group, group.Children[2].Evaluate(context));

                return(new Vector3(x, y, z));
            }
            else
            {
                return(null);
            }
        }
Exemple #17
0
    /**
     * Although this shares a fair bit of code with Evaluate, it is easier to read
     * as a separate method
     */
    public bool Exists(UnityELEvaluator context)
    {
        object host = Host.Evaluate(context);

        if (host == null)
        {
            return(false);
        }
        System.Type hostType = host.GetType();

        object key = Children[0].Evaluate(context);

        System.Type keyType = key?.GetType();

        // If the key is a string, we need to see if there is a property on the host that matches
        if (key is string)
        {
            PropertyInfo info = hostType.GetProperty((string)key);
            if (info != null)
            {
                return(true);
            }
        }

        // Otherwise inspect the host to determine what to do
        if (host is IDictionary)
        {
            IDictionary dictionary = (IDictionary)host;
            return(dictionary.Contains(key));
        }
        else if (host is IList)
        {
            IList list = (IList)host;
            int   i    = TypeCoercer.CoerceToType <int>(this, key);
            return(i < list.Count);
        }
        else if (host is Array)
        {
            Array array = (Array)host;
            int   i     = TypeCoercer.CoerceToType <int>(this, key);
            return(i < array.Length);
        }
        else
        {
            return(false);
        }
    }
Exemple #18
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object lhsResult = Lhs.Evaluate(context);
        object rhsResult = Rhs.Evaluate(context);

        if (lhsResult is float || lhsResult is int)
        {
            float lhsFloat = TypeCoercer.CoerceToType <float>(this, lhsResult);
            float rhsFloat = TypeCoercer.CoerceToType <float>(this, rhsResult);

            return(lhsFloat == rhsFloat);
        }
        else if (lhsResult != null)
        {
            return(lhsResult.Equals(rhsResult));
        }
        else
        {
            return(rhsResult == null);
        }
    }
Exemple #19
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object lhsResult = Lhs.Evaluate(context);
        object rhsResult = Rhs.Evaluate(context);

        // See if the lhs supports an operator overload for the rhs
        if (lhsResult != null)
        {
            OperatorInfo info = FindOperator(lhsResult.GetType(), "op_Multiply", rhsResult);
            if (info != null)
            {
                object coercedRhs = TypeCoercer.CoerceToType(info.OperandType, this, rhsResult);
                return(info.Method.Invoke(null, new object[] { lhsResult, coercedRhs }));
            }
        }

        // Otherwise just use a float multiplication
        float lhsFloat = TypeCoercer.CoerceToType <float>(this, lhsResult);
        float rhsFloat = TypeCoercer.CoerceToType <float>(this, rhsResult);

        return(lhsFloat * rhsFloat);
    }
Exemple #20
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object lhsResult = Lhs.Evaluate(context);
        object rhsResult = Rhs.Evaluate(context);

        string rhsTypeName = TypeCoercer.CoerceToType <string>(this, rhsResult);

        if (rhsTypeName == null)
        {
            throw new ParserException("Right-hand side of 'as' evaluated to null");
        }

        if ("int".Equals(rhsTypeName))
        {
            return(TypeCoercer.CoerceToType <int>(this, lhsResult));
        }
        else if ("float".Equals(rhsTypeName))
        {
            return(TypeCoercer.CoerceToType <float>(this, lhsResult));
        }
        else if ("string".Equals(rhsTypeName))
        {
            return(TypeCoercer.CoerceToType <string>(this, lhsResult));
        }
        else if ("bool".Equals(rhsTypeName))
        {
            return(TypeCoercer.CoerceToType <bool>(this, lhsResult));
        }
        else
        {
            Type type = Type.GetType(rhsTypeName);
            if (type == null)
            {
                throw new ParserException($"Could not resolve type from string: {rhsTypeName}");
            }

            return(TypeCoercer.CoerceToType(type, this, lhsResult));
        }
    }
Exemple #21
0
    public override object Evaluate(UnityELEvaluator context)
    {
        object lhsResult = Lhs.Evaluate(context);
        object rhsResult = Rhs.Evaluate(context);

        if (lhsResult.GetType() == typeof(string))
        {
            // String addition
            string lhsString = TypeCoercer.CoerceToType <string>(this, lhsResult);
            string rhsString = TypeCoercer.CoerceToType <string>(this, rhsResult);

            return(lhsString + rhsString);
        }
        else
        {
            // Mathmatic addition
            float lhsFloat = TypeCoercer.CoerceToType <float>(this, lhsResult);
            float rhsFloat = TypeCoercer.CoerceToType <float>(this, rhsResult);

            return(lhsFloat + rhsFloat);
        }
    }
    public override object Evaluate(UnityELEvaluator context)
    {
        float oldValue = 0;

        // If the value doesn't already exists (and we can detect that) we start with zero.
        bool readCurrentValue = true;

        if (Rhs is ExistsSupport)
        {
            readCurrentValue = ((ExistsSupport)Rhs).Exists(context);
        }
        if (readCurrentValue)
        {
            object current = Rhs.Evaluate(context);
            oldValue = TypeCoercer.CoerceToType <float>(this, current);
        }

        float newValue = oldValue - 1;

        ((AssignableToken)Rhs).Assign(context, newValue);

        return(newValue);
    }
Exemple #23
0
    private OperatorInfo FindOperator(Type type, string operatorName, object operand)
    {
        OperatorInfo bestMethod     = null;
        int          bestSimilarity = int.MaxValue;

        foreach (MethodInfo methodInfo in type.GetMethods())
        {
            if (!methodInfo.IsStatic)
            {
                continue;
            }
            else if (!methodInfo.Name.Equals(operatorName))
            {
                continue;
            }

            ParameterInfo[] methodParameters = methodInfo.GetParameters();
            if (methodParameters.Length != 2)
            {
                continue;
            }

            Type operandType = methodParameters[1].ParameterType;
            if (operand == null || operandType.Equals(operand.GetType()))
            {
                return(new OperatorInfo(methodInfo, operandType));
            }

            int similarity = TypeCoercer.GetTypeSimilarity(operandType, operand.GetType());
            if (similarity < bestSimilarity)
            {
                bestMethod = new OperatorInfo(methodInfo, operandType);
            }
        }

        return(bestMethod);
    }
    public void Assign(UnityELEvaluator context, object value)
    {
        PropertyDetails details = ResolveProperty(context);

        if (details == null)
        {
            throw new ParserException(this, $"Did not resolve host object: {Host}");
        }
        else if (details.Property == null)
        {
            throw new NoSuchPropertyException(this, $"Property: {details.Name} not found on type: {details.HostType}");
        }

        if (!details.Property.CanWrite || details.Property.SetMethod == null ||
            details.Property.SetMethod.IsPrivate)
        {
            throw new ParserException(this, $"Property: {details.Name} on type: {details.HostType} is read only");
        }

        System.Type propertyType = details.Property.PropertyType;
        object      coercedValue = TypeCoercer.CoerceToType(propertyType, this, value);

        details.Property.SetValue(details.Host, coercedValue);
    }
Exemple #25
0
    public T Evaluate(UnityELEvaluator context)
    {
        object result = root.Evaluate(context);

        return(TypeCoercer.CoerceToType <T>(root, result));
    }
Exemple #26
0
    public void Assign(UnityELEvaluator context, object value)
    {
        object host = Host.Evaluate(context);

        if (host == null)
        {
            throw new ParserException(this, $"Did not resolve host object: {Host}");
        }
        System.Type hostType = host.GetType();

        object key = Children[0].Evaluate(context);

        System.Type keyType = key?.GetType();

        // If the key is a string, we need to see if there is a property on the host that matches
        if (key is string)
        {
            PropertyInfo info = hostType.GetProperty((string)key);
            if (info != null)
            {
                if (!info.CanWrite || info.SetMethod == null || info.SetMethod.IsPrivate)
                {
                    throw new ParserException(this, $"Property: {key} on type: {hostType} is read only");
                }

                System.Type propertyType = info.PropertyType;
                object      coercedValue = TypeCoercer.CoerceToType(propertyType, this, value);

                info.SetValue(host, coercedValue);
                return;
            }
        }

        // Otherwise inspect the host to determine what to do
        if (host is IDictionary)
        {
            // See if there is a generic type information
            Type       genericDictionaryType         = typeof(IDictionary <,>);
            MethodInfo assignGenericDictionaryMethod = this.GetType().GetMethod("AssignGenericDictionary",
                                                                                BindingFlags.Instance | BindingFlags.NonPublic);
            foreach (Type type in hostType.GetInterfaces())
            {
                if (type.IsGenericType &&
                    type.GetGenericTypeDefinition() == genericDictionaryType)
                {
                    assignGenericDictionaryMethod.MakeGenericMethod(type.GetGenericArguments())
                    .Invoke(this, new object[] { host, key, value });
                    return;
                }
            }

            // Otheriwse, just use IDictionary
            IDictionary dictionary = (IDictionary)host;
            dictionary[key] = value;
        }
        else if (host is IList)
        {
            int i = TypeCoercer.CoerceToType <int>(this, key);

            // See if there is a generic type information available
            Type       genericListType         = typeof(IList <>);
            MethodInfo assignGenericListMethod = this.GetType().GetMethod("AssignGenericList",
                                                                          BindingFlags.Instance | BindingFlags.NonPublic);
            foreach (Type type in hostType.GetInterfaces())
            {
                if (type.IsGenericType &&
                    type.GetGenericTypeDefinition() == genericListType)
                {
                    assignGenericListMethod.MakeGenericMethod(type.GetGenericArguments())
                    .Invoke(this, new object[] { host, i, value });
                    return;
                }
            }

            // Otherwise just use IList

            // Expand the list if needed
            IList list = (IList)host;
            while (i >= list.Count)
            {
                list.Add(null);
            }

            list[i] = value;
        }
        else if (host is Array)
        {
            Array array = (Array)host;
            int   i     = TypeCoercer.CoerceToType <int>(this, key);
            if (i >= array.Length)
            {
                throw new ParserException(this, $"Array index out of bounds: {i}, length: {array.Length}");
            }
            array.SetValue(value, i);
        }
        else
        {
            throw new ParserException(this, $"Unsupported host value type: {hostType}, or unknown property: {key}");
        }
    }