ModelicaExpression appendIDinExpression(ModelicaExpression e, string ID) { switch (e) { case Literal l: return(l); case Reference r: return(new Reference() { ID = ID, Next = r }); case UnaryExpression u: u.Child = appendIDinExpression(u.Child, ID); return(u); case BinaryExpression b: b.Left = appendIDinExpression(b.Left, ID); b.Right = appendIDinExpression(b.Right, ID); return(b); default: return(e); } }
static ModelicaExpression MakeBinary(BinaryOperator op, ModelicaExpression left, ModelicaExpression right) { return(new BinaryExpression() { Operator = op, Left = left, Right = right }); }
Expression HandleExpression(DAEProblem problem, ModelicaExpression expr) { switch (expr) { case BinaryExpression b: { switch (b.Operator) { case BinaryOperator.Add: return(HandleExpression(problem, b.Left) + HandleExpression(problem, b.Right)); case BinaryOperator.Subtract: return(HandleExpression(problem, b.Left) - HandleExpression(problem, b.Right)); case BinaryOperator.Multiply: return(HandleExpression(problem, b.Left) * HandleExpression(problem, b.Right)); case BinaryOperator.Divide: return(HandleExpression(problem, b.Left) / HandleExpression(problem, b.Right)); case BinaryOperator.Power: return(Sym.Pow(HandleExpression(problem, b.Left), HandleExpression(problem, b.Right))); } } break; case UnaryExpression u: { switch (u.Operator) { case UnaryOperator.Negate: return(-HandleExpression(problem, u.Child)); case UnaryOperator.Parentheses: return(Sym.Par(HandleExpression(problem, u.Child))); case UnaryOperator.TimeDerivative: var y = HandleExpression(problem, u.Child) as Variable; if (y == null) { throw new InvalidOperationException("Cannot handle expressions inside der operator yet."); } var dery = new Variable("der(" + y.Name + ")", 0); var existingVar = problem.DifferentialVariables.FirstOrDefault(v => v.Name == dery.Name); if (existingVar == null) { problem.DifferentialVariables.Add(dery); problem.Mapping.Add(dery, y); return(dery); } else { return(existingVar); } default: throw new InvalidOperationException("Unknown unary operator " + u.Operator.ToString()); } } case BuiltinFunction u: { switch (u.Type) { case BuiltinFunctionType.Sin: return(Sym.Sin(HandleExpression(problem, u.Child))); case BuiltinFunctionType.Cos: return(Sym.Cos(HandleExpression(problem, u.Child))); case BuiltinFunctionType.Tan: return(Sym.Tan(HandleExpression(problem, u.Child))); case BuiltinFunctionType.Log: return(Sym.Ln(HandleExpression(problem, u.Child))); case BuiltinFunctionType.Exp: return(Sym.Exp(HandleExpression(problem, u.Child))); case BuiltinFunctionType.Sqrt: return(Sym.Sqrt(HandleExpression(problem, u.Child))); default: throw new InvalidOperationException("Unknown built-in fucntion " + u.Type.ToString()); } } case DoubleLiteral l: return(new Variable(l.Value.ToString(), l.Value)); case Reference r: { var vari = problem.ResolveReference(r.ToString()); if (vari != null) { return(vari); } else { throw new NullReferenceException("Variable " + r.ToString() + " not defined."); } } default: throw new InvalidOperationException("Unknown expression " + expr.ToString()); } return(null); }