AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

LowLevel & dynamic code
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Fri Jan 23, 2009 10:14 am    Post subject: Reply with quote

Lexikos wrote:
This makes easier my decision to stop development on LowLevel indefinitely,
I changed my mind. Wink

Quote:
1.0.1 - January 18, 2009
Numerous changes have been made to make this release compatible with AutoHotkey pre-v1.0.48 beta, breaking compatibility with older versions of AutoHotkey. Some features are no longer available due to changes in how expressions work.

LowLevel.ahk
  • Added __cacheEnable, __getTokenValue and __mcodeptr.
  • Disabled __expr.
Code.ahk
  • code_arg_deref no longer supports function derefs.
  • code_finalize now fails if code_arg was used to add an expression, and the arg's postfix array has not been set up.

See the first post for updated links. See the included documentation for details about the new functions.
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4515
Location: Boulder, CO

PostPosted: Fri Jan 23, 2009 4:18 pm    Post subject: Reply with quote

Lexikos wrote:
__expr is not supported
It is a pity. __expr is the only low level function I use every day...
Back to top
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 766

PostPosted: Fri Jan 23, 2009 5:03 pm    Post subject: Reply with quote

Indeed, __expr() was the main reason I was using LowLevel, because I needed dynamic (user-defined) functions with a dynamic (user-defined) number of parameters and AHK didn't seem to support that.

Is there an alternate way to do that, or is it no longer possible?
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
ZipCorruptionAlert
Guest





PostPosted: Fri Jan 23, 2009 9:54 pm    Post subject: Reply with quote

The zip you provided for AutoHotkey AutoHotkey pre-v1.0.48 beta is corrupt.
Back to top
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Sat Jan 24, 2009 3:12 am    Post subject: Reply with quote

Sorry, I think I created a new (empty) file by mistake. After re-uploading (er, uploading), downloading the file seems to give a corrupt zip if the name contains dots. Confused I've renamed and corrected the links.
Quote:
Is there an alternate way to do that, or is it no longer possible?
The magic of __expr was that AutoHotkey did not parse the expression fully until it was evaluated. Since that is inefficient, it now parses and tokenizes each expression at load time. For dynamically calling functions, the array of tokens can be created directly without much trouble, but a full expression parser would be much more work.

AutoHotkey_L has some improvements to dynamic function calling which I'm hoping Chris will integrate.

Edit:

Code:
; Requires AutoHotkey pre-v1.0.48 beta

