b := "a" a := "1+2" MsgBox % Eval(%b%)The parameter of the Eval() function can contain other Eval() calls, so the recursion you are asking for is there. It just does not seem to be a good idea to generally change the meaning of %var% to Eval(%var%). It is an interesting idea you could gain some convenience with, but we loose consistency and possibilities.

# Monster: evaluate math expressions in strings

I was trying to start the daunting task of creating something like an Eval function for my SteamWin needs, when I found this.

**Edit:**

I initially posted to ask if I could use your functions from Monster in my script, but when looking further into them, I realized they are more generalized than I need. So as a result, I'm just going to use them as a reference in creating a lightweight eval function for simple math.

Thanks so much for this amazing script. I've learned a lot just from looking at it.

MsgBox % Eval("-2+(-1+2)*3") Eval(x) { ; Evaluate arithmetic expression with numbers, + - / * ( ) Return Eval#(RegExReplace(x,"-","#")) ; # = subtraction, to distinguish from sign } Eval#(x) { ; Evaluate expression with numbers, + #(subtract) / * ( ). Recurse into (..) Return RegExMatch(x,"(.*)\(([^\(\)]+)\)(.*)",y) ? Eval#(y1 . Eval@(y2) . y3) : Eval@(x) } Eval@(x) { ; Evaluate expression with numbers, + #(subtract) / * RegExMatch(x,"(.*)(\+|#)(.*)",y) ; last + or - IfEqual y2,+, Return Eval@(y1) + Eval@(y3) IfEqual y2,#, Return Eval@(y1) - Eval@(y3) RegExMatch(x,"(.*)(\*|/)(.*)",y) ; last * or / IfEqual y2,*, Return Eval@(y1) * Eval@(y3) IfEqual y2,/, Return Eval@(y1) / Eval@(y3) Return x ? x : 0 ; empty expression: 0, number: unchanged }

It looks streamlined and lightweight, and it's perfect for my needs.

Thanks a million Laszlo!

#include MathMONSTER (Core) by Laszlo.ahk $^c:: if gvCtrlCTicks { if (( A_TickCount - gvCtrlCTicks ) < 501 ) { MonsterClip := ClipBoard if ( SubStr( MonsterClip, 0, 1) = "=" ) { MonsterEval := Eval( SubStr(MonsterClip, 1, -1) ) a := MonsterClip . MonsterEval } else { MonsterEval := Eval( MonsterClip ) a := MonsterEval } ClipBoard := a caretx := A_CaretX carety := A_CaretY if ( carety > 150 ) carety -= 25 else carety += 20 ToolTip, %a%,caretx,carety,2 SetTimer, RemoveToolTipMonster, 1100 } else { gvCtrlCTicks := A_TickCount Send ^c } } else { gvCtrlCTicks := A_TickCount Send ^c } Return RemoveToolTipMonster: SetTimer, RemoveToolTipMonster, Off ToolTip,,,,2 return

Thanks Laszlo for this great script!

Edit: I made a tweak in the Monster core, so instead of using "x" as a var prefix internally, it now uses "mmx":

If RegExMatch(x, "(\S*?)\s*:=\s*(.*)", y) { y := "x" . y1 ; user vars internally start with x to avoid name conflicts Return %y% := Eval1(y2) } x := RegExReplace(x,"([a-z_A-Z]\w*)([^\w'»’]|$)","%x$1%$2") ; VAR -> %xVAR%is now

If RegExMatch(x, "(\S*?)\s*:=\s*(.*)", y) { y := "mmx" . y1 ; user vars internally start with x to avoid name conflicts Return %y% := Eval1(y2) } x := RegExReplace(x,"([a-z_A-Z]\w*)([^\w'»’]|$)","%mmx$1%$2") ; VAR -> %xVAR%Enjoy,

Shawn

Seriously, Laszlo, you should try getting into Assembly, this stuff you do with AHK only already is amazing.

He already has He's got more than a few posts of binary ASM code to use in-line in AHK scripts to speed up various operations.

Note: To convert a radians value to degrees, multiply it by 180/pi (approximately 57.29578). To convert a degrees value to radians, multiply it by pi/180 (approximately 0.01745329252). The value of pi (approximately 3.141592653589793) is 4 times the arctangent of 1.

deg := 57.295779513082321 MsgBox % sin(30/deg) ; sine of 30 degrees MsgBox % deg*asin(0.5) ; arc sine of 0.5 in degreesIn Monster you can use 180/pi in place of deg, that is:

sin(30/180*pi) 180/pi*asin(0.5)

Monster: evaluate math expressions in strings w/o external programs

Would you allow Rosetta code to show your code, under its license instead of its link here?

<!-- m -->http://rosettacode.o... ... AutoHotkey<!-- m -->

Thanks.

.an abstract-syntax tree (AST) for the expression must be created from parsing the input

I was using the built-in constants and realized that you're using 1 gallon = 4.54609 liter (Imperial) rather than 3.785411784 liter (US)... :wink:

Marine Corps Gen. Joseph Dunford told senators at his Joint Chiefs of Staff confirmation hearing : “If you want to talk about a nation that could pose an existential threat to the United States, I'd have to point to Russia. And if you look at their behavior, it's nothing short of alarming.”

Thanks. I changed the first post to US gallon.you're using 1 gallon = 4.54609 liter (Imperial) rather than 3.785411784 liter (US)

MsgBox % Eval("$16 5.85")

It gives me 5.8499999999999996. Other examples show similar error.

:?:

Marine Corps Gen. Joseph Dunford told senators at his Joint Chiefs of Staff confirmation hearing : “If you want to talk about a nation that could pose an existential threat to the United States, I'd have to point to Russia. And if you look at their behavior, it's nothing short of alarming.”