NAPA Compiler V4.50
Author: Yves Leduc, yves.leduc.be@gmail.com
Loading...
Searching...
No Matches
C:/Simulate/Napados/Source/sv.c
Go to the documentation of this file.
1/* ** SORT RECORDS, UPDATES and VARIABLES *************************************************************************************** */
2
3#undef EXTERN
4#define EXTERN extern
5
6#include "./napa.h"
7#include "./proto.h"
8
9
10/* *** In this file: ************************************************************************************************************ */
11
12/* void build_record_dependencies(void) */
13/* void build_update_dependencies(void) */
14/* void build_var_dependencies(void) */
15/* void sort_records(void) */
16/* void sort_updates(void) */
17/* void sort_vars(void) */
18
19
20/* ****************************************************************************************************************************** */
21
22/* "sort_vars" will rearrange the list of vars to guarantee a correct order of definition. No circular definiton is expected. */
23
24/* A variable is determined if it is not depending on any other variables, or if it is depending on determined variables only. */
25/* It is assumed that no variable is determined at the beginning of the process. A pointer is set to the first entry at start. */
26
27/* This process is awfully long as soon as the number of variables becomes large. */
28/* A thousand of variables is enough to slow down significantly the sorting process. */
29
30/* "sort_updates" and "sort_records" are using a similar algorithm. */
31
32
33/* ****************************************************************************************************************************** */
34
35/* Build the list of variable dependencies, smash directives if any. */
36/* Directives are smashed to detect non obvious dependencies */
37
38/* List of dependencies is a list of ID corresponding to variables in the var definition. */
39
41 long in, out;
42 long *p = (long*) NULL;
43 char *str = (char*) NULL;
44 char tok[STRLENGTH] = {'\0'};
45 char sgn[2] = {'\0'};
46 long num;
47
48 for (out = 0L; out < Num_Vars; out++) { /* analyze each var, one by one for dependencies */
49 num = 0L;
50 str = Var_List[out].value;
51 for (;;) { /* count the number of var in the var definition */
52 str = get_sign_and_token(str, sgn, tok);
53 if (ISEMPTY(tok)) {
54 break;
55 }
56 in = var_id(tok);
57 if (UNDEFINED != in) {
58 num++;
59 }
60 }
61 Var_List[out].depend = (long*) malloc((size_t) ((long) sizeof (long) * (num+1L)));
62 if ((long*) NULL == Var_List[out].depend) {
63 print_error_location("variable dependency", Var_List[out].mline, Var_List[out].mfile);
64 (void) fprintf(STDERR, " dynamic memory allocation error\n");
66 }
67 p = Var_List[out].depend;
68 str = Var_List[out].value;
69 for (;;) {
70 str = get_sign_and_token(str, sgn, tok);
71 if (ISEMPTY(tok)) {
72 break;
73 }
74 in = var_id(tok);
75 if (UNDEFINED != in) {
76 *p = Var_List[in].ID; /* add variable ID to dependency list */
77 p++;
78 }
79 }
80 *p = -1L; /* to terminate the array */
81 }
82 return;
83}
84
85
86/* Build the list of update variable dependencies, smash directives if any. Don't forget that if the update value is empty, */
87/* variable definition must be USED!An update value can contain a reference to the variable itself! */
88/* Directives are smashed to detect non obvious dependencies. */
89
90/* List of dependencies is a list of ID corresponding to variables in the update definition AND in the update condition!! */
91
93 long in, out;
94 long *p = (long*) NULL;
95 char *str = (char*) NULL;
96 char *nam = (char*) NULL;
97 char tok[STRLENGTH] = {'\0'};
98 char buffer[LINLENGTH] = {'\0'};
99 char sgn[2] = {'\0'};
100 long k, num;
101
102 for (out = 0L; out < Num_Updates; out++) {
103 nam = Update_List[out].name;
104 /* add temporarily here update conditions, if any, to the list of updates */
105 (void) strcpy(buffer, Update_List[out].value);
106 (void) strcat(buffer, " ");
107 (void) strcat(buffer, Update_List[out].condition);
108 num = 0L;
109 /* scan buffer to number the dependencies */
110 str = buffer;
111 for (;;) {
112 str = get_sign_and_token(str, sgn, tok);
113 if (ISEMPTY(tok)) {
114 break;
115 }
116 k = 0L;
117 in = -999L;
118 while (UNDEFINED != in) {
119 k++;
120 in = update_id(tok, k);
121 if ((UNDEFINED != in) && (0 != strcmp(tok, nam))) {
122 num++;
123 }
124 }
125 }
126 Update_List[out].depend = (long*) malloc((size_t) ((long) sizeof (long) * (num+1L)));
127 if ((long*) NULL == Update_List[out].depend) {
128 print_error_location("update dependency", Update_List[out].mline, Update_List[out].mfile);
129 (void) fprintf(STDERR, " dynamic memory allocation error\n");
131 }
132 /* scan again the buffer to store the dependencies */
133 p = Update_List[out].depend;
134 str = buffer;
135 for (;;) {
136 str = get_sign_and_token(str, sgn, tok);
137 if (ISEMPTY(tok)) {
138 break;
139 }
140 k = 0L;
141 in = -999L;
142 while (UNDEFINED != in) {
143 k++;
144 in = update_id(tok, k); /* detect dependencies on -updated- var only */
145 if ((UNDEFINED != in) && (0 != strcmp(tok, nam))) {
146 *p = Update_List[in].ID;
147 p++;
148 }
149 }
150 }
151 *p = -1L; /* to terminate the array */
152 }
153 return;
154}
155
156
157/* List of dependencies is a list of ID corresponding to arrays in the array definition */
158
160 long in, out;
161 long *p = (long*) NULL;
162 char *str = (char*) NULL;
163 char tok[STRLENGTH] = {'\0'};
164 char sgn[2] = {'\0'};
165 long num;
166
167 for (out = 0L; out < Num_Records; out++) {
168 num = 0L;
169 str = Record_List[out].list1;
170 for (;;) { /* count number of arrays in the array definition */
171 str = get_sign_and_token(str, sgn, tok);
172 if (ISEMPTY(tok)) {
173 break;
174 }
175 in = record_id(tok);
176 if (UNDEFINED != in) {
177 num++;
178 }
179 }
180 Record_List[out].depend = (long*) malloc((size_t) ((long) sizeof (long) * (num+1L)));
181 if ((long*) NULL == Record_List[out].depend) {
182 print_error_location("array of pointers dependency", Record_List[out].mline, Record_List[out].mfile);
183 (void) fprintf(STDERR, " dynamic memory allocation error\n");
185 }
186 p = Record_List[out].depend;
187 str = Record_List[out].list1;
188 for (;;) {
189 str = get_sign_and_token(str, sgn, tok);
190 if (ISEMPTY(tok)) {
191 break;
192 }
193 in = record_id(tok);
194 if (UNDEFINED != in) {
195 *p = Record_List[in].ID; /* add array ID to dependency list */
196 p++;
197 }
198 }
199 *p = -1L; /* to terminate the array */
200 }
201 return;
202}
203
204
205/* Process instruction 'init' AS SOON AS POSSIBLE as it could contain acceptance test */
206/* like a test to prevent a division by zero in a variable definition. */
207/* We hope to produce a documented error message before a system message signalling a crash */
208
209void sort_vars(void) {
210 long out1, out2;
211 long nseg;
212 long determined_ptr;
213 long i, j;
214 long *p = (long*) NULL;
215 char *str = (char*) NULL;
216 int first, flag;
217
218 flag = true;
219 determined_ptr = 0L;
220
221 for (out1 = 0L; out1 < Num_Vars; out1++) {
222 flag = true;
223 first = true;
224 p = Var_List[out1].depend;
225 for (;;) { /* get the vars and check that they are determined */
226 j = *p;
227 if (-1L >= j) {
228 break;
229 }
230 flag = false;
231 for (i = 0L; i < determined_ptr; i++) {
232 if (j == Var_List[i].ID) {
233 flag = true;
234 break;
235 }
236 }
237 if (!flag) { /* this input is not yet determined */
238 if (!first) {
239 *p = *(p-1L); /* to speed up, move to beginning of dependencies */
240 *(p-1L) = j;
241 }
242 break;
243 }
244 p++;
245 first = false;
246 }
247 if (flag) { /* this variable depends on determined input */
248 Var_List[out1].determined = true;
249 swap_vars(out1, determined_ptr);
250 out1 = determined_ptr; /* start from the position after last determined */
251 determined_ptr++;
252 }
253 }
254
255 /* Verify that all variables are determined */
256 if ((Num_Vars - 1L) > determined_ptr) {
257 Error_Flag++;
258 (void) fprintf(STDERR, "\nNAPA Error: (static loop)\n");
259 (void) fprintf(STDERR, "\n These variables are involved in one or several loops:\n");
260 for (out1 = determined_ptr; out1 < Num_Vars; out1++) { /* review each undetermined var */
261 flag = false;
262 for (out2 = determined_ptr; out2 < Num_Vars; out2++) { /* check dependency */
263 if (out1 == out2) {
264 continue;
265 }
266 p = Var_List[out2].depend; /* dependencies of out2 */
267 for (;;) { /* check if var out1 is in dependency list of out2 */
268 j = *p;
269 if (-1L >= j) { /* reached end of dependency list */
270 break;
271 }
272 if (j == Var_List[out1].ID) {
273 flag = true; /* var is part of the dependency list */
274 break;
275 }
276 p++;
277 }
278 if (flag) {
279 break;
280 }
281 }
282 if (!flag) { /* this var does not participate to a loop */
283 swap_vars(out1, determined_ptr);
284 determined_ptr++; /* in this search, we mark it as determined */
285 out1 = determined_ptr; /* restart the search */
286 }
287 }
288 }
289
290 for (nseg = 0L; nseg < Num_Segments; nseg++) {
291 flag = true;
292 for (out1 = determined_ptr; out1 < Num_Vars; out1++) {
293 if (Var_List[out1].segment == nseg) {
294 flag = ((Var_List[out1].determined) && (flag)) ? true : false;
295 }
296 }
297 if (!flag) { /* there is a problem in this segment */
298 (void) fprintf(STDERR, "\n variable undetermination");
299 if (1L < Num_Segments) {
300 (void) fprintf(STDERR, " in segment [%ld]\n", nseg);
301 } else {
302 (void) fprintf(STDERR, " in netlist\n");
303 }
304 for (out1 = determined_ptr; out1 < Num_Vars; out1++) {
305 if (Var_List[out1].segment == nseg) {
306 if (!Var_List[out1].determined) {
307 if ('_' == Var_List[out1].name1[0]) {
308 str = Var_List[out1].name1 + 1; /* suppress underscore in void name */
309 } else {
310 str = Var_List[out1].name1;
311 }
312 (void) fprintf(STDERR, " -> var %s\n", str);
313 }
314 }
315 }
316 }
317 }
318 return;
319}
320
321
322/* Process instruction 'assert' AS SOON AS POSSIBLE as it could contain acceptance test like a test to prevent a division by zero */
323/* in a variable update. We hope to produce a documented error message before a system message signalling a crash. */
324
325void sort_updates(void) {
326 long out1, out2;
327 long nseg;
328 long determined_ptr, ptr;
329 long i, j;
330 long *p = (long*) NULL;
331 char *str = (char*) NULL;
332 int first, flag;
333
334 flag = true;
335 determined_ptr = 0L;
336
337 for (out1 = 0L; out1 < Num_Updates; out1++) {
338 ptr = determined_ptr + 1;
339 for (out2 = ptr; out2 < Num_Updates; out2++) { /* prioritize $assert$ */
340 if (0 == strncmp(Update_List[out2].name, "$assert$", (size_t) 8)) {
341 swap_updates(out2, ptr);
342 out2 = ptr;
343 ptr++;
344 }
345 }
346 flag = true;
347 first = true;
348 p = Update_List[out1].depend;
349 for (;;) { /* get updates and check that they are determined */
350 j = *p;
351 if (-1L >= j) {
352 break;
353 }
354 flag = false;
355 for (i = 0L; i < determined_ptr; i++) {
356 if (j == Update_List[i].ID) {
357 flag = true;
358 break;
359 }
360 }
361 if (!flag) {
362 if (!first) {
363 *p = *(p-1L);
364 *(p-1L) = j;
365 }
366 break;
367 }
368 p++;
369 first = false;
370 }
371 if (flag) {
372 Update_List[out1].determined = true;
373 swap_updates(out1, determined_ptr);
374 out1 = determined_ptr;
375 determined_ptr++;
376 }
377 }
378
379 /* Verify that all updates are determined */
380
381 if ((Num_Updates - 1L) > determined_ptr) {
382 Error_Flag++;
383 (void) fprintf(STDERR, "\nNAPA Error: (static loop)\n");
384 (void) fprintf(STDERR, "\n These updates are involved in one or several loops:\n");
385
386 for (out1 = determined_ptr; out1 < Num_Updates; out1++) { /* review undetermined updates */
387 flag = false;
388 for (out2 = determined_ptr; out2 < Num_Updates; out2++) { /* check dependency */
389 if (out1 == out2) {
390 continue;
391 }
392 p = Update_List[out2].depend; /* dependencies of out2 */
393 for (;;) { /* check if update out1 is in out2 dependency list */
394 j = *p;
395 if (-1L >= j) { /* reached end of dependency list */
396 break;
397 }
398 if (j == Update_List[out1].ID) {
399 flag = true; /* update is part of the dependency list */
400 break;
401 }
402 p++;
403 }
404 if (flag) {
405 break;
406 }
407 }
408 if (!flag) { /* this update does not participate to a loop */
409 swap_updates(out1, determined_ptr);
410 determined_ptr++; /* in this search, we mark it as determined */
411 out1 = determined_ptr; /* restart the search */
412 }
413 }
414 }
415
416 for (nseg = 0L; nseg < Num_Segments; nseg++) {
417 flag = true;
418 for (out1 = determined_ptr; out1 < Num_Updates; out1++) {
419 if (Update_List[out1].segment == nseg) {
420 flag = ((Update_List[out1].determined) && (flag)) ? true : false;
421 }
422 }
423 if (!flag) { /* there is a problem in this segment */
424 (void) fprintf(STDERR, "\n");
425 if (1L < Num_Segments) {
426 (void) fprintf(STDERR, " In Segment [%ld]\n", nseg);
427 }
428 for (out1 = determined_ptr; out1 < Num_Updates; out1++) {
429 if ((!Update_List[out1].determined) && (Update_List[out1].segment == nseg)) {
430 if ('_' == Update_List[out1].name[0]) {
431 str = Update_List[out1].name + 1; /* suppress underscore in void name */
432 } else {
433 str = Update_List[out1].name;
434 }
435 (void) fprintf(STDERR, " -> update %s\n", str);
436 }
437 }
438 }
439 }
440 return;
441}
442
443
444void sort_records(void) {
445 long out1, out2;
446 long determined_ptr;
447 long i, j;
448 long *p = (long*) NULL;
449 char *str = (char*) NULL;
450 int first, flag;
451
452 determined_ptr = 0L;
453
454 for (out1 = 0L; out1 < Num_Records; out1++) {
455 flag = true;
456 first = true;
457 p = Record_List[out1].depend;
458 for (;;) { /* get arrays of pointers, check if determined */
459 j = *p;
460 if (-1L >= j) {
461 break;
462 }
463 flag = false;
464 for (i = 0L; i < determined_ptr; i++) {
465 if (j == Record_List[i].ID) {
466 flag = true;
467 break;
468 }
469 }
470 if (!flag) {
471 if (!first) {
472 *p = *(p-1L);
473 *(p-1L) = j;
474 }
475 break;
476 }
477 p++;
478 first = false;
479 }
480 if (flag) {
481 Record_List[out1].determined = true;
482 swap_records(out1, determined_ptr);
483 out1 = determined_ptr;
484 determined_ptr++;
485 }
486 }
487
488 /* Verify that all Records are determined */
489
490 if ((Num_Records - 1L) > determined_ptr) {
491 Error_Flag++;
492 (void) fprintf(STDERR, "\nNAPA Error: (static loop)\n");
493 (void) fprintf(STDERR, "\n These arrays of pointers are involved in one or several loops:\n");
494 for (out1 = determined_ptr; out1 < Num_Records; out1++) { /* review undetermined records */
495 flag = false;
496 for (out2 = determined_ptr; out2 < Num_Records; out2++) { /* check dependency */
497 if (out1 == out2) {
498 continue;
499 }
500 p = Record_List[out2].depend; /* dependencies of out2 */
501 for (;;) { /* check if record out1 is in out2 dependency list */
502 j = *p;
503 if (-1L >= j) { /* reached end of dependency list */
504 break;
505 }
506 if (j == Record_List[out1].ID) {
507 flag = true; /* record is part of the dependency list */
508 break;
509 }
510 p++;
511 }
512 if (flag) {
513 break;
514 }
515 }
516 if (!flag) { /* this record does not participate to a loop */
517 swap_records(out1, determined_ptr);
518 determined_ptr++; /* in this search, we mark it as determined */
519 out1 = determined_ptr; /* restart the search */
520 }
521 }
522 }
523 for (out1 = determined_ptr; out1 < Num_Records; out1++) {
524 if (!Record_List[out1].determined) {
525 str = Record_List[out1].name;
526 (void) fprintf(STDERR, " -> array %s\n", str);
527 }
528 }
529 return;
530}
531
532
533/* ****************************************************************************************************************************** */
534/* end of file */
void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1476
long update_id(const char *identifier, long num)
Definition id.c:807
void swap_records(long i, long j)
Definition id.c:598
void swap_vars(long i, long j)
Definition id.c:606
long var_id(const char *identifier)
Definition id.c:855
void swap_updates(long i, long j)
Definition id.c:614
long record_id(const char *identifier)
Definition id.c:796
EXTERN VAR_TYPE Var_List[2047L]
Definition napa.h:970
EXTERN int Error_Flag
Definition napa.h:853
EXTERN RECORD_TYPE Record_List[127L]
Definition napa.h:965
EXTERN long Num_Vars
Definition napa.h:836
#define UNDEFINED
Definition napa.h:331
EXTERN long Num_Records
Definition napa.h:828
EXTERN long Num_Updates
Definition napa.h:834
#define STDERR
Definition napa.h:105
#define LINLENGTH
Definition napa.h:216
EXTERN long Num_Segments
Definition napa.h:831
#define STRLENGTH
Definition napa.h:217
#define ISEMPTY(s)
Definition napa.h:394
EXTERN UPDATE_TYPE Update_List[2047L]
Definition napa.h:968
void print_error_banner_and_exit(void)
Definition pr.c:5482
char * get_sign_and_token(char *str, char *sgn, char *tok)
Definition tk.c:1188
void sort_records(void)
Definition sv.c:444
void sort_updates(void)
Definition sv.c:325
void sort_vars(void)
Definition sv.c:209
void build_var_dependencies(void)
Definition sv.c:40
void build_record_dependencies(void)
Definition sv.c:159
void build_update_dependencies(void)
Definition sv.c:92