Subversion Repositories Kolibri OS

Rev

Rev 9010 | Rev 9560 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
2
    Copyright 2021 Anton Krotov
3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE List;
21
 
22
TYPE
23
 
24
    tItem* = POINTER TO RECORD
25
        prev*, next*: tItem
26
    END;
27
 
28
    tList* = POINTER TO RECORD
29
        first*, last*: tItem;
30
        count*: INTEGER
31
    END;
32
 
33
    PmovInt = PROCEDURE (VAR v: INTEGER; x: INTEGER);
34
    PmovPtr = PROCEDURE (VAR v: tItem; x: tItem);
35
 
36
 
37
VAR
38
 
39
    _movInt: PmovInt;
40
    _movPtr: PmovPtr;
41
 
42
 
43
PROCEDURE create* (list: tList): tList;
44
BEGIN
45
    IF list = NIL THEN
46
        NEW(list)
47
    END;
48
    list.first := NIL;
49
    list.last  := NIL;
50
    list.count := 0
51
    RETURN list
52
END create;
53
 
54
 
55
PROCEDURE getItem* (list: tList; idx: INTEGER): tItem;
56
VAR
57
    item: tItem;
58
BEGIN
59
    IF idx < 0 THEN
60
        item := NIL
61
    ELSE
62
        item := list.first;
63
        WHILE (idx > 0) & (item # NIL) DO
64
            item := item.next;
65
            DEC(idx)
66
        END
67
    END
68
    RETURN item
69
END getItem;
70
 
71
 
72
PROCEDURE delete* (list: tList; item: tItem);
73
VAR
74
    prev, next: tItem;
75
BEGIN
76
    prev := item.prev;
77
    next := item.next;
78
    IF prev # NIL THEN
79
        prev.next := next;
80
        IF next # NIL THEN
81
            next.prev := prev
82
        ELSE
83
            list.last := prev
84
        END
85
    ELSE
86
        list.first := next;
87
        IF next # NIL THEN
88
           next.prev := NIL
89
        ELSE
90
           list.last := NIL
91
        END
92
    END;
93
    DEC(list.count)
94
END delete;
95
 
96
 
97
PROCEDURE movInt (VAR v: INTEGER; x: INTEGER);
98
BEGIN
99
    _movInt(v, x);
100
    v := x
101
END movInt;
102
 
103
 
104
PROCEDURE movPtr (VAR v: tItem; x: tItem);
105
BEGIN
106
    _movPtr(v, x);
107
    v := x
108
END movPtr;
109
 
110
 
111
PROCEDURE _delete* (list: tList; item: tItem);
112
VAR
113
    prev, next: tItem;
114
BEGIN
115
    prev := item.prev;
116
    next := item.next;
117
    IF prev # NIL THEN
118
        movPtr(prev.next, next);
119
        IF next # NIL THEN
120
            movPtr(next.prev, prev)
121
        ELSE
122
            movPtr(list.last, prev)
123
        END
124
    ELSE
125
        movPtr(list.first, next);
126
        IF next # NIL THEN
127
           movPtr(next.prev, NIL)
128
        ELSE
129
           movPtr(list.last, NIL)
130
        END
131
    END;
132
    movInt(list.count, list.count - 1)
133
END _delete;
134
 
135
 
136
PROCEDURE _append* (list: tList; item: tItem);
137
BEGIN
138
    movPtr(item.prev, list.last);
139
    IF list.last # NIL THEN
140
        movPtr(list.last.next, item)
141
    ELSE
142
        movPtr(list.first, item)
143
    END;
144
    movPtr(list.last, item);
145
    movPtr(item.next, NIL);
146
    movInt(list.count, list.count + 1)
147
END _append;
148
 
149
 
150
PROCEDURE _insert* (list: tList; item, newItem: tItem);
151
VAR
152
    next: tItem;
153
BEGIN
154
    next := item.next;
155
    IF next # NIL THEN
156
        movPtr(next.prev, newItem);
157
        movPtr(newItem.next, next);
158
        movPtr(item.next, newItem);
159
        movPtr(newItem.prev, item);
160
        movInt(list.count, list.count + 1)
161
    ELSE
162
        _append(list, newItem)
163
    END
164
END _insert;
165
 
166
 
9010 leency 167
PROCEDURE _exchange* (list: tList; a, b: tItem);
168
VAR
169
    a0, b0: tItem;
170
BEGIN
171
    IF (a # NIL) & (b # NIL) THEN
172
        ASSERT((a.next = b) & (b.prev = a));
173
        a0 := a.prev;
174
        b0 := b.next;
175
        movPtr(b.prev, a0);
176
        movPtr(a.next, b0);
177
        movPtr(b.next, a);
178
        movPtr(a.prev, b);
9050 leency 179
        IF a0 # NIL THEN
180
            IF b0 # NIL THEN
181
                movPtr(a0.next, b);
182
                movPtr(b0.prev, a);
183
            ELSE
184
                movPtr(a0.next, b);
185
                movPtr(list.last, a)
186
            END
187
        ELSE
188
            IF b0 # NIL THEN
189
                movPtr(b0.prev, a);
190
                movPtr(list.first, b)
191
            ELSE
192
                movPtr(list.first, b);
193
                movPtr(list.last, a)
194
            END
9010 leency 195
        END
196
    END
197
END _exchange;
198
 
199
 
8728 leency 200
PROCEDURE append* (list: tList; item: tItem);
201
BEGIN
202
    item.prev := list.last;
203
    IF list.last # NIL THEN
204
        list.last.next := item
205
    ELSE
206
        list.first := item
207
    END;
208
    list.last := item;
209
    item.next := NIL;
210
    INC(list.count)
211
END append;
212
 
213
 
214
PROCEDURE insert* (list: tList; item, newItem: tItem);
215
VAR
216
    next: tItem;
217
BEGIN
218
    next := item.next;
219
    IF next # NIL THEN
220
        next.prev := newItem;
221
        newItem.next := next;
222
        item.next := newItem;
223
        newItem.prev := item;
224
        INC(list.count)
225
    ELSE
226
        append(list, newItem)
227
    END
228
END insert;
229
 
230
 
231
PROCEDURE pop* (list: tList): tItem;
232
VAR
233
    res: tItem;
234
BEGIN
235
    IF list.count # 0 THEN
236
        res := list.last;
237
        list.last := res.prev;
238
        DEC(list.count);
239
        IF list.count # 0 THEN
240
            list.last.next := NIL
241
        ELSE
242
            list.first := NIL
243
        END;
244
        res.prev := NIL;
245
        res.next := NIL
246
    ELSE
247
        res := NIL
248
    END
249
    RETURN res
250
END pop;
251
 
252
 
253
PROCEDURE init* (movInt: PmovInt; movPtr: PmovPtr);
254
BEGIN
255
    _movInt := movInt;
256
    _movPtr := movPtr
257
END init;
258
 
259
 
260
END List.