 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Wed Dec 19, 2007 9:43 am Post subject: |
|
|
Nice.
I wait for dynamic code insertion
Btw, do you (still) plan to let us iterate global/local variables ?
I needed that bunch of times.
Thx. _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Wed Dec 19, 2007 12:08 pm Post subject: |
|
|
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 |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Wed Dec 19, 2007 1:02 pm Post subject: |
|
|
| 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 |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Wed Dec 19, 2007 3:11 pm Post subject: |
|
|
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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Wed Dec 19, 2007 11:38 pm Post subject: |
|
|
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 |
|
 |
freakkk
Joined: 29 Jul 2005 Posts: 179
|
Posted: Fri Jan 04, 2008 7:08 pm Post subject: |
|
|
Thanks for this new set of toys. Very, very useful indeed!
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
Is this limitation here to stay.. or this issue one that will most likely go away as your module matures
Thanks in advance.. _________________ .o0[ corey ]0o. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Sat Jan 05, 2008 1:19 am Post subject: |
|
|
| 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. (__expr might always have the limitation, though.) |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Tue Jan 08, 2008 4:55 am Post subject: |
|
|
| 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 |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 7171
|
Posted: Tue Jan 08, 2008 7:12 am Post subject: |
|
|
My vote: I like __underscores  |
|
| Back to top |
|
 |
Joy2DWorld
Joined: 04 Dec 2006 Posts: 537 Location: Galil, Israel
|
Posted: Tue Jan 08, 2008 2:31 pm Post subject: |
|
|
@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 |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Tue Jan 08, 2008 2:58 pm Post subject: |
|
|
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 |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4502 Location: Boulder, CO
|
Posted: Tue Jan 08, 2008 3:06 pm Post subject: |
|
|
| 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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Sat Jan 12, 2008 5:33 am Post subject: |
|
|
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 |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4502 Location: Boulder, CO
|
Posted: Sat Mar 15, 2008 9:48 pm Post subject: |
|
|
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 |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4457 Location: Qld, Australia
|
Posted: Sun Mar 16, 2008 12:40 am Post subject: |
|
|
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.
I've updated both the release and test builds. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|