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
Pil



Joined: 26 Feb 2006
Posts: 55
Location: Recife Brazil

PostPosted: Sun Nov 23, 2008 2:39 pm    Post subject: Reply with quote

What about writing code that permits use of ASM code in script using __mcode(FuncName, Hex). Not that I donīt like C, but most of languages I saw use Asm to speed up things. I am reading the GoAsm manual, seems to suit perfectly.
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Sun Nov 23, 2008 9:42 pm    Post subject: Reply with quote

ASM can be used as the source language for __mcode just as easily as C. Either way the code must be compiled/assembled first.
Back to top
View user's profile Send private message Visit poster's website
Pil



Joined: 26 Feb 2006
Posts: 55
Location: Recife Brazil

PostPosted: Sun Nov 23, 2008 10:47 pm    Post subject: Reply with quote

Thatīs what I meant.
Writing code that reads permitted asm line code in source script, then makes an .obj file with GoAsm, links it with GoLink,disassambles the exe with disassem, and takes machinecode out of produced txt file to put it in as an __mcode function on compile time.
Or another way?
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Mon Nov 24, 2008 7:58 am    Post subject: Reply with quote

Since "mcode" is short for "machine code," the function you describe would have to be __asm. Wink

I've never even heard of GoAsm before you mentioned it. You seem to have a reasonable understanding of how it might work, so why not try it yourself?

It is also feasible to write a basic assembler in AutoHotkey, using the Intel documentation as reference.

(If anyone has wondered what I've been working on the last few weekends...)
Back to top
View user's profile Send private message Visit poster's website
Pil



Joined: 26 Feb 2006
Posts: 55
Location: Recife Brazil

PostPosted: Mon Nov 24, 2008 10:36 pm    Post subject: Reply with quote

BITMAP example by SKAN with __mcode funcion by Lexikos.
Code:
ATC:=A_TickCount
SetBatchLines -1
DetectHiddenWindows, On
#include lowlevel.ahk
; Creating a 256x256 24bit bitmap file in memory
Id:="BM",Hdr:=54,W:=256,H:=256,Bit:=24,Byt:=W*H*(Bit/8),  VarSetCapacity(BMP,Hdr+Byt,0)
NumPut( NumGet( Id,0,"UShort" ),BMP,0,"UShort" ), NumPut( Hdr+Byt,BMP,2 )
NumPut( Hdr,BMP,10 ), NumPut( 40,BMP,14 ), NumPut( W,BMP,18 ), NumPut( H,BMP,22 )
NumPut( 1,BMP,26,"UShort" ), NumPut( Bit,BMP,28,"UShort" ), NumPut( Byt,BMP,34 )

Gui, 99:+AlwaysOnTop +ToolWindow +LastFound
Gui99:=WinExist(), hDC:=DllCall("GetDC",UInt,Gui99)
Gui, 99:Add, Text, w256 h256 0x120E hWndhPic gSelColor
;LowLevel.ahk required.
prepare_bitmap(bmp){
}LowLevel_init(),__mcode("prepare_bitmap"
, "8B4424088B088B118B0283C03633D29033C988104088084"
. "0C60000414081F9000100007CED4281FA000100007CE2C3")
prepare_bitmap(BMP)
hBMP := DllCall( "CreateDIBitmap", UInt,hDC, UInt,&BMP+14, Int,4, UInt,&BMP+NumGet(BMP,10)
              , UInt,&BMP+14, UInt,1 )       
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), hBMP,, ahk_id %hPic%
Gui, 99:Show,, % "ColorPicker [ " (A_TickCount-ATC) "ms ]"
Return

SelColor:
 MouseGetPos, X, Y
 PixelGetColor,Color, X, Y, RGB
 Tooltip % SubStr(Color,-5)
 SetTimer, TooltipOff, -2000
Return

ToolTipOff:
 ToolTip
Return

GuiClose:
 ExitApp

