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); }