Moderators SmOke_N Posted March 26, 2009 Moderators Share Posted March 26, 2009 When we nest functions, AutoIt will fire the functions off right to left.In this string example (from GUIListView.au3, (I added an extra parenthesis in there so I could account for erroneous issues)):BitShift(((_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, $icount, BitOR(BitShift($icy, -16), BitAND($icx, 0xFFFF))))), 16)Can any of you come up with a band of regex's or simple "efficient" function that will strip the functions out right to left?Example output:$a_strip_func[0] = BitAND($icx, 0xFFFF) $a_strip_func[1] = BitShift($icy, -16) $a_strip_func[2] = BitOr(a_strip_func[2], $a_strip_func[1]) $a_strip_func[3] = _SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, $icount, $a_strip_func[2]) $a_strip_func[4] = BitShift($a_strip_func[3], -16)Or, maybe even a personal preference output:$a_strip_func[0] = BitAND($icx, 0xFFFF) $a_strip_func[1] = BitShift($icy, -16) $a_strip_func[2] = BitOr(BitShift($icy, -16), BitAND($icx, 0xFFFF)) $a_strip_func[3] = _SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, $icount, BitOr(BitShift($icy, -16), BitAND($icx, 0xFFFF))) $a_strip_func[4] = BitShift(_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, $icount, BitOr(BitShift($icy, -16), BitAND($icx, 0xFFFF))), -16)I am not going to post what I have, because what I have is failing, and I don't want ya'll going down this dead path with me if you are going to attempt it, I'd rather see a fresh outlook and maybe build on that.*Keep in mind that some params may be strings, so if you're thinking of using StringSplit(), it very well could fail.* This expression should give you the functions names:"(\w+)\s*\("If I get it working properly before anyone posts a viable solution, I'll post what I did. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Authenticity Posted March 26, 2009 Share Posted March 26, 2009 (edited) expandcollapse popup#include <Array.au3> #include <String.au3> Dim $sTxt = 'BitShift(((_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT,' & _ '$icount, BitOR(BitShift($icy, -16), BitAND($icx, 0xFFFF))))), 16)' Dim $sPatt = '(\)(?:[^()]*|(?R))\(\w+\b)' Dim $aFuncs[1], $aMatches $sTxt = _StringReverse($sTxt) ConsoleWrite($sTxt & @LF) While 1 $aMatches = StringRegExp($sTxt, $sPatt, 3) If IsArray($aMatches) Then _ArrayDisplay($aMatches) If IsArray($aMatches) Then For $i = 0 To UBound($aMatches)-1 ReDim $aFuncs[UBound($aFuncs)+1] $aFuncs[UBound($aFuncs)-1] = $aMatches[$i] $sTxt = StringRegExpReplace($sTxt, '\Q' & $aMatches[$i] & '\E', '', 1) ConsoleWrite($aMatches[$i] & @TAB) ConsoleWrite($sTxt & @LF) Next Else ExitLoop EndIf WEnd ReDim $aFuncs[UBound($aFuncs)+1] $aFuncs[UBound($aFuncs)-1] = $sTxt $aFuncs[0] = UBound($aFuncs)-1 For $i = 1 To $aFuncs[0] $aFuncs[$i] = _StringReverse($aFuncs[$i]) Next If IsArray($aFuncs) Then _ArrayDisplay($aFuncs) I think it's possible to do it without reversing the string but with a cost of much complicated RegExp. Edited March 26, 2009 by Authenticity Link to comment Share on other sites More sharing options...
Andreik Posted March 26, 2009 Share Posted March 26, 2009 Why index 3 and 5 have only () and ((())). It should be the full function, not? When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Authenticity Posted March 26, 2009 Share Posted March 26, 2009 (edited) expandcollapse popup#include <Array.au3> #include <String.au3> Dim $sTxt = 'BitShift(((_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT,' & _ '$icount, BitOR(BitShift($icy, -16), BitAND($icx, 0xFFFF))))), 16)' Dim $sPatt = '(\)(?:[^()]*|(?R))\(\w+\b)', $sPattRepl = Chr(0xFC) & '\1' & Chr(0xFD), $sFunc Dim $aFuncs[1], $aMatches $sTxt = _StringReverse($sTxt) While 1 $aMatches = StringRegExp($sTxt, $sPatt, 3) If IsArray($aMatches) Then For $i = 0 To UBound($aMatches)-1 ReDim $aFuncs[UBound($aFuncs)+1] $aFuncs[UBound($aFuncs)-1] = $aMatches[$i] $aFuncs[UBound($aFuncs)-1] = StringRegExpReplace($aFuncs[UBound($aFuncs)-1], '\xfc', ')') $aFuncs[UBound($aFuncs)-1] = StringRegExpReplace($aFuncs[UBound($aFuncs)-1], '\xfd', '(') $sFunc = StringRegExpReplace($aMatches[$i], '\)([^(]*)\(.*', '\1', 1) $sTxt = StringRegExpReplace($sTxt, '\)(\Q' & $sFunc & '\E)\(', $sPattRepl, 1) Next Else ExitLoop EndIf WEnd ReDim $aFuncs[UBound($aFuncs)+1] $aFuncs[UBound($aFuncs)-1] = $sTxt $aFuncs[UBound($aFuncs)-1] = StringRegExpReplace($aFuncs[UBound($aFuncs)-1], '\xfc', ')') $aFuncs[UBound($aFuncs)-1] = StringRegExpReplace($aFuncs[UBound($aFuncs)-1], '\xfd', '(') $aFuncs[0] = UBound($aFuncs)-1 For $i = 1 To $aFuncs[0] $aFuncs[$i] = _StringReverse($aFuncs[$i]) Next If IsArray($aFuncs) Then _ArrayDisplay($aFuncs) Respecting the array elements. It's only the concept so it's clumsy and probably not efficient by any mean but it can get better in my opinion. Edited March 26, 2009 by Authenticity Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 26, 2009 Share Posted March 26, 2009 (edited) When we nest functions, AutoIt will fire the functions off right to left. I don't think that's true. They are interpreted left-to-right, and also checked for additional nesting in that order: expandcollapse popup; First test Global $sTest = "" ConsoleWrite(_MyFunc1(_MyFuncA()) & " :: " & _MyFunc2(_MyFuncB()) & " :: " & _MyFunc3(_MyFuncC()) & @LF) ConsoleWrite("First Test: $sTest = " & $sTest & @LF) ; Second test Global $sTest = "" _MyFuncX(_MyFunc1(_MyFuncA()), _MyFunc2(_MyFuncB()), _MyFunc3(_MyFuncC())) ConsoleWrite("Second Test: $sTest = " & $sTest & @LF) ; Functions Func _MyFunc1($vInput = "") $sTest &= "_MyFunc1()" & @CRLF Return 1 EndFunc Func _MyFunc2($vInput = "") $sTest &= "_MyFunc2()" & @CRLF Return 2 EndFunc Func _MyFunc3($vInput = "") $sTest &= "_MyFunc3()" & @CRLF Return 3 EndFunc Func _MyFuncA($vInput = "") $sTest &= "_MyFuncA()" & @CRLF Return "A" EndFunc Func _MyFuncB($vInput = "") $sTest &= "_MyFuncB()" & @CRLF Return "B" EndFunc Func _MyFuncC($vInput = "") $sTest &= "_MyFuncC()" & @CRLF Return "C" EndFunc Func _MyFuncX($vInput1 = "", $vInput2 = "", $vInput3 = "") $sTest &= "_MyFuncX()" Return "X" EndFunc Output: 1 :: 2 :: 3 First Test: $sTest = _MyFuncA() _MyFunc1() _MyFuncB() _MyFunc2() _MyFuncC() _MyFunc3() Second Test: $sTest = _MyFuncA() _MyFunc1() _MyFuncB() _MyFunc2() _MyFuncC() _MyFunc3() _MyFuncX() Edited March 26, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 26, 2009 Author Moderators Share Posted March 26, 2009 (edited) I fail to see what your test is supposed to prove. You have the output in a constant order. Anyway, think about this. If you're using SendMessage API and you use BitAnd() etc as a LPARAM, And you fire off the function left to right... Then you're sending a string with the "BitAnd()" in it, not the Ptr/Integer that you should be sending. Regardless, the right-left/left-right really has nothing to do with the request. Edit: My argument example isn't a very good one. And I think I proved my ownself wrong. ... but it still doesn't matter lol. Edited March 26, 2009 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
PsaltyDS Posted March 26, 2009 Share Posted March 26, 2009 I fail to see what your test is supposed to prove. You have the output in a constant order. The output shows the order they were executed in, which is the order the nested operations were performed in. Anyway, think about this. If you're using SendMessage API and you use BitAnd() etc as a LPARAM, And you fire off the function left to right... Then you're sending a string with the "BitAnd()" in it, not the Ptr/Integer that you should be sending. Regardless, the right-left/left-right really has nothing to do with the request. You're right that it probably doesn't matter = just a matter of technical language. What I meant was that your example would be interpreted in this order: Original: BitShift(((_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, $icount, BitOR(BitShift($icy, -16), BitAND($icx, 0xFFFF))))), 16) 1: BitShift($icy, -16) 2: BitAND($icx, 0xFFFF) 3: _SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT, {result of 1}, {result of 2}) 4: BitShift( {$result of 3}, 16) Because the BitShift() at 1 happens before the BitAnd() at 2, it is left-to-right. It could become significant if the two operations changed some global state that would effect the other's operation. But as you said, this does not address your real question. Sorry for the digression. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 27, 2009 Author Moderators Share Posted March 27, 2009 @Authenticity Kind of funny really, I thought about doing reverse as well. I have taken a different approach myself which I never did iron out yet. I will have a look at what yours is doing and see if maybe do a little of both and see how efficient they may be. Thanks Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Authenticity Posted March 27, 2009 Share Posted March 27, 2009 Regarding the discussion you had with PsaltyDS about the nested being actually evaluated from the most inner, left most, function call toward outside, right most function call. It may be necessary to preform the loop, instead of this: For $i = 0 To UBound($aMatches)-1 like this: For $i = UBound($aMatches)-1 To 0 Step -1. This way it's evaluated from the left most, inner most to the outside right most. ;] Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 27, 2009 Author Moderators Share Posted March 27, 2009 Regarding the discussion you had with PsaltyDS about the nested being actually evaluated from the most inner, left most, function call toward outside, right most function call. It may be necessary to preform the loop, instead of this:For $i = 0 To UBound($aMatches)-1like this:For $i = UBound($aMatches)-1 To 0 Step -1.This way it's evaluated from the left most, inner most to the outside right most. ;]Understood thanks...You did something in your expression that I actually had to look up (recursive), been a while since I had to do that! Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted March 27, 2009 Author Moderators Share Posted March 27, 2009 (edited) This was the original path I was taking:expandcollapse popup#include <array.au3> Dim $s_txt = "BitShift(((_SendMessage($hwnd, $LVM_APPROXIMATEVIEWRECT," & _ "$icount, BitOR(BitShift($icy, -16), BitAND($icx, 0xFFFF))))), 16)" $a_1 = _Func_GetNested($s_txt) $a_2 = _Func_GetNested($s_txt, 0) _ArrayDisplay($a_1, "one") _ArrayDisplay($a_2, "two") Func _Func_GetNested($s_text, $f_inorder = True) Local $a_funcs = StringRegExp($s_text, "(\w+)\s*\(", 3) If @error Then Return SetError(1, 0, 0) Local $a_func_list[UBound($a_funcs)] Local $s_temp = $s_text, $a_temp, $a_split Local $i_parenth_left = 0, $i_parenth_right = 0 For $i = 0 To UBound($a_funcs) - 1 $a_temp = StringRegExp($s_temp, $a_funcs[$i] & ".+\)\s*\z", 1) If @error Then ContinueLoop $a_func_list[$i] = $a_temp[0] $s_temp = StringRegExpReplace($s_temp, "\s*" & $a_funcs[$i] & "\s*\(\s*", "", 1) $a_split = StringSplit($a_func_list[$i], "") $i_parenth_left = 0 $i_parenth_right = 0 For $j = 1 To $a_split[0] If $a_split[$j] = "(" Then If StringRegExp($a_split[$j - 1], "\s|\w") Then $i_parenth_left += 1 EndIf If $a_split[$j] = ")" Then If StringRegExp($a_split[$j - 1], "[\s\w\(]") Then $i_parenth_right += 1 EndIf If $i_parenth_left And $i_parenth_left = $i_parenth_right Then $a_func_list[$i] = StringLeft($a_func_list[$i], $j) ExitLoop EndIf Next Next If $f_inorder Then Return $a_func_list Local $i_ub = UBound($a_func_list), $i_enum = 0 Local $a_ret_temp[$i_ub] For $i = $i_ub - 1 To 0 Step -1 $a_ret_temp[$i_enum] = $a_func_list[$i] $i_enum += 1 Next Return $a_ret_temp EndFunc Edited March 27, 2009 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Authenticity Posted March 27, 2009 Share Posted March 27, 2009 Yeah, it seems like an efficient way. I think that it'd be safe to exclude in both examples anything between " or ' as this is also valid but is not considered a function call ConsoleWrite("Use ConsoleWrite($sArgument) to out put to the console") So both paths don't eliminate this possibility. 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