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
majkinetor



Joined: 24 May 2006
Posts: 4114
Location: Belgrade

PostPosted: Wed Dec 19, 2007 9:43 am    Post subject: Reply with quote

Nice.

I wait for dynamic code insertion Smile

Btw, do you (still) plan to let us iterate global/local variables ?
I needed that bunch of times.

Thx.
_________________
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Wed Dec 19, 2007 12:08 pm    Post subject: Reply with quote

Local variables can already be enumerated, as I demonstrated earlier.

LowLevel does not and will not have access to the script's list/array of global variables. Since ListGlobalVars only gets the ListVars text, I think including it in LowLevel would not be appropriate.
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4114
Location: Belgrade

PostPosted: Wed Dec 19, 2007 1:02 pm    Post subject: Reply with quote

Quote:
Since ListGlobalVars only gets the ListVars text, I think including it in LowLevel would not be appropriate.

Only ? Well, in AHK, almost everything is only text.

Anyway, I would like other way to get variables, that doesn't depend on redirection of OS API (although hacks like this are awesome)

Btw, the way you post it, can produce bad side-effects if some process jumps in the middle of redirection. So it should look like this:

Code:
   
    critical 100000000   ;make critical section, nothing can interupt now, even win message
    NumPut(0x0004C200000001B8, pSFW+0, 0, "int64")  ; return TRUE
    NumPut(0x0008C200000001B8, pSW+0, 0, "int64")   ; return TRUE
   

    ListVars
    NumPut(bkpSFW, pSFW+0, 0, "int64")
    NumPut(bkpSW, pSW+0, 0, "int64")
    critical off    ;we are done hacking, remove the critical section


Then, we have problem number 2:

Quote:
A multiline edit control is also subject to the following limitations:
• The maximum number of characters in a single line is 1024.
• The maximum width of a line is 30,000 pixels.
The maximum number of lines is approximately 16,350.

which means that above function can not handle more then 16.347 variables user created which really makes it insufficient for large arrays, I can easily make more in simple tests...

Also, I dont' know if above code can be seen as "potentialy harmfull operation" by some software, or even OS itself (probably not).

So, you should make this available in lowlevel if possible. Something like above, maybe a bit more flexibile, like some basic filtering, ability to get only local or global variables etc...
_________________


Last edited by majkinetor on Wed Dec 19, 2007 3:36 pm; edited 2 times in total
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4114
Location: Belgrade

PostPosted: Wed Dec 19, 2007 3:11 pm    Post subject: Reply with quote

And yet, there is problem number 3 - if variable has `r`n in its contenst it may produce side effects, for instance:

Code:
s :="which is real ? :) `r`nvar[6 of 7]: damn !"
var:= "damn !"
listvars
pause


