DreamVB Posted October 7, 2014 Share Posted October 7, 2014 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 expandcollapse popup;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. Link to comment Share on other sites More sharing options...
guinness Posted October 8, 2014 Share Posted October 8, 2014 Good start. Check out my Shunting-Yard example of how I did it. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
DreamVB Posted October 9, 2014 Author Share Posted October 9, 2014 Hi here is a small update of my RPN Calculator. Fixed problem that only allowed single numbers. Added ^ operator. And a few other fixes. Code for Version 1.0a expandcollapse popup;Reverse Polish Notation Calculator v1.0a ;Updated works now with any number. ;Added ^ power of operator ;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] ;Add token $_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. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now