public void ArrangeOpsInExecutionOrder() { this.m_slCalcOrder = new SortedList(); object oLastChunk = null; if (this.m_aChunks.Count == 1) { OperatorAndTerms opt = new OperatorAndTerms(null, 0, -1); this.m_slCalcOrder.Add(1, opt); } else { for (int i = 0; i < this.m_aChunks.Count; i++) { object oChunk = this.m_aChunks[i]; if (oChunk.GetType() == typeof(Operator)) { Operator op = (Operator)oChunk; int t1 = -1; int t2 = -1; if (op.IsBinary) { t1 = i - 1; t2 = i + 1; } else { if (op.IsPreOp) { if (oLastChunk == null) //like "-" in "-4" or "-var" { t1 = i + 1; } else if (oLastChunk.GetType() == typeof(Operator)) // or "*-4" { t1 = i + 1; } } if (t1 == -1) { t1 = i - 1; } } oLastChunk = oChunk; OperatorAndTerms opt = new OperatorAndTerms(op, t1, t2); this.m_slCalcOrder.Add((float)i / 1000 + op.Priority, opt); } } } }
public void ArrangeOpsInExecutionOrder() { this.m_slCalcOrder = new SortedList(); object oLastChunk = null; if (this.m_aChunks.Count == 1) { OperatorAndTerms opt = new OperatorAndTerms(null, 0, -1); this.m_slCalcOrder.Add(1, opt); } else { for (int i = 0; i < this.m_aChunks.Count; i++) { object oChunk = this.m_aChunks[i]; if (oChunk.GetType() == typeof(Operator)) { Operator op = (Operator)oChunk; int t1 = -1; int t2 = -1; if (op.IsBinary) { t1 = i-1; t2 = i+1; } else { if (op.IsPreOp) { if (oLastChunk == null) //like "-" in "-4" or "-var" t1 = i+1; else if (oLastChunk.GetType() == typeof(Operator)) // or "*-4" t1 = i+1; } if (t1 == -1) t1 = i-1; } oLastChunk = oChunk; OperatorAndTerms opt = new OperatorAndTerms(op, t1, t2); this.m_slCalcOrder.Add((float)i/1000+op.Priority, opt); } } } }
public Types.Object Evaluate(Executer exec) { //when an operator has been applied to two terms, other operators that involve //any of those terms must use the result of that operation. //So, keep a list of pointers that point to the resulting terms. Hashtable htTermPointers = new Hashtable(); for (int i = 0; i < this.m_aChunks.Count; i++) { ArrayList a = new ArrayList(); a.Add(i); htTermPointers.Add(i, a); } if (this.m_slCalcOrder == null) //don't why this should happen, though... { this.ArrangeOpsInExecutionOrder(); } //ArrayList aChunksCopy = new ArrayList(); ArrayList aChunksCopy = (ArrayList)this.m_aChunks.Clone(); Term t1 = null; Term tNew = null; for (int i = 0; i < this.m_slCalcOrder.Count; i++) { OperatorAndTerms opt = (OperatorAndTerms)this.m_slCalcOrder.GetByIndex(i); ArrayList aTerm1Ptr = (ArrayList)htTermPointers[opt.Term1Index]; ArrayList aTerm2Ptr = null; t1 = (Term)aChunksCopy[(int)aTerm1Ptr[0]]; //this.m_aChunks Term t2 = null; if (opt.Term2Index > 0) { aTerm2Ptr = (ArrayList)htTermPointers[opt.Term2Index]; t2 = (Term)aChunksCopy[(int)aTerm2Ptr[0]]; //this.m_aChunks } //now we've got the term(s). Perform the operation tNew = t1.PerformOperation(exec, opt.Op, t2); aChunksCopy[(int)aTerm1Ptr[0]] = tNew; //if there's a second term, change the pointer to it to the first term instead //so that successive operations use the result of this operation instead of the inital value if (t2 != null) { //aTerm2Ptr = (ArrayList)htTermPointers[opt.Term2Index]; //aTerm2Ptr[0] = opt.Term1Index; //htTermPointers[opt.Term1Index] = aTerm2Ptr; htTermPointers[opt.Term2Index] = aTerm1Ptr; } } //NOPE - no restoring, we've still got the originals (after rewrite): //Always restore directly after execution, making it ready for next execution: Types.Object o = tNew.Value; // t1.Value; //this.Restore(); return(o); }