This can generaly be solved by checking each line to see if it is variable (using your lowlevel module, or using SKAN's method with fixed pointer IIRC) but this will slow down things and will also in second case create bunch of empty variables....
_________________
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Wed Dec 19, 2007 11:38 pm    Post subject: Reply with quote

All good reasons not to include it in LowLevel. I consider any discussion of the drawbacks of ListGlobalVars off-topic.
majkinetor wrote:
Only ? Well, in AHK, almost everything is only text.
What I mean is it has no real relation to the purpose or theme of LowLevel.
majkinetor wrote:
So, you should make this available in lowlevel if possible.
As I have said, LowLevel does not and will not have access to the script's list/array of global variables. Not because I don't want it; because it isn't possible, since AutoHotkey normally accesses it via a member of the Script class, which can only be referenced through a global (C++) variable.

Variable dereferences may be discovered by using __getFirstLine (or __findFunc/__findLabel) and NumGet, referring to lowlevel_outline.txt (Line, ArgStruct, DerefType.) See, for example, __getBuiltInVar. This method won't work for double-derefs/arrays. Would a function with this limitation be useful?
Back to top
View user's profile Send private message Visit poster's website
freakkk



Joined: 29 Jul 2005
Posts: 179

PostPosted: Fri Jan 04, 2008 7:08 pm    Post subject: Reply with quote

Thanks for this new set of toys. Very, very useful indeed! Very Happy

So I'm just now getting a chance to play around with them.. & I found that I can't utilize pScopeFunc for internal commnads that fill arrays (RegExMatch).
Code:
  MyFunc()
  MsgBox,, Global Results, % "Result = " . Result . "`n"
                           . "Match1 = " . Match1

;----
MyFunc()  {
  ; Using global scope, array is populated successfully...
;   __expr( "Result := RegExMatch( 'My string', '(.*)', Match )" )


  ; Using local scope, array doesn't wanna work..
  __expr( "Result := RegExMatch( 'My string', '(.*)', Match )", __findFunc( A_ThisFunc ) )
 
  MsgBox,, Local Results, % "Result = " . Result . "`n"
                          . "Match1 = " . Match1
}

Quote:
Double-derefs in __expr always resolve to a global variable.
I'm not sure if this is what you were referring to here.. as I am ignorant of what double/triple derefs are by definition. I did try searching around a bit- but didn't get too far Laughing

Is this limitation here to stay.. or this issue one that will most likely go away as your module matures Question

Thanks in advance..
_________________
.o0[ corey ]0o.
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Sat Jan 05, 2008 1:19 am    Post subject: Reply with quote

freakkk wrote:
So I'm just now getting a chance to play around with them.. & I found that I can't utilize pScopeFunc for internal commnads that fill arrays (RegExMatch).
I hadn't thought of that. Array-creating functions/commands create local variables in the function that called them, if the base variable is local. Since the expression is executed in __expr_last(), that is where the array variables are created.

It might be possible to "synchronize" __expr_last and pScopeFunc, similar to how __getVarInContext works. However, this could only happen before or after executing the expression. In the worst case, the expression creates too many variables, causing the variable list to be reallocated, then recurses into scope func (either the expression or an interrupting thread might call it.) If the function tried to access the now-deleted variable list (i.e. by using a double-deref or ListVars), AutoHotkey would crash.

I suppose the variables could be manually copied from __expr_last, but there'd be no way of knowing which variables were created by the current expression, since variables can't be deleted. It would also leave junk in __expr_last, and the variables wouldn't be accessible by the scope func if it recurses before the expression completes.

The safest workaround is to declare 'Match' as global, or use global scope. ('Match1', 'Match2', etc. must also be declared global if you wish to access them in script.)
Quote:
I'm not sure if this is what you were referring to here.. as I am ignorant of what double/triple derefs are by definition.
Code:
a := "value!"
var_containing_name := "a"
value_of_a := %var_containing_name% ; <- double-deref
Code:
LowLevel_init()
d = c
c = b
b = a
a = value!
MsgBox % __expr("%" %d% "%") ; <- quadruple-deref :D

Quote:
Is this limitation here to stay..
It will stay until I write dynamic code-insertion methods. Then you'll be able to insert the expression into the scope func itself. Very Happy (__expr might always have the limitation, though.)
Back to top
View user's profile Send private message Visit poster's website
Lexikos



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

PostPosted: Tue Jan 08, 2008 4:55 am    Post subject: Reply with quote

I wrote:
About the poll: I get sick of typing (and seeing) __ in my posts and my code, so I am considering renaming the functions. For most functions I may simply remove __, but some I think should be changed to be less ambiguous. The revised names I am considering are:
Code:
LowLevel_init           LowLevel_init
; No need for two init functions.
__init                  LowLevel_init
; Better reflects the actual purpose.
__mcode                 MakeFuncBuiltIn
; Not ambiguous with regular static keyword because it requires ().
__static                Static
; "Struct" reduces the likelihood of a naming conflict,
; and better reflects the actual purpose.
__getVar                GetVarStruct
__getGlobalVar          GetVarStructGlobal
__getBuiltInVar         GetVarStructBuiltIn
__getVarInContext       GetVarStructInContext
; No "Struct" because it returns a list of names.
__listFuncs             ListFuncs
__findFunc              FindFuncStruct
__getFirstFunc          GetFirstFuncStruct
__listLabels            ListLabels
__findLabel             FindLabelStruct
__getFirstLabel         GetFirstLabelStruct
__getFirstLine          GetFirstLineStruct
__getFuncUDF            GetUdfFuncStruct
__str                   GetStrAt
; "Eval" is already in use by at least two scripts.
; "Expr" more accurately represents the actual functionality.
__expr                  Expr
__MakeExpressionArg     MakeExpressionArg
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 7171

PostPosted: Tue Jan 08, 2008 7:12 am    Post subject: Reply with quote

My vote: I like __underscores Smile
Back to top
View user's profile Send private message
Joy2DWorld



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

PostPosted: Tue Jan 08, 2008 2:31 pm    Post subject: Reply with quote

@lexikos

please use a short & standard lib prefix and _


this is a FUNDAMENTAL and BREAKTHRU function...

should be easy to use, and safe function name wise.


even

LEX_xxx


or

my own favorate

eval_(



anyhow. my 2cents
_________________
Joyce Jamce
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4114
Location: Belgrade

PostPosted: Tue Jan 08, 2008 2:58 pm    Post subject: Reply with quote

I voted for first option. __ in all other languages signify some form of low level thing. If I have to choose anything else it would be LL_
_________________
Back to top
View user's profile Send private message
Laszlo



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

PostPosted: Tue Jan 08, 2008 3:06 pm    Post subject: Reply with quote

I also voted for the first option: keep __prefix. If this script is used to evaluate dynamic expressions (~popup calculator) it is much easier to remember not to use double underscore prefixes in user expressions, than some other restrictions, like LL_...
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Sat Jan 12, 2008 5:33 am    Post subject: Reply with quote

I've made a few modifications/additions to pave the way for additional code generation functions.
I wrote:
__ParseExpressionArg( expr, pArg [, pScopeFunc ] )
    Replaces __MakeExpressionArg. Used by __expr, but provided as a separate function to facilitate generating dynamic code. Since all args for a given line must be contiguous in memory, the caller is responsible for allocating the ArgStruct 'pArg'. (The design of __MakeExpressionArg did not allow for this.)
__lineAlloc()
    Retrieves an empty Line structure for use in code generation functions, allocating memory as necessary.
__lineFree( pline )
    To avoid ListLines instability, clears the Line and marks it for re-use rather than actually deleting it.

Planned functions:
  • Execute a command dynamically. Probably as __exec, __cmd or __eval_cmd (__expr would become __eval_expr in this case.)
  • Execute a block of script dynamically. Probably as __execScript. Would it be worth having __expr and __exec once this is implemented?
  • Code generation functions - i.e. generate a simple command or function call, or complex script, for insertion into the script. This may form the backbone of __expr, __exec and __execScript.

I also discovered the \xXX regex escape sequence, so extended ANSI characters (\x80-\xFF) are now supported in variable names.
Back to top
View user's profile Send private message Visit poster's website
Laszlo



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

PostPosted: Sat Mar 15, 2008 9:48 pm    Post subject: Reply with quote

What is wrong with this script?
Code:
__init()
v = Msg("b,c")
u = Msg("b|c")

__expr(v)  ; no MsgBox (!)
__expr(u)  ; works OK

Msg(x) {
   Msgbox %x%
}
If a quoted string contains a comma, strange things happen.
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Sun Mar 16, 2008 12:40 am    Post subject: Reply with quote

Usually if there is an error, it will set ErrorLevel to descriptive error text. In this instance, it says "Too many parameters passed to function "Msg"." Function derefs need to know how many parameters are being passed. The code that determines this apparently does not check for quoted literal strings. Embarassed

I've updated both the release and test builds.
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 4 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