This repository has been archived by the owner on Sep 26, 2021. It is now read-only.
/
dni.fs
158 lines (116 loc) · 3.7 KB
/
dni.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
\ ==============================================================================
\
\ dni - the generic double linked list iterator in the ffl
\
\ Copyright (C) 2007 Dick van Oudheusden
\
\ This library is free software; you can redistribute it and/or
\ modify it under the terms of the GNU Lesser General Public
\ License as published by the Free Software Foundation; either
\ version 3 of the License, or (at your option) any later version.
\
\ This library is distributed in the hope that it will be useful,
\ but WITHOUT ANY WARRANTY; without even the implied warranty of
\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\ Lesser General Public License for more details.
\
\ You should have received a copy of the GNU Lesser General Public
\ License along with this library; if not, write to the Free
\ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\
\ ==============================================================================
\
\ $Date: 2008-06-25 16:48:34 $ $Revision: 1.5 $
\
\ ==============================================================================
include ffl/config.fs
[UNDEFINED] dni.version [IF]
include ffl/stc.fs
include ffl/dnl.fs
include ffl/dnn.fs
( dni = Generic Double Linked List Iterator )
( The dni module implements an iterator on the generic double linked list [dnl]. )
1 constant dni.version
( Iterator structure )
begin-structure dni% ( -- n = Get the required space for a dni variable )
field: dni>dnl
field: dni>walk
end-structure
( Iterator creation, initialisation and destruction )
: dni-init ( dnl dni -- = Initialise the iterator with a dnl list )
tuck dni>dnl !
dni>walk nil!
;
: dni-create ( dnl "<spaces>name" -- ; -- dni = Create a named iterator in the dictionary with a dnl list )
create
here dni% allot dni-init
;
: dni-new ( dnl -- dni = Create an iterator on the heap )
dni% allocate throw tuck dni-init
;
: dni-free ( dni -- = Free the iterator from the heap )
free throw
;
( Member words )
: dni-get ( dni -- dnn | nil = Get the current node )
dni>walk @
;
( Iterator words )
: dni-first ( dni -- dnn | nil = Move the iterator to the first node, return this node )
dup dni>dnl @
dnl-first@
dup rot dni>walk ! \ walk = dnl.first
;
: dni-next ( dni -- dnn | nil = Move the iterator to the next node, return this node )
dni>walk
dup @
dup nil<> IF \ if walk <> nil then
dnn-next@ \ walk = walk.next
dup rot !
ELSE \ else
exp-invalid-state throw \ exception
THEN
;
: dni-prev ( dni -- dnn | nil = Move the iterator to the previous node, return this node )
dni>walk
dup @
dup nil<> IF \ if walk <> nil then
dnn-prev@ \ walk = walk.prev
dup rot !
ELSE \ else
exp-invalid-state throw \ exception
THEN
;
: dni-last ( dni -- dnn | nil = Move the iterator to the last node, return this node )
dup dni>dnl @
dnl-last@
dup rot dni>walk ! \ walk = dnl.last
;
: dni-first? ( dni -- flag = Check if the iterator is on the first node )
dup dni>dnl @
dnl-first@
dup nil= IF
2drop
false
ELSE
swap dni-get =
THEN
;
: dni-last? ( dni -- flag = Check if the iterator is on the last node )
dup dni>dnl @
dnl-last@
dup nil= IF
2drop
false
ELSE
swap dni-get =
THEN
;
( Inspection )
: dni-dump ( dni -- = Dump the iterator variable )
." dni:" dup . cr
." dnl :" dup dni>dnl ? cr
." walk:" dni>walk ? cr
;
[THEN]
\ ==============================================================================