# RPN Basic Calc

## Recommended Posts

hi This is a Simple RPN expression evaluator, it uses a stack based method to compute the expression.

I know there maybe a few bugs that need ironing out that I try and figure out, as I want to try and make something with this anyway this is just the first version. Hope you may find it us full.

And here is the code

```;Stack begin code
Local \$stksize = 255
Local \$stack[\$stksize]
Local \$stktop = -1

Func _isEmpty()
Return (\$stktop = -1)
EndFunc   ;==>_isEmpty

Func _isFull()
Return (\$stktop + 1 > \$stksize - 1)
EndFunc   ;==>_isFull

Func _StkTop()
Return \$stksize
EndFunc   ;==>_StkTop

Func _Push(\$Value)
If Not _isFull() Then
\$stktop += 1
\$stack[\$stktop] = \$Value
EndIf
EndFunc   ;==>_Push

Func _Pop()
Local \$item
\$item = \$stack[\$stktop]
\$stktop -= 1
Return \$item
EndFunc   ;==>_Pop

;Stack end code

;Start of RPN calc
Func CalcRPN(\$exp)
Local \$x
Local \$c
Local \$Result = 0

For \$x = 1 To StringLen(\$exp)
\$c = StringMid(\$exp, \$x, 1)
If Not StringIsSpace(\$c) Then
;Check for Digits
If StringIsDigit(\$c) Then
;Push digists onto the stack.
_Push(\$c)
EndIf
;Check for operators
If StringInStr("+-/*", \$c) Then
Switch \$c
Case "+"
;Pop of two values, and add the results.
\$Result = (_Pop() + _Pop())
Case "-"
;Pop of two values, and subtract the results.
\$Result = (_Pop() - _Pop())
Case "*"
;Pop of two values, and times the results.
\$Result = (_Pop() * _Pop())
Case "/"
;Pop of two values, and devide the results.
\$Result = (_Pop() / _Pop())
EndSwitch
;Push back the result
_Push(\$Result)
EndIf
EndIf
Next
Return \$Result
EndFunc   ;==>CalcRPN

;Calc Postfix.
MsgBox(64, "RPN Calc-Demo", "Answer = " & CalcRPN("3 5 5 5 + * +"));Infix 1 test 3 + 5 * (5+5)
MsgBox(64, "RPN Calc-Demo", "Answer = " & CalcRPN("3 3 + 3 +"));Infix 2 test 3+3+3```

On Error Resume Pulling Hair Out.

##### Share on other sites

Hi here is a small update of my RPN Calculator.

Fixed problem that only allowed single numbers.

And a few other fixes.

Code for Version 1.0a

```;Reverse Polish Notation Calculator v1.0a

;Updated works now with any number.

;Stack begin code
Local \$stksize = 255
Local \$stack[\$stksize]
Local \$stktop = -1
Local \$idx

Func _StkRetset()
ReDim \$stack[\$stksize]
\$st = -1
EndFunc   ;==>_StkRetset

Func _isEmpty()
Return (\$stktop = -1)
EndFunc   ;==>_isEmpty

Func _isFull()
Return (\$stktop + 1 > \$stksize - 1)
EndFunc   ;==>_isFull

Func _StkTop()
Return \$stksize
EndFunc   ;==>_StkTop

Func _Push(\$Value)
If Not _isFull() Then
\$stktop += 1
\$stack[\$stktop] = \$Value
EndIf
EndFunc   ;==>_Push

Func _Pop()
;Pop item of the stack removing it.
Local \$item
\$item = \$stack[\$stktop]
\$stktop -= 1
Return \$item
EndFunc   ;==>_Pop

Func _Peek()
;Show item with out removeing it
Return \$stack[\$stktop]
EndFunc   ;==>_Peek

;Stack end code

;Tokens stuff
Func StoreTokens(\$expr)
Local \$_Tokens[0]
Local \$count = 0
\$idx = 1
While (\$idx <= StringLen(\$expr))
;Reset token
\$Token = ""

;Skip white spaces
_SkipWhite(StringMid(\$expr, \$idx, 1))

;Check for digits
If StringIsDigit(StringMid(\$expr, \$idx, 1)) Then
While StringIsDigit(StringMid(\$expr, \$idx, 1))
\$Token &= StringMid(\$expr, \$idx, 1)
\$idx += 1
WEnd
EndIf

;Check for operators
If _IsOpSym(StringMid(\$expr, \$idx, 1)) Then
\$Token = StringMid(\$expr, \$idx, 1)
\$idx += 1
EndIf

If StringLen(\$Token) > 0 Then
ReDim \$_Tokens[\$count + 1]
\$_Tokens[\$count] = \$Token
;Get tokens count
\$count += 1
EndIf

;Reset token.
\$Token = Null
WEnd

Return \$_Tokens
ReDim \$_Tokens[0]
EndFunc   ;==>StoreTokens

Func _SkipWhite(\$c)
If StringIsSpace(\$c) Then
\$idx += 1
EndIf
EndFunc   ;==>_SkipWhite

Func _IsOpSym(\$c)
Switch \$c
Case "(", ")"
Return True
Case "+", "-"
Return True
Case "*", "/"
Return True
Case "^"
Return True
Case Else
EndSwitch
EndFunc   ;==>_IsOpSym

;Start of RPN calc
Func CalcRPN(\$Toks)
Local \$x
Local \$c
Local \$Result = 0

For \$x = 0 To UBound(\$Toks) - 1
;Get token
\$c = \$Toks[\$x]
;Check for Digits
If StringIsDigit(\$c) Then
;Push digists onto the stack.
_Push(\$c)
EndIf
;Check for operators
If _IsOpSym(\$c) Then
Switch \$c
Case "+"
;Pop of two values, and add the results.
\$Result = (_Pop() + _Pop())
Case "-"
;Pop of two values, and subtract the results.
\$Result = (_Pop() - _Pop())
Case "*"
;Pop of two values, and times the results.
\$Result = (_Pop() * _Pop())
Case "/"
;Pop of two values, and devide the results.
\$Result = (1 / _Pop() * _Pop())
Case "^"
;Power
Local \$a = _Pop()
Local \$b = _Pop()
\$Result = (\$b ^ \$a)
EndSwitch
;Push back the result
_Push(\$Result)
EndIf
Next

\$Toks = Null
Return \$Result
EndFunc   ;==>CalcRPN

Local \$Tokens[0]
;Get the tokens for the expression.
\$Tokens = StoreTokens("102 10 +")
;Calc Postfix.
MsgBox(64, "RPN Calc-Demo", "Answer = " & CalcRPN(\$Tokens));Infix 1 test 102+10
;Calc Postfix.
\$Tokens = StoreTokens("3 5 5 5 + * +")
MsgBox(64, "RPN Calc-Demo", "Answer = " & CalcRPN(\$Tokens));Infix 2 test 3 + 5 * (5+5)

;Calc Postfix.
\$Tokens = StoreTokens("2 8 ^")
MsgBox(64, "RPN Calc-Demo", "Answer = " & CalcRPN(\$Tokens)) ;2 ^ 8

\$Tokens = Null```

On Error Resume Pulling Hair Out.

## Create an account

Register a new account

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...