 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
no1readsthese
Joined: 08 Feb 2008 Posts: 31 Location: VA
|
Posted: Fri Mar 28, 2008 11:40 pm Post subject: AHK Stacks |
|
|
AHK Stacks by no1readsthese
Description:
Stacks or Last In First Out (LIFO) data structures based on strings with delimiter instead of arrays
mostly proof of concept
Usage:
Set And Change Delimiter:
| Code: | AHKStack_Delimiter := "Delimiter"
;Sets Delimiter For Future Stacks
;Default Delimiter Is "`n"
;Do Not Use After A Stack Has Been Created
AHKStack_ChangeDelimiter(Stack, NewDelimiter="")
;Changes Delimiter For Current And Future Stacks
;If No Delimiter Is Defined, "`n" Is Used |
IsEmpty:
| Code: | Var := AHKStack_IsEmpty(Stack)
;Returns 1 If Stack Is Empty
;Returns 0 If Stack Is Not Empty |
Size:
| Code: | Var := AHKStack_Size(Stack)
;Returns The Size Of The Stack To Var |
Push:
| Code: | AHKStack_Push(Stack, Element)
;Pushes The Element Into The Stack |
Pop:
| Code: | Var := AHKStack_Pop(Stack)
;Removes The Last Element From The Stack And
;Returns Said Element
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0 |
Poop (The Counterpart Of Pop. Thanks [VxE]):
| Code: | Var := AHKStack_Poop(Stack)
;Removes The First Element From The Stack And
;Returns Said Element
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0 |
Peek:
| Code: | Var := AHKStack_Peek(Stack, Index="")
;Returns The Element At The Index, Where The First Element Is At Index 1
;Returns The Last Element If No Index Is Defined
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0 |
Clear:
| Code: | AHKStack_Clear(Stack)
OR
Stack := ""
;Clears Stack Of All Elements |
Copy Stack:
| Code: | NewStack := AHKStack_Copy(Stack)
OR
NewStack := Stack
;Copies Stack To NewStack |
Script:
| Code: | ;=================================================
;== AHK Stacks by no1readsthese ==
;=================================================
/*
;=================================================
;=======================Use=======================
;=================================================
Set And Change Delimiter:
AHKStack_Delimiter := "Delimiter"
;Sets Delimiter For Future Stacks
;Default Delimiter Is "`n"
;Do Not Use After A Stack Has Been Created
AHKStack_ChangeDelimiter(Stack, NewDelimiter="")
;Changes Delimiter For Current And Future Stacks
;If No Delimiter Is Defined, "`n" Is Used
IsEmpty:
Var := AHKStack_IsEmpty(Stack)
;Returns 1 If Stack Is Empty
;Returns 0 If Stack Is Not Empty
Size:
Var := AHKStack_Size(Stack)
;Returns The Size Of The Stack To Var
Push:
AHKStack_Push(Stack, Element)
;Pushes The Element Into The Stack
Pop:
Var := AHKStack_Pop(Stack)
;Removes The Last Element From The Stack And
;Returns Said Element
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0
Poop (The Counterpart Of Pop. Thanks [VxE]):
Var := AHKStack_Poop(Stack)
;Removes The First Element From The Stack And
;Returns Said Element
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0
Peek:
Var := AHKStack_Peek(Stack, Index="")
;Returns The Element At The Index, Where The First Element Is At Index 1
;Returns The Last Element If No Index Is Defined
;If Stack Is Empty, The ERRORLEVEL Var Is Set To 1 And The Function Returns An Empty String
;ERRORLEVEL Is Otherwise Set To 0
Clear:
AHKStack_Clear(Stack)
OR
Stack := ""
;Clears Stack Of All Elements
Copy Stack:
NewStack := AHKStack_Copy(Stack)
OR
NewStack := Stack
;Copies Stack To NewStack
*/
;=================================================
;====================Functions====================
;=================================================
AHKStack_Delimiter := "`n"
AHKStack_ChangeDelimiter(ByRef Stack, NewDelimiter="")
{
Global AHKStack_Delimiter
If Not NewDelimiter
NewDelimiter := "`n"
StringReplace, Stack, Stack, %AHKStack_Delimiter%, %NewDelimiter%, All
AHKStack_Delimiter := NewDelimiter
Return Stack
}
AHKStack_IsEmpty(ByRef Stack)
{
If Stack
Return 0
Return 1
}
AHKStack_Size(ByRef Stack)
{
Global AHKStack_Delimiter
If Not Stack
Return 0
StringReplace, Stack, Stack, %AHKStack_Delimiter%, %AHKStack_Delimiter%, UseErrorLevel
Return ErrorLevel + 1
}
AHKStack_Push(ByRef Stack, Element)
{
Global AHKStack_Delimiter
StringReplace, Element, Element, %AHKStack_Delimiter%,, All
If Not Stack
Stack := Element
Else
Stack := Element AHKStack_Delimiter Stack
Return Stack
}
AHKStack_Pop(ByRef Stack)
{
Global AHKStack_Delimiter
EnvSet, ERRORLEVEL, 0
Position := InStr(Stack, AHKStack_Delimiter)
If Position
{
Element := SubStr(Stack, 1, Position-1)
Stack := SubStr(Stack, Position+1)
Return Element
}
If Stack
{
Element := Stack
Stack := ""
Return Element
}
StringGetPos, Position, Position, SearchText ;Sets ERRORLEVEL To 1
}
AHKStack_Poop(ByRef Stack) ; Tweaked by [VxE]
{
Global AHKStack_Delimiter
EnvSet, ERRORLEVEL, 0
Position := InStr(Stack, AHKStack_Delimiter, 0, 0)
If Position
{
Element := SubStr(Stack, Position+1)
Stack := SubStr(Stack, 1, Position-1)
Return Element
}
If Stack
{
Element := Stack
Stack := ""
Return Element
}
StringGetPos, Position, Position, SearchText ;Sets ERRORLEVEL To 1
}
AHKStack_Peek(ByRef Stack, Index="")
{
Global AHKStack_Delimiter
EnvSet, ERRORLEVEL, 0
If Not Stack
{
StringGetPos, Var, Var, SearchText ;Sets ERRORLEVEL To 1
Return
}
StringSplit, StackArray, Stack, %AHKStack_Delimiter%
If Not Index
Return StackArray1
Index := StackArray0 - Index - 1
Return StackArray%Index%
}
AHKStack_Clear(ByRef Stack)
{
Stack := ""
Return Stack
}
AHKStack_Copy(ByRef Stack)
{
Return Stack
} |
Last edited by no1readsthese on Sat Mar 29, 2008 4:49 am; edited 5 times in total |
|
| Back to top |
|
 |
