PDA

View Full Version : idea for stack-variables



ReneMiner
16-11-2014, 16:28
stack-variables could be very useful if they were built-in. of course one could use an array, but it has to be dynamic then, so for the meantime a stack on some udt-element would be difficult to realize, except one uses some dynamic string or heap memory.

This example uses dynamic String, the only thing that i don't like about it that one has to pass a VarPtr on Stack.PushData() - but i could not find any other dynamic solution without having to pass something like MKx$() nor Memory_Get to be able to Push any type of data onto a stack.



Uses "console"


Type Stack
sData As String
sType As String
lSize As Long

As_Type As Function

PushData As Function
PopData As Function
GetData As Function

End Type
' ---------------------------------------
Function Stack.As_Type(ByVal sType As String) As String

Me.sType = Ucase$(sType) ' save type-names uniform, might be faster to compare

Local data Like sType At 0 ' determine element-size
Me.lSize = SizeOf(data)

Function = Me.sType

End Function

' ---------------------------------------

Function Stack.PushData(ByVal pData As DWord) As Long
' "ByRef data" without any Type sadly not working here

If Me.lSize = 0 Then Exit Function

Me.sData += Memory_Get(pData, Me.lSize)

' returns number of elements stored on stack now

Function = StrPtrLen(StrPtr(Me.sData))/Me.lSize

End Function
' ---------------------------------------

Function Stack.PopData() As Long
' returns number of elements left on stack


If Not Me.lSize Then Return 0
If StrPtrLen(StrPtr(Me.sData)) < Me.lSize Then Return 0

If StrPtrLen(StrPtr(Me.sData)) = Me.lSize Then
Me.sData = ""
Else
Me.sData = LEFT$(Me.sData, StrPtrLen(StrPtr(Me.sData)) - Me.lSize )
EndIf

Function = StrPtrLen(StrPtr(Me.sData))/Me.lSize

End Function
' ---------------------------------------

Function Stack.GetData() As String

If Not Me.lSize Then Exit Function
If StrPtrLen(StrPtr(Me.sData)) < Me.lSize Then Exit Function

Local data Like Me.sType At StrPtr(Me.sData) + StrPtrLen(StrPtr(Me.sData)) - Me.lSize
Function = data

End Function
' ---------------------------------------------------------------------


Dim foo As Stack
Dim i Like foo.As_Type "Long"

For i = 1 To 50 Step 7
foo.PushData(VarPtr i) ' ... still not satisfied because have to pass pointer...
' neither can be an expression here
Next

Do
PrintL foo.GetData
Loop While foo.PopData

PrintL

Dim bac As Stack
Dim d Like bac.As_Type "Double"

For d = 0.25 To 2.0 Step 0.25
bac.PushData(VarPtr d) ' but at least it allows any type this way
Next

Do
PrintL bac.GetData
Loop While bac.PopData

WaitKey


in the end i would like to type in just as simple as this:



Stack foo As Long | Dim foo As Long Stack

Push foo 12345
PrintL foo
Pop foo

'...or like a module:

Dim bac As Long = Stack_Create [As |( ] Double | "Double" [)]
Stack_Push( bac, 123.45 )
Do
PrintL Stack_Get( bac )
Loop While Stack_Pop( bac )

bac = Stack_Destroy( bac ) ' <<< assigns 0