Call(FunctionName, p1="__deFault__", p2="__deFault__", p3="__deFault__", p4="__deFault__", p5="__deFault__", p6="__deFault__", p7="__deFault__", p8="__deFault__", p9="__deFault__", p10="__deFault__")
{
    return Call_(FunctionName, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
}

Call_(FunctionName, ByRef p1="__deFault__", ByRef p2="__deFault__", ByRef p3="__deFault__", ByRef p4="__deFault__", ByRef p5="__deFault__", ByRef p6="__deFault__", ByRef p7="__deFault__", ByRef p8="__deFault__", ByRef p9="__deFault__", ByRef p10="__deFault__")
{
    static pn:="1,2,3,4,5,6,7,8,9,10", line
        , SYM_INVALID:=56, SYM_VAR:=3, SYM_FUNC:=55, SYM_OPERAND:=4, VAR_ALIAS:=0
    if !arg
        LowLevel_init(), arg := NumGet(NumGet(__findLabel("Call_expression_marker"),4),4)
    if !(func := __findFunc(FunctionName))
        return "", ErrorLevel:=1
    if NumGet(func+16) > 10 ; Give up, requires too many parameters.
        return "", ErrorLevel:=2
   
    ; Get pointer to alias var for use in the loop.
    this_param_var := __getVar(this_param)

    ; postfix must fit one ExprTokenType for each param, followed by a SYM_FUNC token
    ; representing a function call, a SYM_INVALID token terminating the expression and
    ; a DerefType holding a pointer to the function to call.
    VarSetCapacity(postfix, 204, 0) ; 16*(10+2) + 12*1
    this_postfix := &postfix
   
    pc := 0
    Loop, Parse, pn, `,
    {
        ; Ignore any parameters beyond the function's capacity.
        if (pc >= NumGet(func+12))
            break
       
        if (p%A_LoopField% == "__deFault__")
        {
            ; If this parameter is required, just pass empty string.
            if (pc < NumGet(func+16))
                p%A_LoopField% =
            else
                break
        }
       
        var := __getVar(p%A_LoopField%)
        ; Resolve ByRef/alias.
        if (NumGet(var+23,0,"char") = VAR_ALIAS)
            var := NumGet(var+12)
       
        ; Put param var into postfix array.
        NumPut(var, this_postfix+0), NumPut(SYM_VAR, this_postfix+8)
       
        ; Move to next token in postfix array, increment param count.
        this_postfix += 16
        pc++
    }
   
    ; Set up the DerefType at the end of the postfix array.
    func_deref := this_postfix+32
    NumPut(func, func_deref+4)
    NumPut(pc, func_deref+9, 0, "char")
   
    ; Set up SYM_FUNC token.
    NumPut(func_deref, this_postfix+0)
    NumPut(SYM_FUNC, this_postfix+8)
    this_postfix += 16
   
    ; Terminate postfix array.
    NumPut(SYM_INVALID, this_postfix+8)
   
    ; Set postfix array of the first arg of 'return' below.
    NumPut(&postfix, arg+12)
   
    Call_expression_marker:
    return, ("") ; Parentheses to force is_expression=true.
}
Back to top
View user's profile Send private message Visit poster's website
bmcclure



Joined: 24 Nov 2007
Posts: 766

PostPosted: Sat Jan 24, 2009 9:40 am    Post subject: Reply with quote

Wow; so if I'm understanding that correctly (and I definitely could be wrong) it will allow a dynamic function call by specifying the function name as the first parameter and any of 10 function params following it? If so, that should do pretty much take care of my problem.

Thanks for the response! (and explanation of the __expr removal)
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
Guest






PostPosted: Sat Jan 24, 2009 11:19 am    Post subject: Reply with quote

Where did you get the source code for the beta?
Back to top
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Sat Jan 24, 2009 11:20 am    Post subject: Reply with quote

Yes.

It works by manually tokenizing a function-call expression. Each token has a symbol defining what the token does, and depending on the symbol, a value. Tokens must be in the order they will be evaluated - i.e. "postfix" order.
  • SYM_VAR and other operand tokens are pushed onto the stack.
  • SYM_FUNC causes a function to be called using parameters popped off the stack. ExprTokenType->deref (uint at offset 0) points to a DerefType structure containing the function to call and number of parameters to pass. (I omitted this field from the LowLevel documentation because it wasn't useful in previous versions, but it is now.)
  • SYM_INVALID marks the end of the expression.
The actual values for the SYM_' constants are defined in the LowLevel documentation, under Enumerations -> SymbolType.

The expression could be visualised as p1 p2 p3 %FunctionName%(,,), except that %FunctionName% is resolved before the expression is evaluated. A script parsing a more complex expression would need to take into account precedence rules. For instance, a+b*c becomes a b c * +. DynCalc (and the AutoHotkey source code) went a long way in helping me to understand this process.
Anonymous wrote:
Where did you get the source code for the beta?
I asked for it.
Back to top
View user's profile Send private message Visit poster's website
bmcclure



Joined: 24 Nov 2007
Posts: 766

PostPosted: Sat Jan 24, 2009 11:42 am    Post subject: Reply with quote

Wow, I'm very impressed! Smile

Thanks a ton for this function. I can finally upgrade and enjoy the reported substantial speed increase of the beta and still use my scripts' numerous dynamic function calls (albeit in a slightly different way)
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
Joy2DWorld



Joined: 04 Dec 2006
Posts: 537
Location: Galil, Israel

PostPosted: Sun Mar 08, 2009 1:51 am    Post subject: Reply with quote

@Lexikos,


is there a reason the pre-parsing can't be exposed to allow creation of an expression token array, which can then be evaluated ?

(have not looked deeply at the new code, but was thinking about the eval issue with the pre-processing.)


hope this makes sense, and is not too ignorant of a question.
_________________
Joyce Jamce
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Sun Mar 08, 2009 4:23 am    Post subject: Reply with quote

Joy2DWorld wrote:
allow creation of an expression token array, which can then be evaluated ?
I already demonstrated it with Call() a few posts back.
Back to top
View user's profile Send private message Visit poster's website
Joy2DWorld



Joined: 04 Dec 2006
Posts: 537
Location: Galil, Israel

PostPosted: Sun Mar 08, 2009 9:47 am    Post subject: Reply with quote

Lexikos wrote:
Joy2DWorld wrote:
allow creation of an expression token array, which can then be evaluated ?
I already demonstrated it with Call() a few posts back.


if am understanding correctly, if an eval function could be easily added into AHK with a 'preproccess this' call inserted before the _expr logic.

Am I tracking correctly ?
_________________
Joyce Jamce
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Sun Mar 08, 2009 10:05 am    Post subject: Reply with quote

If you had a "preprocess this" function to call, then yes, it would be easy to support __expr. However, "preprocess this" would need to fully parse the expression, which is far from simple and would hardly be less work than a standalone expression evaluator.

Perhaps it would not be so bad to have a built-in function using Script::AddLine (since that is what resolves variable/function derefs, and because it may also support commands), with the caveat that each expression would consume memory that cannot be freed until the process terminates. I'm not likely to work on such a feature as there are some usages where this caveat is unacceptable.

Proper dynamic script evaluation is in my "some day" list. It would likely involve a separate build of AutoHotkey (from shared source code, using conditional compilation) which by necessity would have some important memory optimisations disabled. Until then, dynamic function calls and/or temporary scripts should suffice.
Back to top
View user's profile Send private message Visit poster's website
Joy2DWorld



Joined: 04 Dec 2006
Posts: 537
Location: Galil, Israel

PostPosted: Sun Mar 08, 2009 10:40 pm    Post subject: Reply with quote

haven't had time to get into details or look at new code, but seems good guess should be easy for chris to open the preprocessing to outside call and returned tthe oken list, ie, to include an eval() in AHK.

but, maybe am missing something.
_________________
Joyce Jamce
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4468
Location: Qld, Australia

PostPosted: Sun Mar 08, 2009 10:55 pm    Post subject: Reply with quote

Joy2DWorld wrote:
but, maybe am missing something.
See the second paragraph in my previous post.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Page 7 of 10

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group