can you update the new RegEx version to support in-program variables?
i think that might be a solution to my problem:
http://www.autohotke...ost-329565.html
Simple script for evaluating arithmetic expressions
Started by
Laszlo
, Aug 23 2005 10:55 PM
37 replies to this topic
#31
-
Posted 05 February 2010 - 07:02 AM
oh whoops, maybe it already supports vars? i was glancing quickly for the old syntax [var] and didnt see the brackets
#32
-
Posted 05 February 2010 - 07:12 AM
Yes, the RegEx version handles global variables, too. The only problem is if they collide with local variables: i, y, y0, y1, y2, y3; or the parameter name: x. To reduce the chance of such collisions, here is a version which uses the following forbidden names, instead: _, __, ___, _0, _1, _2 and _3:
; Arithmetic expressions evaluator, handling ; unary +,- (-2*3; +3) ; +,-,*,/,\(or % = mod); **(or @ = power) ; (..); constants (pi,e); Global variables (not starting with '_'); abs(),sqrt(),floor() abs := 3, b := 2, c := 1 MsgBox % Eval("abs*b-c") ; 5 x := 10, y2 := 100 MsgBox % Eval("x+y2") ; 110 MsgBox % Eval("-floor(abs(sqrt(1))) * (+pi -((3%5))) +pi+ 2-1-1 + e-abs(sqrt(floor(2)))**2-e") ; 1 Eval(__) { ; expression preprocessing Static pi = 3.141592653589793, e = 2.718281828459045 StringReplace __, __,`%, \, All ; % -> \ for MOD __ := RegExReplace(__,"\s*") ; remove whitespace __ := RegExReplace(__,"([a-zA-Z]\w*)([^\w\(]|$)","%$1%$2") ; var -> %var% Transform __, Deref, %__% ; dereference all %var% StringReplace __, __, -, #, All ; # = subtraction StringReplace __, __, (#, (0#, All ; (-x -> (0-x If (Asc(__) = Asc("#")) __ = 0%__% ; leading -x -> 0-x StringReplace __, __, (+, (, All ; (+x -> (x If (Asc(__) = Asc("+")) StringTrimLeft __, __, 1 ; leading +x -> x StringReplace __, __, **, @, All ; ** -> @ for easier process Loop { ; find innermost (..) If !RegExMatch(__, "(.*)\(([^\(\)]*)\)(.*)", _) Break __ := _1 . Eval@(_2) . _3 ; replace "(x)" with value of x } Return Eval@(__) ; no more (..) } Eval@(__) { RegExMatch(__, "(.*)(\+|\#)(.*)", _) ; execute rightmost +- operator IfEqual _2,+, Return Eval@(_1) + Eval@(_3) IfEqual _2,#, Return Eval@(_1) - Eval@(_3) ; execute rightmost */% operator RegExMatch(__, "(.*)(\*|\/|\\)(.*)", _) IfEqual _2,*, Return Eval@(_1) * Eval@(_3) IfEqual _2,/, Return Eval@(_1) / Eval@(_3) IfEqual _2,\, Return Mod(Eval@(_1),Eval@(_3)) ; execute rightmost power StringGetPos ___, __, @, R IfGreaterOrEqual ___,0, Return Eval@(SubStr(__,1,___)) ** Eval@(SubStr(__,2+___)) ; execute rightmost function If !RegExMatch(__,".*(abs|floor|sqrt)(.*)", _) Return __ ; no more function IfEqual _1,abs, Return abs( Eval@(_2)) IfEqual _1,floor,Return floor(Eval@(_2)) IfEqual _1,sqrt, Return sqrt( Eval@(_2)) }
#33
-
Posted 05 February 2010 - 07:02 PM
I just logged in to say thanks for the code
I needed something that can calculate a global variable with the expression, and this solved my problem right away!
I needed something that can calculate a global variable with the expression, and this solved my problem right away!
#36
-
Posted 21 August 2012 - 12:14 PM
Here's a script for simple arithmetic that I wrote a while back. It makes heavy use of regular expressions and I think with very little effort can be extended to support more operations.
The script may look a bit long, but mostly because of the large comment block at the front ... it is otherwise pretty short, I think.
Enjoy!
Patrick
The script may look a bit long, but mostly because of the large comment block at the front ... it is otherwise pretty short, I think.
Enjoy!
Patrick
;; ----------------------------------------------------------------------- ;; Expression Evaluator ;; ;; Evaluate a simple arithmetic integer expression contained in the function's ;; (string) parameter. ;; ;; The supported expression elements include: ;; => Signed integer numbers, such as 5, -7 or +19 ;; => Addition and subtraction of numbers ;; => Multiplication and (integer) division of numbers ;; => Modulus (a%b = remainder when a is divided by b) ;; => Parenthesized sub-expressions, nested to any depth ;; ;; The expression evaluator obeys the precedence rules of arithmetic, which ;; means that it evaluates sub-expressions in the following order: ;; 1. Parenthesis ;; 2. Multiplication or Division ;; 3. Modulus ;; 4. Addition or Subtraction ;; ;; Examples of valid expressions: ;; a) 12 + 33 ;; b) 42 - 8 ;; c) 42 - -8 ;; d) 10 + 7 * (8 / (18 % 7)) - 18 / (11-8) ;; ;; Any unrecognized characters are left in the expression as-is. This can be used ;; to compute multiple expressions at the same time. For example, the input string ;; "3+5, 3*5" would evaluate to the pair "8, 15". Gen__Evaluate(Expression) { ; Recursively evaluate parenthesized expressions first, starting at the innermost layer. While RegExMatch(Expression, "\(([^()]*)\)", Terms) { Value := Gen__Evaluate(Terms1) StringReplace, Expression, Expression, %Terms%, %Value%, All } ; Evaluate multiplication and (integer) division. While RegExMatch(Expression, "([-+]?\d+)\s*([*/])\s*([-+]?\d+)", Terms) { if Terms2 = * { Value := Terms1 * Terms3 } else { Value := Terms1 // Terms3 } StringReplace, Expression, Expression, %Terms%, %Value% } ; Evaluate modulus operations with syntax "a % b". While RegExMatch(Expression, "([-+]?\d+)\s*%\s*([-+]?\d+)", Terms) { Value := Mod(Terms1, Terms2) StringReplace, Expression, Expression, %Terms%, %Value% } ; Evaluate addition and subtraction. While RegExMatch(Expression, "([-+]?\d+)\s*([-+])\s*([-+]?\d+)", Terms) { if Terms2 = + { Value := Terms1 + Terms3 } else { Value := Terms1 - Terms3 } StringReplace, Expression, Expression, %Terms%, %Value% } return Expression }
#37
-
Posted 21 August 2012 - 06:36 PM
edit: sorry, my bug report (deleted) was not related to this thread!
#38
-
Posted 20 September 2014 - 02:29 AM