Exemplo n.º 1
0
        private void CheckMultipleVariableExpression(MultipleVariableExpression e, TypeCheckingContext context)
        {
            List <Type> elementTypes = new List <Type>();

            int index = 0;

            foreach (string variable in e.Variables)
            {
                Type elementType = context.RightOperandType.GenericTypeArguments[index];
                elementTypes.Add(elementType);
                context.VariableContext.Set(variable, context.CreateAutoCreatedVariableValue(elementType));
                index++;

                if (index > context.RightOperandType.GenericTypeArguments.Length - 1)
                {
                    break;
                }
            }


            Type baseType = null;

            int elementCount = elementTypes.Count;

            if (elementCount == 1)
            {
                baseType = typeof(Tuple <>);
            }
            else if (elementCount == 2)
            {
                baseType = typeof(Tuple <,>);
            }
            else if (elementCount == 3)
            {
                baseType = typeof(Tuple <, ,>);
            }
            else if (elementCount == 4)
            {
                baseType = typeof(Tuple <, , ,>);
            }
            else if (elementCount == 5)
            {
                baseType = typeof(Tuple <, , , ,>);
            }
            else if (elementCount == 6)
            {
                baseType = typeof(Tuple <, , , , ,>);
            }

            e.Type = baseType.MakeGenericType(elementTypes.ToArray());
        }
        private object EvaluteBinaryExpression(BinaryExpression e, VariableContext context, out bool isEvaluated)
        {
            isEvaluated = false;


            bool isTupleValue = e.Right.Type.Name.Contains("Tuple");

            if (e.Operator == BinaryOperator.Assign && (e.Left is MultipleVariableExpression || isTupleValue))
            {
                isEvaluated = true;

                object rightValue = Evaluate(e.Right, context);


                if (e.Left is MultipleVariableExpression)
                {
                    MultipleVariableExpression mv = e.Left as MultipleVariableExpression;

                    if (isTupleValue)
                    {
                        int count = mv.Type.GenericTypeArguments.Length;

                        for (int i = 0; i <= count - 1; i++)
                        {
                            context.Set(mv.Variables[i], rightValue.GetType().GetProperty("Item" + (i + 1)).GetValue(rightValue));
                        }
                    }
                    else
                    {
                        context.Set(mv.Variables[0], rightValue);
                    }
                }
                else
                {
                    context.Set((e.Left as VariableExpression).VariableName, rightValue.GetType().GetProperty("Item1").GetValue(rightValue));
                }


                return(rightValue);
            }
            else if (e.Operator == BinaryOperator.Add)
            {
                if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Add(Evaluate(e.Right, context) as Matrix));
                }
                else if (e.Left.Type == typeof(Matrix) && Types.IsNumberType(e.Right.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Add(Types.ConvertValue <double>(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Matrix) && Types.IsNumberType(e.Left.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Matrix).Add(Types.ConvertValue <double>(Evaluate(e.Left, context))));
                }
                else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Vector).Add(Types.ConvertValue <double>(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Vector).Add(Types.ConvertValue <double>(Evaluate(e.Left, context))));
                }
            }
            else if (e.Operator == BinaryOperator.Subtract)
            {
                if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Add((Evaluate(e.Right, context) as Matrix).ToNegative()));
                }
                else if (e.Left.Type == typeof(Matrix) && Types.IsNumberType(e.Right.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Subtract(Types.ConvertValue <double>(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Matrix) && Types.IsNumberType(e.Left.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Matrix).Subtract(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative());
                }
                else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Vector).Subtract(Types.ConvertValue <double>(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Vector).Subtract(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative());
                }
            }
            else if (e.Operator == BinaryOperator.Multiply)
            {
                if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Multiply(Evaluate(e.Right, context) as Matrix));
                }
                else if (e.Left.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Multiply(Convert.ToDouble(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Matrix).Multiply(Convert.ToDouble(Evaluate(e.Left, context))));
                }
                else if (e.Left.Type == typeof(Vector) && Types.IsNumberType(e.Right.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Vector).Multiply(Types.ConvertValue <double>(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Vector) && Types.IsNumberType(e.Left.Type))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Vector).Multiply(Types.ConvertValue <double>(Evaluate(e.Left, context))).GetNegative());
                }
            }
            else if (e.Operator == BinaryOperator.Divide)
            {
                if (e.Left.Type == typeof(Matrix) && e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Divide((Evaluate(e.Right, context) as Matrix)));
                }
                else if (e.Left.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Matrix).Multiply(1 / Convert.ToDouble(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Matrix))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Matrix).ElementInvert().Multiply(Convert.ToDouble(Evaluate(e.Left, context))));
                }
                if (e.Left.Type == typeof(Vector))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Left, context) as Vector).Multiply(1 / Convert.ToDouble(Evaluate(e.Right, context))));
                }
                else if (e.Right.Type == typeof(Vector))
                {
                    isEvaluated = true;
                    return((Evaluate(e.Right, context) as Vector).ElementInvert().Multiply(Convert.ToDouble(Evaluate(e.Left, context))));
                }
            }


            return(null);
        }