HuBa
Joined: 24 Feb 2007 Posts: 175 Location: Budapest, Hungary
|
Posted: Sat Mar 29, 2008 1:22 am Post subject: |
|
|
| Nice, but what is the -9999? |
|
| Back to top |
|
 |
no1readsthese
Joined: 08 Feb 2008 Posts: 31 Location: VA
|
Posted: Sat Mar 29, 2008 1:35 am Post subject: |
|
|
-9999 is the stack-underflow error message
i would have liked something like -1 but if someone wanted to push -1 into the stack, there would have been a problem
so i chose -9999 since it would not likely be all that common
EDIT: the stack underflow error is now handled by setting the var ERRORLEVEL equal to 1 and returning an empty string
I hope that is clearer |
|
| Back to top |
|
 |
[VxE]
Joined: 07 Oct 2006 Posts: 3254 Location: Simi Valley, CA
|
Posted: Sat Mar 29, 2008 3:11 am Post subject: |
|
|
Very nice *applause*.
Sometimes, I think that AHK spoils me by not having structs to deal with. Seeing Ye Olde Tyme Stack really brings back memories.
You may want to think about adding the Poop (the counterpart of pop) function: | Code: | AHKStack_Poop(ByRef Stack) ; Tweaked by [VxE]
{
Global AHKStack_Delimiter
Global ERRORLEVEL := 0
Position := InStr(Stack, AHKStack_Delimiter, 0, 0)
If Position
{
Element := SubStr(Stack, Position+1)
Stack := SubStr(Stack, 1, Position-1)
Return Element
}
If Stack
{
Element := Stack
Stack := ""
Return Element
}
ERRORLEVEL := 1
} |
Although the line Global ERRORLEVEL := 0 gives me an error ( I think it needs to be set by EnvSet, or something)[/code] _________________ Ternary (a ? b : c) guide TSV Table Manipulation Library
Post code inside [code][/code] tags! |
|
| Back to top |
|
 |
no1readsthese
Joined: 08 Feb 2008 Posts: 31 Location: VA
|
Posted: Sat Mar 29, 2008 4:32 am Post subject: |
|
|
| [VxE] wrote: | | You may want to think about adding the Poop (the counterpart of pop) function |
I've never heard of 'poop' with stacks but oh well
Added it anyways. Thanks
| [VxE] wrote: | Although the line Global ERRORLEVEL := 0 gives me an error ( I think it needs to be set by EnvSet, or something)[/code] |
Sorry about that. I didn't think of checking it since it would have worked for any other var.
I fixed it by adding lines that are guaranteed to indirectly change ERRORLEVEL to the desired values |
|
| Back to top |
|
 |
widow Guest
|
Posted: Sat Mar 29, 2008 12:53 pm Post subject: |
|
|
| why not use machine code for this? |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4710 Location: Boulder, CO
|
Posted: Sat Mar 29, 2008 3:09 pm Post subject: |
|
|
| These stacks are close to lists, which can be handled by the three years old List manipulation functions, too. Nice to have an alternative. |
|
| Back to top |
|
 |
Mr_and_Mrs_D
Joined: 19 Dec 2006 Posts: 164
|
Posted: Sun May 03, 2009 4:33 pm Post subject: |
|
|
1. I also read these (and I use them in a soon to be released script)
2. BUGGY in Peek :
I think this | Code: | | Index := StackArray0 - Index - 1 |
should be replaced by this : | Code: | | Index := StackArray0 - Index + 1 |
EDIT : or maybe index should be left alone ? Cause the way it is index = 1 would give me the first element that was inserted. Is this what you want ??? _________________ XP SP3 Pro x32 / 7 x64 Pro - AHK 1.0.48.05
Last edited by Mr_and_Mrs_D on Fri Jan 29, 2010 3:11 pm; edited 1 time in total |
|
| Back to top |
|
 |
tinku99
Joined: 03 Aug 2007 Posts: 513 Location: Houston, TX
|
Posted: Wed May 27, 2009 9:23 pm Post subject: another stack implementation |
|
|
With this implementation you don't have to worry about the delimiter showing up in the objects you want to stack.
| Code: | msgbox % stack("push", 4)
msgbox % stack("push", 5)
msgbox % stack("peek")
msgbox % stack("pop")
msgbox % stack("peek")
msgbox % stack("empty")
msgbox % stack("pop")
msgbox % stack("empty")
return
stack(command, value = 0)
{
static
if !pointer
pointer = 10000
if (command = "push")
{
_p%pointer% := value
pointer -= 1
return value
}
if (command = "pop")
{
pointer += 1
return _p%pointer%
}
if (command = "peek")
{
next := pointer + 1
return _p%next%
}
if (command = "empty")
{
if (pointer == 10000)
return "empty"
else
return 0
}
}
|
|
|
| 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
|