]> git.ipfire.org Git - thirdparty/gcc.git/blob - libbanshee/engine/nonspec.c
Merge tree-ssa-20020619-branch into mainline.
[thirdparty/gcc.git] / libbanshee / engine / nonspec.c
1 /*
2 * Copyright (c) 2000-2001
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31 #include "banshee.h"
32 #include "flowrow-sort.h"
33 #include "flowrow-var.h"
34 #include "setif-sort.h"
35 #include "setif-var.h"
36 #include "setst-sort.h"
37 #include "setst-var.h"
38 #include "term-sort.h"
39 #include "term-var.h"
40
41 struct constructor
42 {
43 sort_kind sort;
44 int type;
45 int arity;
46 char *name;
47 sig_elt *sig;
48 };
49
50 typedef struct constructor *constructor;
51
52 typedef enum
53 {
54 vnc_pos,
55 vnc_neg,
56 vnc_non
57 } vnc_kind;
58
59 struct sig_elt
60 {
61 vnc_kind variance;
62 sort_kind sort;
63 };
64
65 typedef struct sig_elt sig_elt;
66
67 typedef struct proj_pat
68 {
69 sort_kind sort;
70 int type;
71 stamp st;
72 int i;
73 gen_e exp;
74 vnc_kind variance;
75 constructor c;
76 } *proj_pat;
77
78
79 typedef struct cons_expr
80 {
81 sort_kind sort;
82 int type;
83 stamp st;
84 int arity;
85 char *name;
86 sig_elt *sig;
87 gen_e *exps;
88 } * cons_expr;
89
90
91 static int new_type()
92 {
93 static int type = 10;
94 int ret = type;
95 if (type > 2000)
96 {
97 fprintf(stderr, "Exceeded maximum number of constructors\n");
98 assert(0);
99 }
100 type += 2;
101 return ret;
102 }
103
104 static bool fixed_sort(sort_kind s)
105 {
106 return !(s == sort_term || s == sort_set);
107 }
108
109 /*
110 Convention : constructor types are even, pats are odd.
111 The smallest specialized type is 10.
112 */
113 static bool setif_is_pat(gen_e e)
114 {
115 int type = ((setif_term)e)->type;
116 return ( (type & 1) && (type > 10) );
117 }
118
119 static bool setst_is_pat(gen_e e)
120 {
121 int type = ((setst_term)e)->type;
122 return ( (type & 1) && (type > 10) );
123 }
124
125 static gen_e get_proj_var(sort_kind s, bool large)
126 {
127 switch (s)
128 {
129 case setif_sort:
130 {
131 if (large)
132 return (gen_e)sv_fresh_large(get_sort_region(setif_sort),NULL);
133 else return (gen_e)sv_fresh(get_sort_region(setif_sort),NULL);
134 }
135 break;
136 case setst_sort:
137 {
138 if (large)
139 return (gen_e)st_fresh_large(get_sort_region(setst_sort),NULL);
140 else return (gen_e)st_fresh(get_sort_region(setst_sort),NULL);
141 }
142 break;
143 case flowrow_sort:
144 {
145 if (large)
146 return (gen_e)fv_fresh_large(get_sort_region(flowrow_sort),NULL);
147 else return (gen_e)fv_fresh(get_sort_region(flowrow_sort),NULL);
148 }
149 break;
150 case term_sort:
151 {
152 if (large)
153 return (gen_e)tv_fresh_large(get_sort_region(term_sort),NULL);
154 else return (gen_e)tv_fresh(get_sort_region(term_sort),NULL)
155 }
156 break;
157 default:
158 {
159 fail("Unmatched sort in get_proj_var\n");
160 return NULL;
161 }
162 break;
163 }
164
165 return NULL;
166 }
167
168 static gen_e get_sort_zero(sort_kind s)
169 {
170 switch (s)
171 {
172 case setif_sort:
173 return setif_zero();
174 case setst_sort:
175 return setst_zero();
176 case flowrow_sort:
177 return flowrow_zero();
178 case term_sort:
179 return term_zero();
180 default:
181 fail("Unmatched sort in get_sort_zero\n");
182 return NULL;
183 }
184 return NULL;
185 }
186
187 static gen_e get_sort_one(sort_kind s)
188 {
189 switch (s)
190 {
191 case setif_sort:
192 return setif_one();
193 case setst_sort:
194 return setst_one();
195 case flowrow_sort:
196 return flowrow_one();
197 case term_sort:
198 return term_one();
199 default:
200 fail("Unmatched sort in get_sort_zero\n");
201 return NULL;
202 }
203 return NULL;
204 }
205
206 static region get_sort_region(sort s)
207 {
208 switch (s)
209 {
210 case setif_sort:
211 return setif_region;
212 case setst_sort:
213 return setst_region;
214 case flowrow_sort:
215 return flowrow_region;
216 case term_sort:
217 return term_region:
218 default:
219 fail("Unmatched sort in get_sort_region\n");
220 return NULL;
221 }
222 return NULL;
223 }
224
225 static term_hash get_sort_hash(sort s)
226 {
227 switch (s)
228 {
229 case setif_sort:
230 return setif_hash;
231 case setst_sort:
232 return setst_hash;
233 case flowrow_sort:
234 return flowrow_hash;
235 case term_sort:
236 return term_hash:
237 default:
238 fail("Unmatched sort in get_sort_hash\n");
239 return NULL;
240 }
241 return NULL;
242 }
243
244 constructor make_constructor(const char *name,sort_kind sort, sig_elt s[],
245 int arity)
246 {
247 constructor c = ralloc(expr_region,struct constructor);
248 sig_elt *sig = rarrayalloc(expr_region,arity,sig_elt);
249
250 c->type = new_type();
251
252 if (arity)
253 {
254 memcpy(sig,s,sizeof(sig_elt)*arity);
255 }
256
257 if ( fixed_sort(sort) )
258 failure("Specified sort does not allow constructor types\n");
259
260 c->sort = sort;
261 c->arity = arity;
262 c->name = rstrdup(expr_region,name);
263 c->sig = sig;
264
265 return c;
266 }
267
268 gen_e constructor_expr(constructor c, gen_e exps[], int arity)
269 {
270 cons_expr result;
271 int i;
272 region sort_region = get_sort_region(c->sort);
273 term_hash sort_hash = get_sort_hash(c->sort);
274
275 stamp *st = rarrayalloc(sort_region,arity + 1,stamp);
276 st[0] = c->type;
277
278 // Dynamic arity check
279 if(arity != c->arity)
280 failure("Signature mismatch\n");
281
282 // Dynamic sort checks
283 for (i = 0; i < arity; i++)
284 {
285 if ( c->sig[i].sort != exps[i]->sort)
286 failure(stderr,"Signature mismatch\n");
287 st[i+1] = exps[i]->st;
288 }
289
290 // Hash-consing of terms
291 if (!(result = term_hash_find(sort_hash,st,arity+1)) || arity == 0 )
292 {
293 gen_e *e = rarrayalloc(sort_region,arity,gen_e);
294
295 if (arity)
296 memcpy(e,exps,sizeof(gen_e)*arity);
297 else
298 e = NULL;
299
300 result = ralloc(sort_region,struct cons_expr);
301 result->type = st[0];
302 result->st = stamp_fresh();
303 result->sort = c->sort;
304 result->arity = c->arity;
305 result->name = c->name;
306 result->sig = c->sig;
307 result->exps = e;
308
309 term_hash_insert(expr_hash,result,st,arity+1);
310 }
311
312 return (gen_e)result;
313 }
314
315 static gen_e proj_pat(constructor c, int i, gen_e e)
316 {
317 proj_pat pat;
318 region sort_region = get_sort_region(e->sort);
319 term_hash sort_hash = get_sort_hash(e->sort);
320
321 stamp s[3];
322 s[0] = c->type + 1;
323 s[1] = e->st;
324 s[2] = i;
325
326 if (! (pat = term_hash_find(sort_hash,s,3)) )
327 {
328 pat = ralloc(sort_region,struct proj_pat);
329 pat->type = s[0];
330 pat->st = stamp_fresh();
331 pat->sort = c->sort;
332 pat->exp = e;
333 pat->variance = c->sig[i].variance;
334 pat->c = c;
335 pat->i = i;
336 term_hash_insert(sort_hash,pat,s,3);
337 }
338
339 return (gen_e)pat;
340 }
341
342 gen_e setif_proj_pat(constructor c,int i,gen_e e)
343 {
344 return proj_pat(c,i,e);
345 }
346
347 gen_e setst_proj_pat(constructor c, int i, gen_e e)
348 {
349 return proj_pat(c,i,e);
350 }
351
352 gen_e setif_proj(constructor c, int i, gen_e e)
353 {
354 setif_var v;
355 gen_e proj_var, proj;
356
357 gen_e nonspec_get_proj(gen_e_list arg1)
358 {
359 proj_pat pat;
360 gen_e_list_scanner scan;
361 gen_e temp;
362
363 gen_e_list_scan(arg1,&scan);
364 while (gen_e_list_next(&scan,&temp))
365 {
366 pat = (proj_pat)temp;
367 if ( pat_match(pat->type,c->type) && i == pat->i )
368 return pat->exp;
369 }
370 return NULL;
371 }
372
373 if (e->sort != setif_sort)
374 {
375 failure("Sort check : setif_proj\n");
376 }
377
378 else if (i < 0 || i > c->arity)
379 {
380 failure("Signature mismatch\n");
381 }
382
383 else if (setif_is_zero(e))
384 return get_sort_zero(c->sig[i].sort);
385
386 else if ( ((setif_term)e)->type == c->type )
387 {
388 cons_expr constructed = (cons_expr)e;
389 return constructed->exps[i];
390 }
391
392 else if (setif_is_var(e))
393 {
394 v = (setif_var)e;
395 if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
396 {
397 return proj;
398 }
399 else
400 {
401 gen_e pat;
402 gen_e_list_scanner scan;
403 gen_e lb;
404 proj_var = get_proj_var(c->sig[i].sort,FALSE);
405 pat = setif_proj_pat(c,i,proj_var);
406 sv_add_ub_proj(sort_region,v,pat);
407
408 gen_e_list_scan(sv_get_lbs(v),&scan);
409 while (gen_e_list_next(&scan,&lb))
410 {
411 setif_inclusion(lb,pat);
412 }
413 return proj_var;
414 }
415 }
416
417 else if (setif_is_union(e))
418 {
419 if( (proj = nonspec_get_proj(setif_get_proj_cache(e))) )
420 return proj;
421 else
422 {
423 gen_e pat;
424 proj_var = get_proj_var(c->sig[i].sort,FALSE);
425 pat = setif_proj_pat(c,i,proj_var);
426
427 setif_set_proj_cache(e,pat);
428
429 setif_inclusion(e,pat);
430 return proj_var;
431 }
432 }
433 else
434 {
435 gen_e pat;
436 proj_var = get_proj_var(c->sig[i].sort,FALSE);
437 pat = setif_proj_pat(c,i,proj_var);
438 setif_inclusion(e,pat);
439 return proj_var;
440 }
441 }
442
443 gen_e setst_proj(constructor c, int i, gen_e e)
444 {
445 setst_var v;
446 gen_e proj_var, proj;
447
448 gen_e nonspec_get_proj(gen_e_list arg1)
449 {
450 proj_pat pat;
451 gen_e_list_scanner scan;
452 gen_e temp;
453
454 gen_e_list_scan(arg1,&scan);
455 while (gen_e_list_next(&scan,&temp))
456 {
457 pat = (proj_pat)temp;
458 if ( pat_match(pat->type,c->type) && i == pat->i )
459 return pat->exp;
460 }
461 return NULL;
462 }
463
464 if (e->sort != setst_sort)
465 {
466 failure("Sort check : setst_proj\n");
467 }
468
469 else if (i < 0 || i > c->arity)
470 {
471 failure("Signature mismatch\n");
472 }
473
474 else if (setst_is_zero(e))
475 return get_sort_zero(c->sig[i].sort);
476
477 else if ( ((setst_term)e)->type == c->type )
478 {
479 cons_expr constructed = (cons_expr)e;
480 return constructed->exps[i];
481 }
482
483 else if (setst_is_var(e))
484 {
485 v = (setst_var)e;
486 if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
487 {
488 return proj;
489 }
490 else
491 {
492 gen_e pat;
493 gen_e_list_scanner scan;
494 gen_e lb;
495 proj_var = get_proj_var(c->sig[i].sort,FALSE);
496 pat = setst_proj_pat(c,i,proj_var);
497 sv_add_ub_proj(sort_region,v,pat);
498
499 gen_e_list_scan(sv_get_lbs(v),&scan);
500 while (gen_e_list_next(&scan,&lb))
501 {
502 setst_inclusion(lb,pat);
503 }
504 return proj_var;
505 }
506 }
507
508 else if (setst_is_union(e))
509 {
510 if( (proj = nonspec_get_proj(setst_get_proj_cache(e))) )
511 return proj;
512 else
513 {
514 gen_e pat;
515 proj_var = get_proj_var(c->sig[i].sort,FALSE);
516 pat = setst_proj_pat(c,i,proj_var);
517
518 setst_set_proj_cache(e,pat);
519
520 setst_inclusion(e,pat);
521 return proj_var;
522 }
523 }
524 else
525 {
526 gen_e pat;
527 proj_var = get_proj_var(c->sig[i].sort,FALSE);
528 pat = setst_proj_pat(c,i,proj_var);
529 setst_inclusion(e,pat);
530 return proj_var;
531 }
532 }
533
534 static void setif_con_match(gen_e e1, gen_e e2)
535 {
536 // Case where e1 is a constructor expression and e2 is a proj_pat
537 if (pat_match(((setif_term)e2)->type,((setif_term)e1)->type))
538 {
539 cons_expr c = (cons_expr)e1;
540 proj_pat p = (proj_pat)e2;
541 int i = p->i;
542
543 if (c->sig[i].variance == vnc_pos)
544 call_inclusion_fn(c->exps[i],p->exp);
545 else if (c->sig[i].variance == vnc_neg)
546 call_inclusion_fn(p->exp,c->exps[i]);
547 else
548 call_unify_fn(c->exps[i],p->exp);
549 }
550 else if (setif_is_pat(e2))
551 {
552 return;
553 }
554
555 // Case where e1 and e2 are constructor expressions
556 else
557 {
558 cons_expr c1 = (cons_expr)e1,
559 c2 = (cons_expr)e2;
560
561 if (c1->type != c2->type)
562 failure("Constructor mismatch\n");
563 else
564 {
565 int i;
566 for (i = 0; i < c1->arity; i++)
567 {
568 if (c1->sig[i].variance == vnc_pos)
569 call_inclusion_fn(e1,e2);
570 else if (c1->sig[i].variance == vnc_neg)
571 call_inclusion_fn(e2,e1);
572 else
573 call_unify_fn(e1,e2);
574 }
575
576 }
577 }
578 }
579
580 static void setst_con_match(gen_e e1, gen_e e2)
581 {
582 // Case where e1 is a constructor expression and e2 is a proj_pat
583 if (pat_match(((setst_term)e2)->type,((setst_term)e1)->type))
584 {
585 cons_expr c = (cons_expr)e1;
586 proj_pat p = (proj_pat)e2;
587 int i = p->i;
588
589 if (c->sig[i].variance == vnc_pos)
590 call_inclusion_fn(c->exps[i],p->exp);
591 else if (c->sig[i].variance == vnc_neg)
592 call_inclusion_fn(p->exp,c->exps[i]);
593 else
594 call_unify_fn(c->exps[i],p->exp);
595 }
596 else if (setst_is_pat(e2))
597 {
598 return;
599 }
600
601 // Case where e1 and e2 are constructor expressions
602 else
603 {
604 cons_expr c1 = (cons_expr)e1,
605 c2 = (cons_expr)e2;
606
607 if (c1->type != c2->type)
608 failure("Constructor mismatch\n");
609 else
610 {
611 int i;
612 for (i = 0; i < c1->arity; i++)
613 {
614 if (c1->sig[i].variance == vnc_pos)
615 call_inclusion_fn(e1,e2);
616 else if (c1->sig[i].variance == vnc_neg)
617 call_inclusion_fn(e2,e1);
618 else
619 call_unify_fn(e1,e2);
620 }
621
622 }
623 }
624 }
625
626 // given x <= proj(c,i,e)
627 // proj_merge(region,e,get_proj_i_arg,fresh_large_fn_ptr,
628 // sort_inclusion_fn_ptr,set_inclusion)
629 static bool nonspec_res_proj(set_var v1,gen_e e2)
630 {
631 proj_pat projection_pat = (proj_pat)e2;
632
633 gen_e setif_get_proj(gen_e_list arg1)
634 {
635 gen_e_list_scanner scan;
636 gen_e temp;
637 proj_pat pat;
638
639 gen_e_list_scan(arg1,&scan);
640 while(gen_e_list_next(&scan,&temp))
641 {
642 pat = (proj_pat)temp;
643 if ( pat->type == ((setif_term)e2)->type &&
644 pat->i == ((proj_pat)e2)->i)
645 return pat->exp;
646 }
647 return NULL;
648 }
649
650 gen_e fresh_large(void)
651 {
652 return get_proj_var( ((proj_pat)e2)->exp->sort,TRUE);
653 }
654
655 bool sort_inclusion(gen_e e1, gen_e e2)
656 {
657 if ( projection_pat->variance == vnc_pos )
658 return call_inclusion_fn(e1,e2);
659 else if ( projection_pat->variance == vnc_neg)
660 return call_inclusion_fn(e2,e1);
661 else
662 return call_unify_fn(e1,e2);
663 }
664
665 gen_e proj_con(gen_e e)
666 {
667 return make_proj_pat( ((proj_pat)e2)->c, ((proj_pat)e2)->i,e);
668 }
669
670 return setif_proj_merge(setif_region,v1,((proj_pat)e2)->exp,
671 setif_get_proj,proj_con,
672 fresh_large,sort_inclusion,
673 call_setif_inclusion);
674
675 }
676
677
678 void call_setif_inclusion(gen_e e1,gen_e e2)
679 {
680 setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
681 }
682
683 void call_setif_unify(gen_e e1, gen_e e2)
684 {
685 setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
686 setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
687 }
688
689 void call_setst_inclusion(gen_e e1, gen_e e2)
690 {
691 setst_inclusion(setst_con_match,e1,e2);
692 }
693
694 void call_setst_unify(gen_e e1, gen_e e2)
695 {
696 setst_inclusion(setst_con_match,e1,e2);
697 setst_inclusion(setst_con_match,e2,e1);
698 }
699
700 void call_flowrow_inclusion(gen_e e1,gen_e e2)
701 {
702
703 if ( (e1->sort != flowrow_sort) || (e2->sort != flowrow_sort) )
704 failure("Constraint system is not well-sorted\n");
705
706 if ( flowrow_base_sort(e1) != flowrow_base_sert(e2))
707 failure("Constraint system is not well-sorted\n");
708
709
710 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
711 }
712
713 void call_flowrow_unify(gen_e e1, gen_e e2)
714 {
715 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
716 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
717 }
718
719 static void term_con_match(gen_e e1, gen_e e2)
720 {
721 cons_expr c1 = (cons_expr)e1,
722 c2 = (cons_expr)e2;
723
724 if (c1->type != c2->type)
725 failure("Constructor mismatch\n");
726 else
727 {
728 int i;
729 for (i = 0; i < c1->arity; i++)
730 {
731 call_unify_fn(e1,e2);
732 }
733
734 }
735 }
736
737 static void term_occurs(term_var v, gen_e e)
738 {
739 gen_e ecr = term_get_ecr(e);
740
741 if (((gen_term)ecr)->type == VAR_TYPE)
742 return ( term_get_stamp((gen_e)v) == term_get_stamp(e) );
743
744 else if (((gen_term)ecr)->type >= 10)
745 {
746 cons_expr c_e = (cons_expr) e;
747 int i;
748 for (int i = 0; i < arity; i++)
749 {
750 if (term_occurs(v,c->exps[i]))
751 return TRUE;
752 }
753 }
754
755 return FALSE;
756 }
757
758 void call_term_unify(gen_e e1, gen_e e2)
759 {
760 term_unify(term_con_match,term_occurs,e1,e2);
761 }
762
763 void call_term_cunify(gen_e e1, gen_e e2)
764 {
765 term_cunify(term_con_match,term_occurs,e1,e2);
766 }
767
768
769 static void call_inclusion_fn(gen_e e1, gen_e e2)
770 {
771 switch (e1->sort)
772 {
773 case sort_setif:
774 {
775 setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
776 }
777 break;
778 case sort_setst:
779 {
780 setst_inclusion(setst_con_match,e1,e2);
781 }
782 break;
783 case sort_term:
784 {
785 term_unify(term_con_match,term_occurs,e1,e2);
786 }
787 break;
788 case sort_row:
789 {
790 /* TODO */
791 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
792 }
793 break;
794 default :
795 fail("Unmatched sort in call inclusion\n");
796 }
797 }
798
799 static bool call_unify_fn(gen_e e1, gen_e e2)
800 {
801
802 switch (e1->sort)
803 {
804 case sort_setif:
805 {
806 setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
807 setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
808 }
809 break;
810 case sort_setst:
811 {
812 setst_inclusion(setst_con_match,e1,e2);
813 setst_inclusion(setst_con_match,e2,e1);
814 }
815 break;
816 case sort_term:
817 {
818 term_unify(term_con_match,term_occurs,e1,e2);
819 }
820 break;
821 case sort_row:
822 {
823 /* TODO */
824 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
825 flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
826 }
827 break;
828 default :
829 fail("Unmatched sort in call inclusion\n");
830 }
831 }
832
833 void nonspec_init(void)
834 {
835 banshee_init();
836 setif_init();
837 setst_init();
838 flowrow_init();
839 }
840
841 void nonspec_reset(void)
842 {
843 flowrow_reset();
844 setst_reset();
845 setif_reset();
846 banshee_reset();
847 }
848
849 void expr_print(FILE *f,gen_e e)
850 {
851
852 }