PIPS
newgen_list.h
Go to the documentation of this file.
1 /*
2 
3  $Id: newgen_list.h 1386 2018-10-24 09:18:26Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of NewGen.
8 
9  NewGen is free software: you can redistribute it and/or modify it under the
10  terms of the GNU General Public License as published by the Free Software
11  Foundation, either version 3 of the License, or any later version.
12 
13  NewGen is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16  License for more details.
17 
18  You should have received a copy of the GNU General Public License along with
19  NewGen. If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 /*
23  These are the functions defined in the Newgen list library.
24 */
25 
26 #ifndef newgen_list_included
27 #define newgen_list_included
28 
29 #include "newgen_types.h"
30 
31 /** @addtogroup newgen_list */
32 
33 /** @{ */
34 
35 /** The structure used to build lists in NewGen
36 
37  cons is a list element, list is a pointer to these elements
38 
39  The names are quite related to their Lisp equivalents.
40 */
41 typedef struct cons {
42  gen_chunk car; /**< The data payload of a list element */
43  struct cons *cdr ; /**< The pointer to the next element. It is NIL if none */
44 } cons;
45 
46 /** The empty list (nil in Lisp) */
47 #define NIL ((list)NULL)
48 
49 /** Modify a list pointer to point on the next element of the list
50 
51  If a list is considered as a stack and elements are pushed by
52  insertion at the list head, popping an element from the stack can be
53  seen as skipping the first one.
54 
55  Not that the list elements by themself are not modified.
56 
57  @param l the list to pop
58 */
59 #define POP(l) ((l)=(l)->cdr)
60 
61 /** Test if a list is empty
62 
63  @param l the list to test
64  @return true if the list is the empty list, false else
65 */
66 #define ENDP(l) ((l)==NIL)
67 
68 /** Undefined list definition :-) */
69 #define list_undefined ((cons *)-3)
70 
71 /** Return if a list is undefined
72 
73  Note it is different than testing for an empty list.
74  */
75 #define list_undefined_p(c) ((c)==list_undefined)
76 
77 /** Get the value of the first element of a list
78 
79  If CAR is applied on an empty list, a segmentation violation will
80  occur.
81 
82  It is called CAR in the Lisp tradition, dating back to some register
83  names in an old IBM computer where it was implemented.
84 
85  @paral pcons is the list
86 
87  @return the value of the first element of the list. Since it is
88  gen_chunk NewGen generic container, it is good behaviour to use
89  through a NewGen accessor, such as STATEMENT(CAR(l)) to the
90  first PIPS statement of a list of statements
91 */
92 #define CAR(pcons) ((pcons)->car)
93 
94 /** Get the list less its first element
95 
96  Note that the list by itself is not modified, only a pointer to the
97  second element is returned. So this pointer represent the original
98  list less the firs element.
99 
100  If CDR is applied on an empty list, a segmentation violation will
101  occur.
102 
103  It is called CDR in the Lisp tradition, dating back to some register
104  names in an old IBM computer where it was implemented.
105 
106  @paral pcons is the list
107 
108  @return a pointer to the second element of the list. list following
109  value of the first element of the list
110 */
111 #define CDR(pcons) ((pcons)->cdr)
112 
113 /** Get the adress of the first element of a list
114 
115  @paral pcons is the list
116 
117  @return a pointer to the value of the first element of the list
118 */
119 #define REFCAR(pc) (&(CAR(pc).p))
120 
121 /** List element cell constructor (insert an element at the beginning of a
122  list)
123 
124  Mimmic the cons function in Lisp: construct a list element cell and
125  link it to a list. So the element is the first element of a new list
126  that goes on with the old one.
127 
128  @param _t_ is the type of the list element cell to construct
129 
130  @param _i_ is the element to put in the list element cell
131 
132  @param _l_ is the list to linked the element cell with a the beginning
133 
134  @return the new list with the new element cell at the beginning
135 
136  For example, to insert a PIPS statement s at the beginning of a
137  statement list sl you can write:
138 
139  list new_list = CONS(statement, s, sl);
140 
141  Another way is to directly use the specialized NewGen list constructor
142  for the type:
143 
144  list new_list = gen_statement_cons(s, sl);
145 
146  Note that it also works with just the type name in upper case, as:
147 
148  list l = CONS(STATEMENT, s, l);
149 */
150 #define CONS(_t_,_i_,_l_) gen_##_t_##_cons((_i_),(_l_))
151 
152 /** @} */
153 
154 /** @addtogroup newgen_list */
155 
156 /** @{ */
157 
158 /** Apply/map an instruction block on all the elements of a list
159 
160  FOREACH(T, v, l) {
161  instructions;
162  }
163  iterates on all the elements of the list l of elements of type T by
164  allocating a local element index variable v of type T. Instructions
165  access the list element through variable v.
166 
167  FOREACH is similar to MAP but is more gdb/emacs/vim... friendly since
168  it remains line oriented like the C99 for() used to implement it and
169  does not choke on some "," in the instruction block.
170 
171  @param _fe_CASTER is the type of elements, aka the newgen type
172  name or newgen basic types such as int, string, list.
173 
174  @param _fe_item is the variable to allocate and use as an iterator on
175  the list elements
176 
177  @param _fe_list is the list parameter to iterate on
178 */
179 #define FOREACH(_fe_CASTER, _fe_item, _fe_list) \
180  list NGMID(l) = (_fe_list); \
181  for( _fe_CASTER##_TYPE _fe_item; \
182  !ENDP(NGMID(l)) && \
183  (_fe_item= _fe_CASTER##_CAST(CAR(NGMID(l)) )); \
184  POP(NGMID(l)))
185 
186 #define VOLATILE_FOREACH(_fe_CASTER, _fe_item, _fe_list) \
187  volatile list NGMID(l) = (_fe_list); \
188  for( volatile _fe_CASTER##_TYPE _fe_item; \
189  !ENDP(NGMID(l)) && \
190  (_fe_item= _fe_CASTER##_CAST(CAR(NGMID(l)) )); \
191  POP(NGMID(l)))
192 
193 /** Apply some code on the addresses of all the elements of a list
194 
195  @param _map_list_cp is the variable that will iterate on the adresses
196  of all the list elements to be accessed in _code
197 
198  @param _code is the statement (block) applied on each element address
199  in the variable _map_list_cp
200 
201  @param _l is the list parameter to iterate on
202 */
203 #define MAPL(_map_list_cp,_code,_l) \
204  { \
205  list _map_list_cp = (_l) ; \
206  for(; !ENDP(_map_list_cp); POP(_map_list_cp)) \
207  _code; \
208  }
209 
210 /** Apply/map an instruction block on all the elements of a list (old
211  fashioned)
212 
213  Now you should use the more modern FOREACH implementation instead.
214 
215  @param _map_CASTER is the caster of the type of elements, that is the
216  newgen type name in uppercase, such as STATEMENT for a PIPS statement.
217 
218  @param _map_item is the variable to allocate and use as an iterator on
219  the list elements from _map_code
220 
221  @param _map_code is the statement (block) applied on each element in
222  the variable _map_item
223 
224  @param _map_list is the list parameter to iterate on
225 */
226 #define MAP(_map_CASTER, _map_item, _map_code, _map_list) \
227  { \
228  list _map_item##_list = (_map_list); \
229  _map_CASTER##_TYPE _map_item; \
230  for(; _map_item##_list; POP(_map_item##_list)) \
231  { \
232  _map_item = _map_CASTER(CAR(_map_item##_list)); \
233  _map_code; \
234  } \
235  }
236 
237 /** Another name to the funtion to insert a bool element at the start
238  of a list */
239 #define gen_BOOL_cons gen_bool_cons
240 
241 /** Another name to the funtion to insert an integer element at the start
242  of a list */
243 #define gen_INT_cons gen_int_cons
244 
245 /** Another name to the funtion to insert a list element at the start of a
246  list
247 
248  It is to build list of lists
249 */
250 #define gen_LIST_cons gen_list_cons
251 
252 /** Another name to the funtion to insert a list element at the start of a
253  list
254 
255  It is to build list of lists
256 */
257 #define gen_CONSP_cons gen_list_cons
258 
259 /** Another name to the funtion to insert a string element at the start of
260  a list */
261 #define gen_STRING_cons gen_string_cons
262 
263 /** @} */
264 
265 /* #define CONS(type,x,l) gen_cons((void*) (x), (l)) */
266 
267 // UNRELATED TO LISTS, and possibly in other files
268 extern void gen_copy(void *, void *);
269 extern bool gen_eq(const void *, const void *);
270 extern void *gen_identity(const void *);
271 extern void *gen_chunk_identity(gen_chunk);
272 extern void *gen_find_tabulated(const char*, int);
273 extern list gen_filter_tabulated(bool(*)(gen_chunk*), int);
274 extern void gen_free_area(void**, int);
275 extern void gen_mapc_tabulated(void (*)(gen_chunk*), int);
276 
277 // Functions in list.c
278 
279 // LIST OPERATION
280 extern list gen_append(list , const list);
281 extern list gen_concatenate(const list , const list);
282 extern list gen_copy_seq(const list);
283 extern list gen_nconc(list, list);
284 extern list gen_full_copy_list(const list);
285 extern list gen_make_list(int, ...);
286 extern list gen_nreverse(list);
287 
288 // EXTRACTIONS
289 extern void *gen_find(const void *, const list ,
291 extern void *gen_find_from_end
292  (const void *, const list, gen_filter2_func_t, gen_extract_func_t);
293 extern void *gen_find_eq(const void *, const list);
296 
297 // DESTRUCTORS
298 extern void gen_free_list(list);
299 extern void gen_full_free_list(list);
300 
301 extern list gen_last(const list);
302 extern void *gen_car(const list);
303 
304 // OBSERVERS
305 extern size_t gen_length(const list);
306 extern size_t list_own_allocated_memory(const list);
307 extern gen_chunk gen_nth(int, const list);
308 extern list gen_nthcdr(int, const list);
309 
310 // MAP
311 extern void gen_map(gen_iter_func_t, const list);
312 extern void gen_mapl(gen_iter_func_t, const list);
313 
314 extern void * gen_reduce(void *, void *(*)(void*, const list), const list);
315 
316 extern void gen_remove(list *, const void *);
317 extern void gen_remove_once(list *, const void *);
318 extern list gen_some(gen_filter_func_t, const list);
319 extern bool gen_replace_in_list(list, const void *, const void *);
320 extern void gen_exchange_in_list(list, const void *, const void *);
321 
322 extern list gen_insert_list(list, const void *, list, bool);
323 extern void gen_insert_after(const void *, const void *, list);
324 extern list gen_insert_before(const void *, const void *, list);
325 extern list gen_once(const void *, list);
326 extern bool gen_in_list_p(const void *, const list);
327 extern int gen_occurences(const void *, const list);
328 extern bool gen_once_p(const list);
329 extern bool gen_equals(const list, const list, gen_eq_func_t);
330 
331 // LIST MODIFIERS
332 extern void gen_sort_list(list, gen_cmp_func_t);
333 extern void gen_list_patch(list, const void *, const void *);
334 
336 extern void gen_closure(gen_closure_func_t, const list);
337 
338 extern list gen_copy_string_list(const list);
339 extern void gen_free_string_list(list);
340 void gen_fprint(FILE *, const string, const list, gen_string_func_t);
341 
342 // UTILS
343 extern list gen_cons(const void *, const list);
344 extern list gen_bool_cons(bool, const list);
345 extern list gen_int_cons(_int, const list);
346 extern list gen_string_cons(string, const list);
347 extern list gen_list_cons(const list, const list); // list of lists
348 extern list gen_typed_cons(_int, const void *, const list);
349 extern list gen_CHUNK_cons(const gen_chunk *, const list);
350 extern list gen_VOID_STAR_cons(const void *, const list);
351 
352 extern void gen_list_and(list *, const list);
353 extern void gen_list_and_not(list *, const list);
354 
355 extern int gen_position(const void *, const list);
356 
357 extern bool gen_list_cyclic_p (const list);
358 extern list gen_list_head(list *, int);
359 extern list gen_common_prefix(const list, const list);
360 
361 extern void gen_substitute_chunk_by_list(list * pl, const void * o, list sl);
362 
363 /* sweep a list...
364  */
370 
371 #define gen_sweep_forward_init(l, p1, p2) gen_sweep_init(l, gen_sweep_forward, p1, p2)
372 #define gen_sweep_backward_init(l, p1, p2) gen_sweep_init(l, gen_sweep_backward, p1, p2)
373 
374 #endif /* newgen_list_included */
void *() gen_extract_func_t(const gen_chunk)
Definition: genC.h:72
void * gen_chunk_identity(gen_chunk)
Definition: genClib.c:2812
void * gen_identity(const void *)
Just return the argument.
Definition: genClib.c:2807
list gen_make_list(int,...)
Definition: list.c:851
void gen_fprint(FILE *, const string, const list, gen_string_func_t)
Definition: list.c:873
list gen_insert_list(list, const void *, list, bool)
insert nl before or after item in list l, both initial lists are consumed
Definition: list.c:269
list gen_list_head(list *, int)
Definition: list.c:1015
list gen_nreverse(list)
reverse a list in place
Definition: list.c:304
void gen_exchange_in_list(list, const void *, const void *)
exchange items i1 & i2 in the list
Definition: list.c:651
void gen_remove(list *, const void *)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
void gen_list_and(list *, const list)
Compute A = A inter B: complexity in O(n2)
Definition: list.c:941
int gen_position(const void *, const list)
Element ranks are strictly positive as for first, second, and so on.
Definition: list.c:995
void gen_remove_once(list *, const void *)
Remove the first occurence of o in list pl:
Definition: list.c:691
list gen_concatenate(const list, const list)
concatenate two lists.
Definition: list.c:436
void gen_map(gen_iter_func_t, const list)
Definition: list.c:172
list gen_once(const void *, list)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
struct cons cons
The structure used to build lists in NewGen.
list gen_VOID_STAR_cons(const void *, const list)
Definition: list.c:934
list gen_copy_seq(const list)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list)
Definition: list.c:150
list gen_cons(const void *, const list)
Definition: list.c:888
list gen_common_prefix(const list, const list)
return the common list prefix of lists l1 and l2.
Definition: list.c:1033
void gen_list_and_not(list *, const list)
Compute A = A inter non B:
Definition: list.c:963
bool gen_once_p(const list)
FC: ARGH...O(n^2)!
Definition: list.c:758
void gen_free_string_list(list)
Definition: list.c:564
void gen_copy(void *, void *)
#define CONS(type,x,l) gen_cons((void*) (x), (l))
Definition: list.c:359
list gen_some(gen_filter_func_t, const list)
Definition: list.c:206
list gen_nconc(list, list)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
list gen_list_cons(const list, const list)
Definition: list.c:924
void gen_free_list(list)
free the spine of the list
Definition: list.c:327
list gen_last(const list)
Return the last element of a list.
Definition: list.c:578
list gen_CHUNK_cons(const gen_chunk *, const list)
Definition: list.c:929
bool gen_in_list_p(const void *, const list)
tell whether vo belongs to lx
Definition: list.c:734
size_t list_own_allocated_memory(const list)
Definition: list.c:158
void * gen_find_if_from_end(gen_filter_func_t, list, gen_extract_func_t)
the last match is returned
Definition: list.c:382
void * gen_find_if(gen_filter_func_t, const list, gen_extract_func_t)
Definition: list.c:370
void * gen_find_eq(const void *, const list)
Definition: list.c:422
list gen_nthcdr(int, const list)
caution: the first item is 0! was: return( (n<=0) ? l : gen_nthcdr( n-1, CDR( l ))) ; if n>gen_length...
Definition: list.c:700
void * gen_find(const void *, const list, gen_filter2_func_t, gen_extract_func_t)
Definition: list.c:398
list gen_append(list, const list)
Definition: list.c:471
bool gen_list_cyclic_p(const list)
Definition: list.c:120
list gen_copy_string_list(const list)
of string
Definition: list.c:556
void gen_mapl(gen_iter_func_t, const list)
MAP.
Definition: list.c:165
int gen_occurences(const void *, const list)
count occurences of vo in l
Definition: list.c:746
gen_chunk gen_nth(int, const list)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
void gen_list_patch(list, const void *, const void *)
Replace all the reference to x in list l by a reference to y:
Definition: list.c:985
list gen_string_cons(string, const list)
Definition: list.c:919
void gen_free_area(void **, int)
free an area.
Definition: list.c:775
void * gen_find_from_end(const void *, const list, gen_filter2_func_t, gen_extract_func_t)
Definition: list.c:408
list gen_full_copy_list(const list)
Copy a list structure with element copy.
Definition: list.c:535
void gen_sort_list(list, gen_cmp_func_t)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
void gen_substitute_chunk_by_list(list *pl, const void *o, list sl)
substitute item o by list sl in list *pl, which is modified as a side effect.
Definition: list.c:591
list gen_bool_cons(bool, const list)
typed cons for "basic" types
Definition: list.c:909
void * gen_car(const list)
Definition: list.c:364
void gen_insert_after(const void *, const void *, list)
Definition: list.c:223
bool gen_replace_in_list(list, const void *, const void *)
substitute all item s by t in list l
Definition: list.c:634
list gen_insert_before(const void *, const void *, list)
Definition: list.c:238
list gen_int_cons(_int, const list)
Definition: list.c:914
bool gen_equals(const list, const list, gen_eq_func_t)
compares two lists using the functor given in parameters returns true if for all n,...
Definition: list.c:192
bool gen_eq(const void *, const void *)
Definition: list.c:111
list gen_typed_cons(_int, const void *, const list)
CONS a list with minimal type checking this cannot be done within the CONS macro because possible fun...
Definition: list.c:900
list(* gen_closure_func_t)(gen_chunk *, list)
Definition: newgen_list.h:335
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
void * gen_reduce(void *, void *(*)(void *, const list), const list)
void gen_sweep_done(gen_sweep_state)
Definition: list.c:1166
void gen_closure(gen_closure_func_t, const list)
void gen_full_free_list(list)
Definition: genClib.c:1023
struct __gen_sweep_state * gen_sweep_state
Definition: newgen_list.h:366
gen_sweep_state gen_sweep_init(list, gen_sweep_direction, list *, list *)
initialize list l sweep in direction dir, with pointers for head & tail
Definition: list.c:1060
gen_sweep_direction
sweep a list...
Definition: newgen_list.h:365
@ gen_sweep_backward
Definition: newgen_list.h:365
@ gen_sweep_forward
Definition: newgen_list.h:365
void gen_mapc_tabulated(void(*)(gen_chunk *), int)
apply fp to domain...
Definition: tabulated.c:127
bool gen_sweep_update(gen_sweep_state)
Definition: list.c:1108
list gen_filter_tabulated(bool(*)(gen_chunk *), int)
returns the list of entities with this caracteristics.
Definition: tabulated.c:144
bool(* gen_filter2_func_t)(const void *, const void *)
Definition: newgen_types.h:110
string(* gen_string_func_t)(const void *)
Definition: newgen_types.h:111
void(* gen_iter_func_t)(void *)
Definition: newgen_types.h:116
intptr_t _int
_INT
Definition: newgen_types.h:53
struct cons * list
Definition: newgen_types.h:106
bool(* gen_filter_func_t)(const void *)
Definition: newgen_types.h:109
bool(* gen_eq_func_t)(const void *, const void *)
Definition: newgen_types.h:115
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
sweep status
Definition: list.c:1050
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
struct cons * cdr
The pointer to the next element.
Definition: newgen_list.h:43
gen_chunk car
The data payload of a list element.
Definition: newgen_list.h:42
A gen_chunk is used to store every object.
Definition: genC.h:58