Lightning fast... giving me the enthousiam trying to write an "automation script" making possible to write simple asm code in AHK script.
However:
Lexikos wrote wrote:
It is also feasible to write a basic assembler in AutoHotkey, using the Intel documentation as reference.
(If anyone has wondered what I've been working on the last few weekends...)

Are you saying that thatīs where you are working on?
PS. Above script gives an error using beta version.
Back to top
View user's profile Send private message
tinku99



Joined: 03 Aug 2007
Posts: 308
Location: Houston, TX

PostPosted: Sun Dec 07, 2008 11:00 am    Post subject: save function created by __expr Reply with quote

I am able to keep the temp function created by __expr
as follows:
Code:
__expr(expr, pScopeFunc=0, function = "__expr_sub")
{
    static pThisFunc
        pFunc:=__getFuncUDF(function), pThisFunc:=__getFuncUDF(A_ThisFunc), __init()
   
    nInst := NumGet(pThisFunc+40)
    VarSetCapacity(Line%nInst%,44,0), __static(Line%nInst%), pLine:=&Line%nInst%

    if ! __ParseExpressionArg(expr, pArg:=&Line%nInst%+32, pScopeFunc)
        return
   
    NumPut(pArg,NumPut(1,NumPut(102,pLine+0,0,"char"),0,"char"),2)
    , NumPut(pLine,NumPut(pLine,pLine+16))
    , NumPut(pLine,pFunc+4)
    , ret := %function%()
    return ret
}

However, all the functions i create seem to point to the last function created.

Code:
setq(ByRef var, val){
var = %val%
}

myMsg(msg)
{
Msgbox % msg
}
function1() {
    global
    ; Contents replaced at run-time by __expr.
}
function2() {
    global
    ; Contents replaced at run-time by __expr.
}

F11::  ;; test various dynamic functions

setq(x, 5)
setq(y, 7)
__expr("myMsg(y)", 0, "function2")
__expr("myMsg(x)", 0, "function1")
function1()
function2()
return
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Lexikos



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

PostPosted: Sun Dec 07, 2008 12:01 pm    Post subject: Reply with quote

Pil wrote:
Are you saying that thatīs where you are working on?
Yes. You give the script basic assembly source, and it spits out a hexadecimal string. It is at a "functional but not useful" state. When it gets far enough to at least implement the simple function I wrote for SKAN's example, I'll start a thread. (Please save any further discussion until then.)
Quote:
PS. Above script gives an error using beta version.
I likely won't write a fix until after the next official (non-beta) release of AutoHotkey.
tinku99 wrote:
I am able to keep the temp function created by __expr as follows:
__expr reuses the same structures for each call, except when a previous call is still running. Below is an alternative which replaces the function's body, but does not call it. It should not be used on a given function more than once as it does not free the memory used by the text and derefs.
Code:
x=Ex.
y=Why?
LowLevel_init()
__expr_("function2", "myMsg(y)")
__expr_("function1", "myMsg(x)")
function1()
function2()

__expr_(function, expr, pScopeFunc=0)
{
    __init()
    pFunc:=__getFuncUDF(function)
    VarSetCapacity(Line%function%,44,0), __static(Line%function%), pLine:=&Line%function%
    if ! __ParseExpressionArg(expr, pArg:=&Line%function%+32, pScopeFunc)
        return false
    NumPut(pArg,NumPut(1,NumPut(102,pLine+0,0,"char"),0,"char"),2)
    , NumPut(pLine,NumPut(pLine,pLine+16))
    , NumPut(pLine,pFunc+4)
    return true
}


myMsg(msg)
{
Msgbox % msg
}
function1() {
    global
    ; Contents replaced at run-time by __expr.
}
function2() {
    global
    ; Contents replaced at run-time by __expr.
}

If you have a practical use for this, would you mind posting a demonstration?
Back to top
View user's profile Send private message Visit poster's website
tinku99



Joined: 03 Aug 2007
Posts: 308
Location: Houston, TX

PostPosted: Tue Dec 09, 2008 8:40 pm    Post subject: dynamic function creation Reply with quote

Lexikos wrote:

If you have a practical use for this, would you mind posting a demonstration?


Thanks Lexikos. That works.

I was just playing around with it.

No specific use for it yet.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Lexikos



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

PostPosted: Mon Jan 05, 2009 10:01 am    Post subject: Reply with quote

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.)

This makes easier my decision to stop development on LowLevel indefinitely, instead focusing my efforts on AutoHotkey_L. I intend to eventually introduce similar functionality.

That aside, some of you may find the following script interesting, especially those that know what the uses of an anonymous function are (since my example is not useful):
Code:
private=no
FuncA()

FuncA()
{
    static _T,_F ; Generate the exression function only once.
    if !_T
        LowLevel_init(),_T:=__findFunc(A_ThisFunc)
   
    private=yep
   
    ; Demonstrate that FuncB cannot access 'private' directly.
    MsgBox % FuncB("private")
    ; Demonstrate that via _T, functions created by __function CAN access our local variables.
    MsgBox % FuncB(__function(_F,"private '!'",_T) "()")
}

