Jump to content


Photo

eval() - evaluate AutoHotkey expressions dynamically!


  • Please log in to reply
10 replies to this topic

#1 fincs

fincs
  • Fellows
  • 1532 posts

Posted 20 July 2012 - 08:28 PM

Some of you may remember that Lexikos' LowLevel.ahk used to support a nifty function called __expr(), but then...

I recently realised that __expr cannot easily be made to work with the pre-v1.0.48 beta, since all expressions must be pre-tokenized before evaluation. In other words, it would need to implement a full expression parser, which is simply something I will not do. (If Line::ExpressionToPostfix() were exposed to script it would be possible, but permanent memory would be allocated for each expression evaluated.)

... which is what I crazily did :D

Introducing...

expr() v1.0

This library allows you to dynamically execute AutoHotkey expressions on the fly, with NO temporary scripts at all! It works via parsing the expression manually using AHK source code translated from C++ to AHK (!), then executing it using a bit (understatement) of low-level magic. As such, it may or may not work with AutoHotkey versions newer than v1.1.08.

Usage is really simple:
MsgBox % eval("(1 + sqrt(5)) / 2")
eval("DllCall(""MessageBox"", ""ptr"", 0, ""str"", ""Hello, world!"", ""str"", A_ScriptName, ""uint"", 0)")
MsgBox % eval("eval(""2+2"")") ; you can even nest calls to eval()!
eval("variable := ""value""") ; variables are also supported...
eval("obj := { array: [2, 3, 5] }") ; even objects!
MsgBox % variable " | " obj.array[2]
Download - GitHub

Included with the package is calculator.ahk, which allows you to type commands. A fun one is this:
ComObjCreate("SAPI.SpVoice").Speak("Hello world!")
Limitations[*:1bxrzo80]You can only access global variables
[*:1bxrzo80]Double-derefs are not supported yet
[*:1bxrzo80]Clipboard is read-only
[*:1bxrzo80]ClipboardAll doesn't work
[*:1bxrzo80]obj.field(something) := val is not supported yet
[*:1bxrzo80]Compound object field assignment is not supported yet

#2 fragman

fragman
  • Members
  • 1591 posts

Posted 20 July 2012 - 09:22 PM

Very interesting! Could you point out some potential uses? A calculator obviously comes to mind, but other methods might be more suited as they could support units for example.

#3 fincs

fincs
  • Fellows
  • 1532 posts

Posted 20 July 2012 - 09:30 PM

fragman: well, I did not think of any uses besides making a calculator. I'll let users be creative :)

#4 flyingDman

flyingDman
  • Members
  • 1072 posts

Posted 21 July 2012 - 12:34 AM

What are the advantages over Lazlo's "Monster" (http://www.autohotke...pic.php?t=17058)?

#5 fincs

fincs
  • Fellows
  • 1532 posts

Posted 21 July 2012 - 09:40 AM

Laszlo's Monster does not support the full AutoHotkey expression syntax (including strings, objects and built-in functions/variables) and it sometimes did not evaluate expressions correctly when I was testing it a long time ago (sadly, I cannot remember which expressions they were).

#6 Lexikos

Lexikos
  • Administrators
  • 8855 posts

Posted 21 July 2012 - 01:31 PM

How does it compare to ExprEval(), which presumably isn't as version-dependent? Since you haven't mentioned ternary or short-circuit evaluation, I presume your function supports those.

NOTE: Does not support AHK_L object references, ternary operators, or boolean short-circuiting.



#7 fincs

fincs
  • Fellows
  • 1532 posts

Posted 21 July 2012 - 08:10 PM

How does it compare to ExprEval(), which presumably isn't as version-dependent? Since you haven't mentioned ternary or short-circuit evaluation, I presume your function supports those.

This library does support both ternary and short-circuit evaluation, as it's a pretty straightforward translation of AHK's expression parsing code. It also supports object syntax, variable operations (with some restrictions on built-in variables that are to be fixed) as well as function operations (including variadic calls). Also, it may be faster because it does not use RegEx (unlike Monster or ExprEval), it doesn't do ugly string operations (which the others do due to AHK Basic's lack of objects) and it lets AHK itself perform the evaluation (I haven't benchmarked it). Also, the source code is significantly more readable :)

#8 MasterFocus

MasterFocus
  • Moderators
  • 4132 posts

Posted 21 July 2012 - 09:44 PM

This is great, fincs. I suppose you don't intend to make a Basic-compatible version, right?

#9 fincs

fincs
  • Fellows
  • 1532 posts

Posted 21 July 2012 - 10:06 PM

MasterFocus: no, AutoHotkey Basic is ridiculously outdated and I don't plan on making scripts compatible with it anymore. Not to mention I make heavy use of objects and other new features, and in this case internal AHK structures.

#10 IsNull

IsNull
  • Fellows
  • 990 posts

Posted 22 July 2012 - 09:12 AM

fincs this is a great hack!

Injecting the tokens directly into the AHK Interpreter is really bad ass! :mrgreen:

Even this one works:
([10,20,30])[2]


#11 adrianh

adrianh
  • Members
  • 586 posts

Posted 17 November 2012 - 09:59 PM

Wow. Crazy! I'm a little afraid to use it. :)