FreeBASIC  0.91.0
stack.bas
Go to the documentation of this file.
1 '' generic stack
2 ''
3 '' chng: jan/2005 written [v1ctor]
4 ''
5 
6 #include once "stack.bi"
7 
8 declare function hAllocTB ( _
9  byval stk as TSTACK ptr, _
10  byval nodes as integer _
11  ) as integer
12 
13 '':::::
14 function stackNew _
15  ( _
16  byval stk as TSTACK ptr, _
17  byval nodes as integer, _
18  byval nodelen as integer, _
19  byval doclear as integer _
20  ) as integer
21 
22  '' fill ctrl struct
23  stk->tbhead = NULL
24  stk->tbtail = NULL
25  stk->nodes = 0
26  stk->nodelen = nodelen + len( TSTACKNODE )
27  stk->tos = NULL
28  stk->clear = doclear
29 
30  '' allocate the initial pool
31  function = hAllocTB( stk, nodes )
32 
33 end function
34 
35 '':::::
36 function stackFree _
37  ( _
38  byval stk as TSTACK ptr _
39  ) as integer
40 
41  dim as TSTACKTB ptr tb, nxt
42 
43  '' for each pool, free the mem block and the pool ctrl struct
44  tb = stk->tbhead
45  do while( tb <> NULL )
46  nxt = tb->next
47  deallocate( tb->nodetb )
48  deallocate( tb )
49  tb = nxt
50  loop
51 
52  stk->tbhead = NULL
53  stk->tbtail = NULL
54  stk->nodes = 0
55 
56  function = TRUE
57 
58 end function
59 
60 '':::::
61 function hAllocTB _
62  ( _
63  byval stk as TSTACK ptr, _
64  byval nodes as integer _
65  ) as integer static
66 
67  dim as TSTACKNODE ptr nodetb, node, prev
68  dim as TSTACKTB ptr tb
69  dim as integer i
70 
71  function = FALSE
72 
73  if( nodes <= 1 ) then
74  exit function
75  end if
76 
77  '' allocate the pool
78  if( stk->clear ) then
79  nodetb = xcallocate( nodes * stk->nodelen )
80  else
81  nodetb = xallocate( nodes * stk->nodelen )
82  end if
83 
84  '' and the pool ctrl struct
85  tb = xallocate( len( TSTACKTB ) )
86 
87  '' add the ctrl struct to pool list
88  if( stk->tbhead = NULL ) then
89  stk->tbhead = tb
90  end if
91  if( stk->tbtail <> NULL ) then
92  stk->tbtail->next = tb
93  end if
94  stk->tbtail = tb
95 
96  tb->next = NULL
97  tb->nodetb = nodetb
98  tb->nodes = nodes
99 
100  '' relink
101  stk->nodes += nodes
102 
103  prev = stk->tos
104  node = nodetb
105  if( prev <> NULL ) then
106  prev->next = node
107  end if
108 
109  for i = 1 to nodes-1
110  node->prev = prev
111  node->next = cast( TSTACKNODE ptr, cast( byte ptr, node ) + stk->nodelen)
112  prev = node
113  node = node->next
114  next
115 
116  node->prev = prev
117  node->next = NULL
118 
119  ''
120  function = TRUE
121 
122 end function
123 
124 '':::::
125 function stackPush _
126  ( _
127  byval stk as TSTACK ptr _
128  ) as any ptr static
129 
130  '' move up
131  if( stk->tos = NULL ) then
132  stk->tos = stk->tbhead->nodetb
133  else
134  '' alloc new node if there are no free nodes
135  if( stk->tos->next = NULL ) Then
136  hAllocTB( stk, cunsg(stk->nodes) \ 4 )
137  end if
138 
139  stk->tos = stk->tos->next
140  end if
141 
142  function = cast( byte ptr, stk->tos ) + len( TSTACKNODE )
143 
144 end function
145 
146 '':::::
147 sub stackPop _
148  ( _
149  byval stk as TSTACK ptr _
150  ) static
151 
152  '' node can contain strings descriptors, so, erase it..
153  if( stk->clear ) then
154  clear( byval cast(TSTACKNODE ptr, stk->tos) + 1, 0, stk->nodelen - len( TSTACKNODE ) )
155  end if
156 
157  '' move down
158  stk->tos = stk->tos->prev
159 
160 end sub
161 
162 '':::::
163 function stackGetTOS _
164  ( _
165  byval stk as TSTACK ptr _
166  ) as any ptr
167 
168  if( stk->tos = NULL ) then
169  return NULL
170  else
171  return cast( byte ptr, stk->tos ) + len( TSTACKNODE )
172  end if
173 
174 end function
175 
176