FuncB(x)
{
    if SubStr(x,-1)="()"
    {
        F := SubStr(x,1,-2)
        return %F%()
    }
    else
        return (%x%)
}

; Builds a function from a given expression, and returns its name.
; DO NOT CALL if func_buf has been assigned contents or given
;   non-zero capacity by anything other than this function.
; IT IS NOT SAFE to simply clear func_buf since it will not release
;   resources allocated by __ParseExpressionArg.
__function(ByRef func_buf, expr="", pScopeFunc=0)
{
    static ACT_RETURN:=102, VAR_ASSUME_LOCAL:=1
        , SIZE_FUNC:=52, SIZE_LINE:=32, SIZE_ARGSTRUCT:=12
        , func_index:=0
    LowLevel_init()
    if !(first_func:=__getFirstFunc())
        return ; FATAL ERROR.
   
    ; Recommended usage is to use 'func' to conveniently cache the result.
    ; func MUST have capacity=0 unless set by a previous call to this function.
    if VarSetCapacity(func_buf)
        return __str(NumGet(func_buf))
    if expr =
        return ; OOPS!
   
    ; Function name can be anything since AutoHotkey won't be validating it.
    func_index += 1
   
    VarSetCapacity(func_buf, SIZE_FUNC + SIZE_LINE + SIZE_ARGSTRUCT + StrLen(func_index) + 1, 0)
   
    ptr_func := &func_buf
    ptr_line := ptr_func + SIZE_FUNC
    ptr_arg  := ptr_line + SIZE_LINE
    ptr_name := ptr_arg  + SIZE_ARGSTRUCT
   
    DllCall("lstrcpy","uint",ptr_name,"str",func_index) ; Copy name into buffer.
   
    NumPut(ptr_name, ptr_func + 0) ; Func->Name
    NumPut(ptr_line, ptr_func + 4) ; Func->JumpToLine
    NumPut(VAR_ASSUME_LOCAL, ptr_func + 48, 0, "char") ; Func->DefaultVarType
   
    NumPut(ACT_RETURN | 1<<8, ptr_line + 0, 0, "short") ; Line->{ActionType,Argc}
    NumPut(ptr_arg, ptr_line + 4) ; Line->Arg
   
    ; ArgStruct will be initialised by the following call:
    __ParseExpressionArg(expr, ptr_arg, pScopeFunc)
   
    ; Now that Func, Line and ArgStruct are valid, insert function into list.
    NumPut(NumGet(first_func + 44), ptr_func + 44)
    NumPut(ptr_func, first_func + 44)
   
    return func_index ; Name, not address.
}
It has similar functionality to __expr_ in my previous post, but creates an entirely new function rather than overwriting an existing one.

A more useful function would support something like:
Code:
MyFunc(myparam) {
    ...
    Foreach(list, __function(_F
        , "(f, i) => mylocal .= f + myparam * i . ','"
    ,_T))
}

Foreach(list, func, delim=",") {
    Loop, Parse, list, %delim%
        %func%(A_LoopField, A_Index)
}
Entirely untested and probably useless pseudo-code. Yes, it is entirely feasible.
Back to top
View user's profile Send private message Visit poster's website
Titan



Joined: 11 Aug 2004
Posts: 4975
Location: /b/

PostPosted: Mon Jan 05, 2009 12:10 pm    Post subject: Reply with quote

Lexikos wrote:
(f, i) => mylocal .= f + myparam * i . ',
I see what you're doing there. While syntax sugar like delegates and reflection can be useful to fluent programmers, the typical AutoHotkey user would probably never get the hang of them. You could end up with feature bloat as py3k has taught us, not to mention the massive waste of time for the developer. Keep us updated on your new ideas though, it'll help me decide what to work into the IA lexer when I do it the first time round - like arrays for example.
_________________
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Lexikos



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

PostPosted: Tue Jan 06, 2009 8:20 am    Post subject: Reply with quote

Titan wrote:
You could end up with feature bloat as py3k has taught us,
It's a hypothetical script, not a proposal for a built-in feature.
Quote:
not to mention the massive waste of time for the developer.
Given its dependence on __expr, it would be only a small waste of time. Not small enough, I think.
Quote:
While syntax sugar like delegates and reflection can be useful to fluent programmers,
What I was suggesting was merely an extension of the function to allow a list of parameter names without requiring an extra parameter. As it is, the generated function cannot have parameters.

What does reflection have to do with syntax sugar?
Quote:
the typical AutoHotkey user
...has nothing to do with this thread. Razz
Back to top
View user's profile Send private message Visit poster's website
Titan



