Cool, I've added some simple variable stuff :)
Edit: Fixed a small bug
' calculate.string.bmx by Daniel Wooden ' email: dan.wooden@... ' ' Simple variable stuff added by fredborg ' Keep variable names to single letters, as "x" may be confused with ie. "xx" by the evaluator ' Use FlushVariables() to reset variables. ' Const STACKSIZE:Int = 25 Global VarIndex:Int Global VarStack:String[ STACKSIZE, 2] Global TermsStack:String[ STACKSIZE ] Global MulDivStack:String[ STACKSIZE ] Global AddSubStack:String[ STACKSIZE ] ' ' Example SetVariable("x = 10") SetVariable("y = x*x*2") SetVariable("z = (x+y)/2") SetVariable("x = x+1") Print CalculateString("x+y+z") Print "GetVariable(~qx~q) = "+GetVariable("x") ' ' Verify result x# = 10 y# = x*x*2 z# = (x+y)/2 x = x+1 Print x+y+z Function SetVariable( in:String ) in = in.trim() va:String = String(in[..in.Find("=")]).Trim() pa:String = in[in.Find("=")+1..] ' ' Test if variable already exists For Local i:Int = 0 Until VarIndex If VarStack[i,0] = va VarStack[i,1] = CalculateString( pa ) Return EndIf Next ' ' It's a new variable VarStack[VarIndex,0] = va VarStack[VarIndex,1] = CalculateString( pa ) VarIndex :+ 1 End Function Function GetVariable:Float( in:String ) For Local i:Int = 0 Until VarIndex If VarStack[i,0] = in Return Float(VarStack[i,1]) Next EndFunction Function FlushVariables() VarIndex = 0 End Function Function InsertVariables:String( in:String ) For Local i:Int = 0 Until VarIndex in = in.Replace(VarStack[i,0],String(VarStack[i,1])) Next Return in End Function Function CalculateString:Float( Line:String ) Line = InsertVariables(Line) AnswerLine:String = "" CurrentChr:String = "" ' Remove Spaces For i = 0 To Line.Length CurrentChr = Chr( Line[ i ] ) If CurrentChr <> " " Then AnswerLine :+ CurrentChr End If Next PointA:Int = -1 PointB:Int = -1 While AnswerLine.Contains( "(" ) For i = 0 To AnswerLine.Length CurrentChr = Chr( AnswerLine[ i ] ) If CurrentChr = "(" Then PointA = i ElseIf CurrentChr = ")" Then PointB = i End If If PointA => 0 And PointB => 0 Then A:String = Mid( AnswerLine, PointA+2, PointB-PointA-1 ) A = CalculateScope( A ) B:String = Mid( AnswerLine, PointA+1, PointB-PointA+1 ) AnswerLine = AnswerLine.Replace( B, A ) Goto NextCalcStep End If Next #NextCalcStep PointA = -1 PointB = -1 Wend AnswerLine = CalculateScope( AnswerLine ) Return AnswerLine.ToFloat() End Function Function CalculateScope:Float( Line:String ) SplitTerms( Line ) CalcTerms() CalcValue:Float = 0.0 For i = 0 To STACKSIZE-1 If TermsStack[ i ] <> "" Then If i = 0 Then CalcValue = TermsStack[ i ].ToFloat() ElseIf TermsStack[ i ] = "+" Then CalcValue :+ TermsStack[ i+1 ].ToFloat() ElseIf TermsStack[ i ] = "-" Then CalcValue :- TermsStack[ i+1 ].ToFloat() End If End If Next For i = 0 To STACKSIZE-1 TermsStack[ i ] = "" MulDivStack[ i ] = "" AddSubStack[ i ] = "" Next Return CalcValue End Function Function SplitTerms( Line:String ) StackIndex:Int = 0 Value:String = "" CurrentChr:String = "" For i = 0 To Line.Length CurrentChr = Chr( Line[ i ] ) If CurrentChr = "+" Or CurrentChr = "-" Then TermsStack[ StackIndex ] = Value StackIndex :+ 1 TermsStack[ StackIndex ] = Chr( Line[ i ] ) StackIndex :+ 1 Value = "" ElseIf i = Line.Length TermsStack[ StackIndex ] = Value Else Value :+ Chr( Line[ i ] ) End If Next End Function Function CalcTerms() For i = 0 To STACKSIZE-1 If TermsStack[ i ] <> "+" And TermsStack[ i ] <> "-" And TermsStack[ i ] <> "" Then TermsStack[ i ] = MulDiv( TermsStack[ i ] ) End If Next End Function Function MulDiv:Float( Line:String ) Value:String = "" CurrentChr:String = "" CalcValue:Float = 0.0 StackIndex:Int = 0 For i = 0 To Line.Length CurrentChr = Chr( Line[ i ] ) If CurrentChr = "*" Or CurrentChr = "/" MulDivStack[ StackIndex ] = Value Value = "" StackIndex :+ 1 MulDivStack[ StackIndex ] = CurrentChr StackIndex :+ 1 ElseIf i = Line.Length Value :+ CurrentChr MulDivStack[ StackIndex ] = Value Else Value :+ CurrentChr End If Next For i = 0 To STACKSIZE-1 If MulDivStack[ i ] <> "" Then If i = 0 Then CalcValue = MulDivStack[ i ].ToFloat() ElseIf MulDivStack[ i ] = "*" Then CalcValue :* MulDivStack[ i+1 ].ToFloat() ElseIf MulDivStack[ i ] = "/" Then CalcValue :/ MulDivStack[ i+1 ].ToFloat() End If End If Next Return CalcValue End Function
Edit: Fixed a small bug