Dynamic LinkedList / Array of LinkedList
Posted: Wed Nov 01, 2006 11:37 am
Edit: If you use Windows 9.x you must manually free all the lists before you end the program. Also the free list procedure isn't very tested so I hope it works...
This code allows you to create native PB linked lists on-the-fly. You can put them into arrays, sort them and juggle them around as you see fit.
Each function that deals with the dynamic lists requires the type of the list as a postfix to the function name, so to bind a list name to a dynamic list of strings, the function used is BindListS(ListName(), List). To create a new list of strings, use List.q = DynamicNewListS().
To create functions for a type use UseListType(Type). All this becomes clear as you see the example.
The code that you need to include or put on top of your file:
Example of an array of linked lists of strings. It assumes that the code above is included.
This code allows you to create native PB linked lists on-the-fly. You can put them into arrays, sort them and juggle them around as you see fit.
Each function that deals with the dynamic lists requires the type of the list as a postfix to the function name, so to bind a list name to a dynamic list of strings, the function used is BindListS(ListName(), List). To create a new list of strings, use List.q = DynamicNewListS().
To create functions for a type use UseListType(Type). All this becomes clear as you see the example.
The code that you need to include or put on top of your file:
Code: Select all
Macro GlobalNewDynamicListPointer(Name, Type)
If 0
Global NewList Name.Type()
EndIf
EndMacro
Macro NewDynamicListPointer(Name, Type)
If 0
NewList Name.Type()
EndIf
EndMacro
Macro BindListTemplate(Type)
Procedure BindList#Type(List.Type(), ID.q)
!mov eax, [p.v_ID]
!mov edx, [p.v_ID+4]
!mov ecx, [p.v_ID-4]
!mov [ecx], eax
!add ecx, 4
!mov [ecx], edx
EndProcedure
EndMacro
Macro DynamicNewListTemplate(Type)
Procedure.q DynamicNewList#Type()
Protected NewList Local.Type()
!mov eax, [esp]
!mov edx, [esp+4]
!add esp, 8
!ret
EndProcedure
EndMacro
Macro FreeListTemplate(Type)
Procedure FreeList#Type(ID.q)
If 0
NewList Dummy.Type()
EndIf
BindList#Type(Dummy(), ID.q)
EndProcedure
EndMacro
Macro UseListType(Type)
BindListTemplate(Type)
DynamicNewListTemplate(Type)
FreeListTemplate(Type)
EndMacro
Code: Select all
UseListType(S) ; Generate functions with postfix S for string type
; UseListType(L) ; Generate functions with postfix L for long type
#ArrayLen = 10
; Allocate array
Dim ListArray.q(#ArrayLen) ; Notice that ListArray is of type .q. It can
; store lists of any type.
; Create a dummy list ("list name") to represent the dynamic lists
; Global means that NAME is global. The dynamic LISTS you create are
; always global. Later you use a dynamically created list by binding the
; name to a list. So you don't have to create 1000 names to work with
; 1000 dynamic lists.
GlobalNewDynamicListPointer(Dummy, s) ; Notice that names are typed.
; Fill array with LinkedLists
For I = 0 To #ArrayLen
ListArray(I) = DynamicNewListS()
Next
; Fill those LinkedLists with some gibberish
For I = 0 To #ArrayLen
BindListS(Dummy(), ListArray(I))
For J = 0 To I
AddElement(Dummy())
Dummy() = Str(J) + "_"
Next
Next
BindListS(Dummy(), ListArray(9))
SortList(Dummy(), 1)
; Print each LinkedList. Notice that ForEach can be used
; for the individual lists, but obviously not for the
; array
For I = 0 To #ArrayLen
Debug "------------ " + Str(I) + " ------------"
BindListS(Dummy(), ListArray(I))
ForEach Dummy()
Debug Dummy()
Next
Next