Joined: 11 Aug 2004
Posts: 4975
Location: /b/

PostPosted: Tue Jan 06, 2009 11:04 am    Post subject: Reply with quote

Lexikos wrote:
It's a hypothetical script, not a proposal for a built-in feature.
My statement was a hypothetical response.

Lexikos wrote:
some of you may find the following script interesting, especially those that know what the uses of an anonymous function are
Lexikos wrote:
an extension of the function to allow a list of parameter names without requiring an extra parameter.
In some languages there are anonymous delegates and object initializers. What you're describing is a mix of both, can you be more clear?

Lexikos wrote:
What does reflection have to do with syntax sugar?
In the low level (pun intended) sense that here it would cause a conversion to an intermediate form, or "pre-tokenized before evaluation [Line::ExpressionToPostfix()]." Anyway the point is not to discuss the definition of syntax sugar, I don't want to hijack this thread with another debate over semantics.

Lexikos wrote:
Quote:
the typical AutoHotkey user
...has nothing to do with this thread.
I probably haven't understood who the target audience for your AutoHotkey fork exactly is. Going by your response I would assume the proficient few programmers, correct?
_________________
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Lexikos



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

PostPosted: Tue Jan 06, 2009 12:40 pm    Post subject: Reply with quote

Titan wrote:
In some languages there are anonymous delegates and object initializers. What you're describing is a mix of both, can you be more clear?
I was a bit vague, speaking only in the context of __function.

__function creates a "Func" structure which can be dynamically called by AutoHotkey to evaluate an expression and return its result. My "idea" was strictly limited to allowing __function to add parameters to the "Func" it creates, for use in the expression.
Quote:
In the low level (pun intended) sense that here it would cause a conversion to an intermediate form, or "pre-tokenized before evaluation [Line::ExpressionToPostfix()]."
Thanks for the explanation. I now see what reflection has to do with the script, but my original point remains: Syntax defines how a functionality is accessed, but is not itself functional.

The way I see it now, dynamic function calls provide the capability for delegation, and LowLevel provides the capability for reflection. Neither are syntax, but the former is represented by such: %func%(). This you could say is syntax sugar, as there are longer ways to achieve similar results without having syntax specifically for it.

This brings me to __function("(params)=>expression") - syntax sugar for __function("params","expression"). (Just one way of placing less importance on the "params" param.)
Quote:
I don't want to hijack this thread with another debate over semantics.
By debating semantics, I come to a better understanding of what you really mean, rather than what I would mean if I spoke those words.

While the script I posted uses "reflection" to allow a function to be defined in-line, if it were a built-in feature as in C#, "reflection" would not be necessary. From a user's perspective, they are not using reflection, but using functionality made feasible by it.
Quote:
I probably haven't understood who the target audience for your AutoHotkey fork exactly is.
What I meant was that this thread, LowLevel, is absolutely not intended for typical AutoHotkey users - i.e. those that "would probably never get the hang of" its functionality.
Back to top
View user's profile Send private message Visit poster's website
Titan



Joined: 11 Aug 2004
Posts: 4975
Location: /b/

PostPosted: Tue Jan 06, 2009 3:46 pm    Post subject: Reply with quote

It was misleading of me to suggest that dynamic code or reflection is syntax sugar, with the same logic one could argue looping is no different as it can be done with conditional gotos. What I meant to refer to was the added stages in the lexer such that if "(params)=>expression" were to be converted to "params","expression" then reparsed and evaluated no new functionality has been added as far as the parser is concerned, hence low level syntactic sugar.

Lexikos wrote:
By debating semantics, I come to a better understanding of what you really mean, rather than what I would mean if I spoke those words.
As I see it there can only be a single definition. I am not a professional programmer so if my understanding is incorrect please let me know.

Lexicos wrote:
What I meant was that this thread, LowLevel, is absolutely not intended for typical AutoHotkey users
Lexicos earlier wrote:
This makes easier my decision to stop development on LowLevel indefinitely, instead focusing my efforts on AutoHotkey_L.
My posts were in fact directed towards your AutoHotkey fork and the concepts you're taking over from this script. Here seemed like the right place to discuss it.
_________________
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Lexikos



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

PostPosted: Tue Jan 06, 2009 9:59 pm    Post subject: Reply with quote

Quote:
My posts were in fact directed towards your AutoHotkey fork and the concepts you're taking over from this script. Here seemed like the right place to discuss it.
I should have qualified "similar functionality" by saying I intend to implement only a few key functionalities, like "reflection" and __expr.
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 6 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