//------------------------------------------------------------ // add a term to the Environment public MMC.Numbers.CNumber Evaluate(string NewTerm) { CTerm_Base Term = CTerm_Base.Compile(ref NewTerm, this); _Result.Value = (Term != null) ? Term.Calc(this) : null; return(_Result.Value); }
//************************************************************ // static helpers to generate a Term //************************************************************ // try to extract the next term from the string // put the term on the stack protected static CTerm_Base GetNextTerm(ref string Term, Stack <CTerm_Base> Stack, MMC.Calc.CEnvironment Env, TPriority Prio) { CTerm_Base Result = null; int Stack_Count = Stack.Count; while (!String.IsNullOrEmpty(Term) || Result != null) { // if we didn't find a term yet if (Result == null) { // find next operation Result = Env.FindOp(ref Term); // if we didn't find anything ... if (Result == null) { break; } } // This term ends if prio is less or equal, i.e. 2-3+2 = (2-3)+2 if (Result.Priotity <= Prio) { break; } // Let the Operation get their operands from stack or string CTerm_Base Next = Result.Compile(ref Term, Stack, Env); // and try to reduce the term as much as possible TTermType Type = Result.Type; Result = Result.Replace(Env); // check if we have to combine this Term with the TopOfStack // but only if the second term is not a number // e.g. "2sqrt2" = "2*sqrt2" if ((Type != TTermType.Number) && (Type != TTermType.Seperator) && (Stack.Count == Stack_Count + 1)) { Result = Env.Combine(Stack.Pop(), Result); Result = Result.Replace(Env); } // put the Operation onto the stack Stack.Push(Result); // and proceed with the next term (or null if none) Result = Next; } return(Result); }
//------------------------------------------------------------ public static CTerm_Base Compile(ref string Term, MMC.Calc.CEnvironment Env) { Stack <CTerm_Base> Stack = new Stack <CTerm_Base>(); CTerm_Base Pending = GetNextTerm(ref Term, Stack, Env, TPriority.none); if (Pending != null) { throw new CTermException("Could not compile completely!"); } if (Stack.Count != 1) { throw new CTermException("Mathematical operation missing!"); } return(Stack.Pop()); }