home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #3 / Amiga Plus CD - 1997 - No. 03.iso / pd / programmierung / vbcc / type_expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-29  |  50.6 KB  |  1,245 lines

  1. /*  $VER: vbcc (type_expr.c) V0.4   */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int alg_opt(np),type_expression2(np);
  8. int test_assignment(struct Typ *,np);
  9. void make_cexpr(np);
  10.  
  11. int dontopt;
  12.  
  13. void insert_const2(union atyps *p,int t)
  14. /*  Traegt Konstante in entprechendes Feld ein        */
  15. {
  16.     if(!p) ierror(0);
  17.     t&=31;
  18.     if(t==CHAR) {p->vchar=vchar;return;}
  19.     if(t==SHORT) {p->vshort=vshort;return;}
  20.     if(t==INT) {p->vint=vint;return;}
  21.     if(t==LONG) {p->vlong=vlong;return;}
  22.     if(t==(UNSIGNED|CHAR)) {p->vuchar=vuchar;return;}
  23.     if(t==(UNSIGNED|SHORT)) {p->vushort=vushort;return;}
  24.     if(t==(UNSIGNED|INT)) {p->vuint=vuint;return;}
  25.     if(t==(UNSIGNED|LONG)) {p->vulong=vulong;return;}
  26.     if(t==FLOAT) {p->vfloat=vfloat;return;}
  27.     if(t==DOUBLE) {p->vdouble=vdouble;return;}
  28.     if(t==POINTER) {p->vpointer=vpointer;return;}
  29. }
  30. void insert_const(np p)
  31. /*  Spezialfall fuer np */
  32. {
  33.     if(!p||!p->ntyp) ierror(0);
  34.     insert_const2(&p->val,p->ntyp->flags);
  35. }
  36. int const_typ(struct Typ *p)
  37. /*  Testet, ob Typ konstant ist oder konstante Elemente enthaelt    */
  38. {
  39.     int i;struct struct_declaration *sd;
  40.     if(p->flags&CONST) return(1);
  41.     if(p->flags==STRUCT||p->flags==UNION)
  42.         for(i=0;i<p->exact->count;i++)
  43.             if(const_typ((*p->exact->sl)[i].styp)) return(1);
  44.     return(0);
  45. }
  46. void eval_const(union atyps *p,int t)
  47. /*  weist bestimmten globalen Variablen Wert einer CEXPR zu         */
  48. {
  49.     int f=t&15;
  50.     if(!p) ierror(0);
  51.     if(f>=CHAR&&f<=LONG){
  52.         if(!(t&UNSIGNED)){
  53.             if(f==CHAR) vlong=zc2zl(p->vchar);
  54.             if(f==SHORT)vlong=zs2zl(p->vshort);
  55.             if(f==INT)  vlong=zi2zl(p->vint);
  56.             if(f==LONG) vlong=p->vlong;
  57.             vulong=zl2zul(vlong);
  58.             vdouble=zl2zd(vlong);
  59.         }else{
  60.             if(f==CHAR) vulong=zuc2zul(p->vuchar);
  61.             if(f==SHORT)vulong=zus2zul(p->vushort);
  62.             if(f==INT)  vulong=zui2zul(p->vuint);
  63.             if(f==LONG) vulong=p->vulong;
  64.             vlong=zul2zl(vulong);
  65.             vdouble=zul2zd(vulong);
  66.         }
  67.         vpointer=zul2zp(vulong);
  68.     }else{
  69.         if(f==POINTER){
  70.             vulong=zp2zul(p->vpointer);
  71.             vlong=zul2zl(vulong);vdouble=zul2zd(vulong);
  72.         }else{
  73.             if(f==FLOAT) vdouble=zf2zd(p->vfloat); else vdouble=p->vdouble;
  74.             vlong=zd2zl(vdouble);
  75.             vulong=zl2zul(vlong);
  76.         }
  77.     }
  78.     vfloat=zd2zf(vdouble);
  79.     vuchar=zul2zuc(vulong);
  80.     vushort=zul2zus(vulong);
  81.     vuint=zul2zui(vulong);
  82.     vchar=zl2zc(vlong);
  83.     vshort=zl2zs(vlong);
  84.     vint=zl2zi(vlong);
  85. }
  86. struct Typ *arith_typ(struct Typ *a,struct Typ *b)
  87. /*  Erzeugt Typ fuer arithmetische Umwandlung von zwei Operanden    */
  88. {
  89.     int ta,tb;struct Typ *new;
  90.     new=mymalloc(TYPS);
  91.     new->next=0;
  92.     ta=a->flags&31;tb=b->flags&31;
  93.     if(ta==DOUBLE||tb==DOUBLE){new->flags=DOUBLE;return(new);}
  94.     if(ta==FLOAT||tb==FLOAT){new->flags=FLOAT;return(new);}
  95.     ta=int_erw(ta);tb=int_erw(tb);
  96.     if(ta==(UNSIGNED|LONG)||tb==(UNSIGNED|LONG)){new->flags=UNSIGNED|LONG;return(new);}
  97.     if((ta==LONG&&tb==(UNSIGNED|INT))||(ta==(UNSIGNED|INT)&&tb==LONG)){
  98.         if(UINT_MAX<=LONG_MAX) new->flags=LONG; else new->flags=UNSIGNED|LONG;
  99.         return(new);
  100.     }
  101.     if(ta==LONG||tb==LONG){new->flags=LONG;return(new);}
  102.     if(ta==(UNSIGNED|INT)||tb==(UNSIGNED|INT)){new->flags=UNSIGNED|INT;return(new);}
  103.     new->flags=INT;
  104.     return(new);
  105. }
  106. int int_erw(int t)
  107. /*  Fuehrt Integer_Erweiterung eines Typen durch                */
  108. {
  109.     if((t&15)>SHORT) return(t);
  110.     if((t&31)==CHAR&&SCHAR_MAX<=INT_MAX) return(INT);
  111.     if((t&31)==SHORT&&SHRT_MAX<=INT_MAX) return(INT);
  112.     if((t&31)==(UNSIGNED|CHAR)&&UCHAR_MAX<=INT_MAX) return(INT);
  113.     if((t&31)==(UNSIGNED|SHORT)&&USHRT_MAX<=INT_MAX) return(INT);
  114.     return(UNSIGNED|INT);
  115. }
  116. int type_expression(np p)
  117. /*  Art Frontend fuer type_expression2(). Setzt dontopt auf 0   */
  118. {
  119.     dontopt=0;
  120.     return(type_expression2(p));
  121. }
  122. int type_expression2(np p)
  123. /*  Erzeugt Typ-Strukturen fuer jeden Knoten des Baumes und     */
  124. /*  liefert eins zurueck, wenn der Baum ok ist, sonst 0         */
  125. /*  Die Berechnung von Konstanten und andere Vereinfachungen    */
  126. /*  sollten vielleicht in eigene Funktion kommen                */
  127. {
  128.     int ok,f=p->flags,mopt=dontopt;
  129.     if(!p){ierror(0);return(1);}
  130. /*    if(p->ntyp) printf("Warnung: ntyp!=0\n");*/
  131.     p->lvalue=0;
  132.     p->sidefx=0;
  133.     ok=1;
  134.     if(f==CALL&&p->left->flags==IDENTIFIER&&!find_var(p->left->identifier,0)){
  135.     /*  implizite Deklaration bei Aufruf einer Funktion     */
  136.         struct struct_declaration *sd;struct Typ *t;
  137.         error(161,p->left->identifier);
  138.         sd=mymalloc(sizeof(*sd));
  139.         sd->count=0;
  140.         t=mymalloc(TYPS);
  141.         t->flags=FUNKT;
  142.         t->exact=add_sd(sd);
  143.         t->next=mymalloc(TYPS);
  144.         t->next->next=0;
  145.         t->next->flags=INT;
  146.         add_var(p->left->identifier,t,EXTERN,0);
  147.     }
  148.     dontopt=0;
  149.     if(f==ADDRESS&&p->left->flags==IDENTIFIER) {p->left->flags|=256;/*puts("&const");*/}
  150.     if(p->left&&p->flags!=ASSIGNADD){ struct struct_declaration *sd;
  151.     /*  bei ASSIGNADD wird der linke Zweig durch den Link bewertet  */
  152.         ok&=type_expression2(p->left); p->sidefx|=p->left->sidefx;
  153.         if(!ok) return(0);
  154.     }
  155.     if(p->right&&p->right->flags!=MEMBER){ struct struct_declaration *sd;
  156.         if(p->flags==ASSIGNADD) dontopt=1; else dontopt=0;
  157.         ok&=type_expression2(p->right); p->sidefx|=p->right->sidefx;
  158.         if(!ok) return(0);
  159.     }
  160.  
  161. /*    printf("bearbeite %s\n",ename[p->flags]);*/
  162. /*  Erzeugung von Zeigern aus Arrays                            */
  163. /*  Hier muss noch einiges genauer werden (wie gehoert das?)    */
  164.     if(p->left&&((p->left->ntyp->flags&15)==ARRAY||(p->left->ntyp->flags&15)==FUNKT)){
  165.         if(f!=ADDRESS&&f!=ADDRESSA&&f!=ADDRESSS&&f!=FIRSTELEMENT&&f!=DSTRUCT&&(f<PREINC||f>POSTDEC)&&(f<ASSIGN||f>ASSIGNRSHIFT)){
  166.             np new=mymalloc(NODES);
  167.             if((p->left->ntyp->flags&15)==ARRAY) new->flags=ADDRESSA;
  168.              else new->flags=ADDRESS;
  169.             new->ntyp=0;
  170.             new->left=p->left;
  171.             new->right=0;new->lvalue=0;new->sidefx=0; /* sind sidefx immer 0? */
  172.             p->left=new;
  173.             ok&=type_expression2(p->left);
  174.         }
  175.     }
  176.     if(p->right&&f!=FIRSTELEMENT&&f!=DSTRUCT&&f!=ADDRESSS&&((p->right->ntyp->flags&15)==ARRAY||(p->right->ntyp->flags&15)==FUNKT)){
  177.             np new=mymalloc(NODES);
  178.             if((p->right->ntyp->flags&15)==ARRAY) new->flags=ADDRESSA;
  179.              else new->flags=ADDRESS;
  180.             new->ntyp=0;
  181.             new->left=p->right;
  182.             new->right=0;new->lvalue=0;new->sidefx=0; /* sind sidefx immer 0? */
  183.             p->right=new;
  184.             ok&=type_expression2(p->right);
  185.     }
  186.  
  187.     if(f==IDENTIFIER||f==(IDENTIFIER|256)){
  188.         int ff;struct Var *v;
  189.         v=find_var(p->identifier,0);
  190.         if(v==0){error(82,p->identifier);return(0);}
  191.         ff=v->vtyp->flags&15;
  192.         if((ff>=CHAR&&ff<=DOUBLE)||ff==POINTER||ff==STRUCT||ff==UNION/*||ff==ARRAY*/) p->lvalue=1;
  193.         p->ntyp=clone_typ(v->vtyp);
  194.         /*  arithmetischen const Typ als Konstante behandeln, das muss noch
  195.             deutlich anders werden, bevor man es wirklich so machen kann
  196.         if((p->ntyp->flags&CONST)&&arith(p->ntyp->flags&15)&&v->clist&&!(f&256)){
  197.             p->flags=CEXPR;
  198.             p->val=v->clist->val;
  199.             v->flags|=USEDASSOURCE;
  200.         }*/
  201.         p->flags&=~256;
  202.         if((p->ntyp->flags&15)==ENUM){
  203.         /*  enumerations auch als Konstante (int) behandeln */
  204.             p->flags=CEXPR;
  205.             if(!v->clist) ierror(0);
  206.             p->val=v->clist->val;
  207.             p->ntyp->flags=CONST|INT;
  208.         }
  209.         p->o.v=v;
  210.         return(1);
  211.     }
  212.  
  213.     if(f==CEXPR||f==PCEXPR||f==STRING) return(1);
  214.  
  215.     if(f==KOMMA){
  216.         p->ntyp=clone_typ(p->right->ntyp);
  217.         if(f==CEXPR) p->val=p->right->val;
  218.         return(ok);
  219.     }
  220.     if(f==ASSIGN||f==ASSIGNADD){
  221.         if(!p){ierror(0);return(0);}
  222.         if(!p->left){ierror(0);return(0);}
  223.         if(p->left->lvalue==0) {error(86);/*prd(p->left->ntyp);*/return(0);}
  224.         if(const_typ(p->left->ntyp)) {error(87);return(0);}
  225.         if(type_uncomplete(p->left->ntyp)) {error(88);return(0);}
  226.         if(type_uncomplete(p->right->ntyp)) {error(88);return(0);}
  227.         p->ntyp=clone_typ(p->left->ntyp);
  228.         p->sidefx=1;
  229.         return(test_assignment(p->left->ntyp,p->right));
  230.     }
  231.     if(f==LOR||f==LAND){
  232.         int a1=-1,a2=-1,m;
  233.         if(f==LAND) m=1; else m=0;
  234.         p->ntyp=mymalloc(TYPS);
  235.         p->ntyp->flags=INT;p->ntyp->next=0;
  236.         if(!arith(p->left->ntyp->flags&15)&&(p->left->ntyp->flags&15)!=POINTER)
  237.             {error(89);ok=0;}
  238.         if(!arith(p->right->ntyp->flags&15)&&(p->right->ntyp->flags&15)!=POINTER)
  239.             {error(89);ok=0;}
  240.         if(p->left->flags==CEXPR){
  241.             eval_constn(p->left);
  242.             if(!zdeqto(vdouble,d2zd(0.0))||!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))) a1=1; else a1=0;
  243.         }
  244.         if(p->right->flags==CEXPR){
  245.             eval_constn(p->right);
  246.             if(!zdeqto(vdouble,d2zd(0.0))||!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))) a2=1; else a2=0;
  247.         }
  248.         if(a1==1-m||a2==1-m||(a1==m&&a2==m)){
  249.             p->flags=CEXPR;p->sidefx=0;
  250.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;} else p->sidefx=1;
  251.             if(!p->right->sidefx||a1==1-m) {free_expression(p->right);p->right=0;} else p->sidefx=0;
  252.             if(a1==1-m||a2==1-m) {p->val.vint=zl2zi(l2zl((long)(1-m)));}
  253.              else {p->val.vint=zl2zi(l2zl((long)m));}
  254.         }
  255.         return(ok);
  256.     }
  257.     if(f==OR||f==AND||f==XOR){
  258.         if(((p->left->ntyp->flags&15)<CHAR)||((p->left->ntyp->flags&15)>LONG)){error(90);return(0);}
  259.         if(((p->right->ntyp->flags&15)<CHAR)||((p->right->ntyp->flags&15)>LONG)){error(90);return(0);}
  260.         p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  261.         if(!mopt){
  262.             if(!alg_opt(p)) ierror(0);
  263.         }
  264.         return(ok);
  265.     }
  266.     if(f==LESS||f==LESSEQ||f==GREATER||f==GREATEREQ||f==EQUAL||f==INEQUAL){
  267.     /*  hier noch einige Abfragen fuer sichere Entscheidungen einbauen  */
  268.     /*  z.B. unigned/signed-Vergleiche etc.                             */
  269.     /*  die val.vint=0/1-Zuweisungen muessen noch an zint angepasst     */
  270.     /*  werden                                                          */
  271.         zlong s1,s2;zulong u1,u2;zdouble d1,d2;int c=0;
  272.         struct Typ *t;
  273.         if(!arith(p->left->ntyp->flags&15)||!arith(p->right->ntyp->flags&15)){
  274.             if((p->left->ntyp->flags&15)!=POINTER||(p->right->ntyp->flags&15)!=POINTER){
  275.                 if(f!=EQUAL&&f!=INEQUAL){
  276.                     error(92);return(0);
  277.                 }else{
  278.                     if(((p->left->ntyp->flags&15)!=POINTER||p->right->flags!=CEXPR)&&
  279.                        ((p->right->ntyp->flags&15)!=POINTER||p->left->flags!=CEXPR)){
  280.                         error(93);return(0);
  281.                     }else{
  282.                         if(p->left->flags==CEXPR) eval_constn(p->left);
  283.                          else                     eval_constn(p->right);
  284.                         if(vdouble!=0||vlong!=0||vulong!=0)
  285.                             {error(40);return(0);}
  286.                     }
  287.                 }
  288.             }else{
  289.                 if(compare_pointers(p->left->ntyp->next,p->right->ntyp->next,15)){
  290.                 }else{
  291.                     if(f!=EQUAL&&f!=INEQUAL){error(41);}
  292.                     if((p->left->ntyp->next->flags&15)!=VOID&&(p->right->ntyp->next->flags&15)!=VOID)
  293.                         {error(41);}
  294.                 }
  295.             }
  296.         }
  297.         if(p->left->flags==CEXPR){
  298.             eval_constn(p->left);
  299.             d1=vdouble;u1=vulong;s1=vlong;c|=1;
  300.             if(p->right->ntyp->flags&UNSIGNED&&!(p->left->ntyp->flags&UNSIGNED)){
  301.                 if(zdleq(d1,zl2zd(l2zl(0)))&&zlleq(s1,l2zl(0))){
  302.                     if(!zdeqto(d1,d2zd(0.0))||!zleqto(s1,l2zl(0L))){
  303.                         error(165);
  304.                     }else{
  305.                         if(f==GREATER||f==LESSEQ) error(165);
  306.                     }
  307.                 }
  308.             }
  309.         }
  310.         if(p->right->flags==CEXPR){
  311.             eval_constn(p->right);
  312.             d2=vdouble;u2=vulong;s2=vlong;c|=2;
  313.             if(p->left->ntyp->flags&UNSIGNED&&!(p->right->ntyp->flags&UNSIGNED)){
  314.                 if(zdleq(d2,zl2zd(l2zl(0)))&&zlleq(s2,l2zl(0))){
  315.                     if(!zdeqto(d2,d2zd(0.0))||!zleqto(s2,l2zl(0L))){
  316.                         error(165);
  317.                     }else{
  318.                         if(f==LESS||f==GREATEREQ) error(165);
  319.                     }
  320.                 }
  321.             }
  322.         }
  323.         p->ntyp=mymalloc(TYPS);
  324.         p->ntyp->flags=INT;
  325.         p->ntyp->next=0;
  326.         if(c==3){
  327.             p->flags=CEXPR;
  328.             t=arith_typ(p->left->ntyp,p->right->ntyp);
  329.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  330.             if(!p->right->sidefx) {free_expression(p->right);p->right=0;}
  331.             if((t->flags&15)==FLOAT||(t->flags&15)==DOUBLE){
  332.                 if(f==EQUAL) p->val.vint=zdeqto(d1,d2);
  333.                 if(f==INEQUAL) p->val.vint=!zdeqto(d1,d2);
  334.                 if(f==LESSEQ) p->val.vint=zdleq(d1,d2);
  335.                 if(f==GREATER) p->val.vint=!zdleq(d1,d2);
  336.                 if(f==LESS){
  337.                     if(zdleq(d1,d2)&&!zdeqto(d1,d2)) p->val.vint=1;
  338.                      else p->val.vint=0;
  339.                 }
  340.                 if(f==GREATEREQ){
  341.                     if(!zdleq(d1,d2)||zdeqto(d1,d2)) p->val.vint=1;
  342.                      else p->val.vint=0;
  343.                 }
  344.             }else{
  345.                 if(t->flags&UNSIGNED){
  346.                     if(f==EQUAL) p->val.vint=zuleqto(u1,u2);
  347.                     if(f==INEQUAL) p->val.vint=!zuleqto(u1,u2);
  348.                     if(f==LESSEQ) p->val.vint=zulleq(u1,u2);
  349.                     if(f==GREATER) p->val.vint=!zulleq(u1,u2);
  350.                     if(f==LESS){
  351.                         if(zulleq(u1,u2)&&!zuleqto(u1,u2)) p->val.vint=1;
  352.                          else p->val.vint=0;
  353.                     }
  354.                     if(f==GREATEREQ){
  355.                         if(!zulleq(u1,u2)||zuleqto(u1,u2)) p->val.vint=1;
  356.                          else p->val.vint=0;
  357.                     }
  358.                 }else{
  359.                     if(f==EQUAL) p->val.vint=zleqto(s1,s2);
  360.                     if(f==INEQUAL) p->val.vint=!zleqto(s1,s2);
  361.                     if(f==LESSEQ) p->val.vint=zlleq(s1,s2);
  362.                     if(f==GREATER) p->val.vint=!zlleq(s1,s2);
  363.                     if(f==LESS){
  364.                         if(zlleq(s1,s2)&&!zleqto(s1,s2)) p->val.vint=1;
  365.                          else p->val.vint=0;
  366.                     }
  367.                     if(f==GREATEREQ){
  368.                         if(!zlleq(s1,s2)||zleqto(s1,s2)) p->val.vint=1;
  369.                          else p->val.vint=0;
  370.                     }
  371.                 }
  372.             }
  373.             freetyp(t);
  374.         }
  375.         return(ok);
  376.     }
  377.     if(f==ADD||f==SUB||f==MULT||f==DIV||f==MOD||f==LSHIFT||f==RSHIFT||f==PMULT){
  378.         if(!arith(p->left->ntyp->flags&15)||!arith(p->right->ntyp->flags&15)){
  379.             np new;zlong sz; int type=0;
  380.             if(f!=ADD&&f!=SUB){error(94);return(0);}
  381.             if((p->left->ntyp->flags&15)==POINTER){
  382.                 if((p->left->ntyp->next->flags&15)==VOID)
  383.                     {error(95);return(0);}
  384.                 if((p->right->ntyp->flags&15)==POINTER){
  385.                     if((p->right->ntyp->next->flags&15)==VOID)
  386.                         {error(95);return(0);}
  387.                     if(!compare_pointers(p->left->ntyp->next,p->right->ntyp->next,15))
  388.                         {error(41);}
  389.                     if(f!=SUB){error(96);return(0);}
  390.                      else {type=3;}
  391.                 }else{
  392.                     if((p->right->ntyp->flags&15)>LONG)
  393.                         {error(97,ename[f]);return(0);}
  394.                     if((p->right->ntyp->flags&15)<CHAR)
  395.                         {error(97,ename[f]);return(0);}
  396.                     if(p->right->flags!=PMULT&&p->right->flags!=PCEXPR){
  397.                         new=mymalloc(NODES);
  398.                         new->flags=PMULT;
  399.                         new->ntyp=0;
  400.                         new->left=p->right;
  401.                         new->right=mymalloc(NODES);
  402.                         new->right->flags=PCEXPR;
  403.                         new->right->left=new->right->right=0;
  404.                         new->right->ntyp=mymalloc(TYPS);
  405.                         new->right->ntyp->flags=INT;
  406.                         new->right->ntyp->next=0;
  407.                         sz=szof(p->left->ntyp->next);
  408.                         if(zleqto(l2zl(0L),sz)) error(78);
  409.                         new->right->val.vint=zl2zi(sz);
  410.                         p->right=new;
  411.                         ok&=type_expression2(p->right);
  412.                     }
  413.                     type=1;
  414.                 }
  415.             }else{
  416.                 np merk;
  417.                 if((p->right->ntyp->flags&15)!=POINTER)
  418.                     {error(98);return(0);}
  419.                 if((p->right->ntyp->next->flags&15)==VOID)
  420.                     {error(95);return(0);}
  421.                 if((p->left->ntyp->flags&15)>LONG)
  422.                     {error(98);return(0);}
  423.                 if((p->left->ntyp->flags&15)<CHAR)
  424.                     {error(98);return(0);}
  425.                 if(p->flags==SUB){error(99);return(0);}
  426.                 if(p->left->flags!=PMULT&&p->left->flags!=PCEXPR){
  427.                     new=mymalloc(NODES);
  428.                     new->flags=PMULT;
  429.                     new->ntyp=0;
  430.                     new->left=p->left;
  431.                     new->right=mymalloc(NODES);
  432.                     new->right->flags=PCEXPR;
  433.                     new->right->left=new->right->right=0;
  434.                     new->right->ntyp=mymalloc(TYPS);
  435.                     new->right->ntyp->flags=INT;
  436.                     new->right->ntyp->next=0;
  437.                     sz=szof(p->right->ntyp->next);
  438.                     if(zleqto(l2zl(0L),sz)) error(78);
  439.                     new->right->val.vint=zl2zi(sz);
  440.                     p->left=new;
  441.                     ok&=type_expression2(p->left);
  442.                 }
  443.                 type=2;
  444.                 merk=p->left;p->left=p->right;p->right=merk;
  445.             }
  446.             if(type==0){ierror(0);return(0);}
  447.             else{
  448.                 if(type==3){
  449.                     p->ntyp=mymalloc(TYPS);
  450.                     p->ntyp->next=0;p->ntyp->flags=INT;
  451.                 }else{
  452.                     /*if(type==1)*/ p->ntyp=clone_typ(p->left->ntyp);
  453.                     /* else       p->ntyp=clone_typ(p->right->ntyp);*/
  454.                     /*  Abfrage wegen Vertauschen der Knoten unnoetig   */
  455.                 }
  456.             }
  457.         }else{
  458.             p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  459.             if((p->ntyp->flags&15)>LONG&&(f==MOD||f==LSHIFT||f==RSHIFT))
  460.                 {error(101);ok=0;}
  461.             /*  Typerweiterungen fuer SHIFTS korrigieren    */
  462.             if((f==LSHIFT||f==RSHIFT)&&(p->ntyp->flags&15)==LONG&&(p->left->ntyp->flags&15)<LONG)
  463.                 {p->ntyp->flags&=~15;p->ntyp->flags|=INT;}
  464.         }
  465.         /*  fuegt &a+x zusammen, noch sub und left<->right machen   */
  466.         /*  Bei CEXPR statt PCEXPR auch machen?                     */
  467.         if((p->flags==ADD||p->flags==SUB)){
  468.             np m,c=0,a=0;
  469.             if(p->left->flags==PCEXPR&&p->flags==ADD) c=p->left;
  470.             if(p->right->flags==PCEXPR) c=p->right;
  471.             if(p->left->flags==ADDRESS||p->left->flags==ADDRESSA||p->left->flags==ADDRESSS) a=p->left;
  472.             if(p->right->flags==ADDRESS||p->right->flags==ADDRESSA||p->right->flags==ADDRESSS) a=p->right;
  473.             if(c&&a){
  474.                 m=a->left;
  475.                 /*  kann man das hier so machen oder muss man da mehr testen ?  */
  476.                 while(m->flags==FIRSTELEMENT||m->flags==ADDRESS||m->flags==ADDRESSA||m->flags==ADDRESSS) m=m->left;
  477.                 if(m->flags==IDENTIFIER){
  478.                     if(DEBUG&1) printf("&a+x with %s combined\n",ename[p->left->flags]);
  479.                     eval_const(&c->val,c->ntyp->flags);
  480.                     if(p->flags==ADD) m->val.vlong=zuladd(m->val.vlong,vlong);
  481.                      else m->val.vlong=zlsub(m->val.vlong,vlong);
  482.                     vlong=szof(m->ntyp);
  483.                     if(!zleqto(vlong,l2zl(0L))&&zulleq(vlong,m->val.vlong)){
  484.                         if(zuleqto(vlong,m->val.vlong))
  485.                             error(79);
  486.                         else
  487.                             error(80);
  488.                     }
  489.                     vlong=l2zl(0L);
  490.                     if(!zleqto(m->val.vlong,l2zl(0L))&&zulleq(m->val.vlong,vlong)) error(80);
  491.                     free_expression(c);
  492.                     if(p->ntyp) freetyp(p->ntyp);
  493.                     *p=*a;
  494.                     free(a);
  495.                     return(type_expression2(p));
  496.                 }
  497.             }
  498.         }
  499.         if(!mopt){
  500.             if(!alg_opt(p)) ierror(0);
  501.         }
  502.         return(ok);
  503.     }
  504.     if(f==CAST){
  505.         int from=p->left->ntyp->flags&15,to=p->ntyp->flags&15;
  506.         if(to==VOID) return(ok);
  507.         if(from==VOID)
  508.             {error(102);return(0);}
  509.         if((!arith(to)||!arith(from))&&
  510.            (to!=POINTER||from!=POINTER)){
  511.             if(to==POINTER){
  512.                 if(from<=LONG){
  513.                     if(!zlleq(sizetab[from],sizetab[POINTER])){
  514.                         error(103);return(0);
  515.                     }
  516.                 }else{
  517.                     error(104);return(0);
  518.                 }
  519.             }else{
  520.                 if(from!=POINTER)
  521.                     {error(105);return(0);}
  522.                 if(to<=LONG){
  523.                     if(!zlleq(sizetab[POINTER],sizetab[to])){
  524.                         error(106);return(0);
  525.                     }
  526.                 }else{
  527.                     error(104);return(0);
  528.                 }
  529.             }
  530.         }
  531.         if(from<=LONG&&to<=LONG&&!zlleq(sizetab[from],sizetab[to])&&p->left->flags!=CEXPR) error(166);
  532.         if(to==POINTER&&from==POINTER&&!zlleq(align[p->ntyp->next->flags&15],align[p->left->ntyp->next->flags&15]))
  533.             error(167);
  534.         if(p->left->flags==CEXPR){
  535.             eval_constn(p->left);
  536.             if((p->ntyp->flags&15)==POINTER)
  537.                 if(!zuleqto(vulong,ul2zul(0UL))||!zleqto(vlong,l2zl(0L))||!zdeqto(vdouble,d2zd(0.0)))
  538.                     error(81);
  539.             insert_const(p);
  540.             p->flags=CEXPR;
  541.             if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  542.         }
  543.         return(ok);
  544.     }
  545.     if(f==MINUS||f==KOMPLEMENT||f==NEGATION){
  546.         if(!arith(p->left->ntyp->flags&15)){
  547.             if(f!=NEGATION){error(107);return(0);
  548.             }else{
  549.                 if((p->left->ntyp->flags&15)!=POINTER)
  550.                     {error(108);return(0);}
  551.             }
  552.         }
  553.         if(f==KOMPLEMENT&&(p->left->ntyp->flags&15)>LONG)
  554.             {error(109);return(0);}
  555.         if(f==NEGATION){
  556.             p->ntyp=mymalloc(TYPS);
  557.             p->ntyp->next=0;
  558.             p->ntyp->flags=INT;
  559.         }else{
  560.             if(!p->left->ntyp) ierror(0);
  561.             p->ntyp=clone_typ(p->left->ntyp);
  562.             if((p->ntyp->flags&15)<=LONG) p->ntyp->flags=int_erw(p->ntyp->flags);
  563.         }
  564.         if(p->left->flags==CEXPR){
  565.             eval_constn(p->left);
  566.             if(f==KOMPLEMENT){vlong=zlkompl(vlong);vulong=zlkompl(vulong);
  567.                               vint=zl2zi(vlong);vuint=zul2zui(vulong);}
  568.             if(f==MINUS){vdouble=zdsub(d2zd(0.0),vdouble);vfloat=zd2zf(vdouble);
  569.                          vulong=zulsub(ul2zul(0UL),vulong);vuint=zul2zui(vulong);
  570.                          vlong=zlsub(l2zl(0L),vlong);vint=zl2zi(vlong);}
  571.             if(f==NEGATION){if(zdeqto(vdouble,d2zd(0.0))&&zuleqto(vulong,ul2zul(0UL))&&zleqto(vlong,l2zl(0L)))
  572.                 vlong=l2zl(1L); else vlong=l2zl(0L);
  573.                 vint=zl2zi(vlong);
  574.             }
  575.             insert_const(p);
  576.             p->flags=CEXPR;
  577.             if(!p->left->sidefx&&p->left) {free_expression(p->left);p->left=0;}
  578.         }
  579.         return(ok);
  580.     }
  581.     if(f==CONTENT){
  582.         if((p->left->ntyp->flags&15)!=POINTER)
  583.             {error(111);return(0);}
  584.         if((p->left->ntyp->next->flags&15)!=ARRAY&&type_uncomplete(p->left->ntyp->next))
  585.             {error(112);return(0);}
  586.         p->ntyp=clone_typ(p->left->ntyp->next);
  587.         if((p->ntyp->flags&15)!=ARRAY) p->lvalue=1;
  588.         if(p->left->flags==ADDRESS&&zuleqto(p->left->val.vulong,ul2zul(0UL))){
  589.         /*  *&x durch x ersetzen                                */
  590.             np merk;
  591.             merk=p->left;
  592.             if(p->ntyp) freetyp(p->ntyp);
  593.             if(p->left->ntyp) freetyp(p->left->ntyp);
  594.             *p=*p->left->left;
  595.             free(merk->left);
  596.             free(merk);
  597.             return(ok);
  598.         }
  599.         /*  *&ax durch firstelement-of(x) ersetzen  */
  600.         if(p->left->flags==ADDRESSA||p->left->flags==ADDRESSS){
  601.             np merk;
  602.             if(DEBUG&1) printf("substitutet * and %s with FIRSTELEMENT\n",ename[p->left->flags]);
  603.             p->flags=FIRSTELEMENT;
  604.             p->lvalue=1;    /*  evtl. hier erst Abfrage ?   */
  605.             merk=p->left;
  606.             p->left=merk->left;
  607.             p->right=merk->right;
  608.             if(merk->ntyp) freetyp(merk->ntyp);
  609.             free(merk);
  610.         }
  611.         return(ok);
  612.     }
  613.     if(f==FIRSTELEMENT){
  614. /*        if((p->left->ntyp->flags&15)!=ARRAY)
  615.             {ierror(0);return(0);}*/
  616.         if((p->left->ntyp->flags&15)==ARRAY) p->ntyp=clone_typ(p->left->ntyp->next);
  617.          else{
  618.             int i,n=-1;
  619.             for(i=0;i<p->left->ntyp->exact->count;i++)
  620.                 if(!strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)) n=i;
  621.             if(n<0){ierror(0);return(0);}
  622.             p->ntyp=clone_typ((*p->left->ntyp->exact->sl)[n].styp);
  623.         }
  624.         p->lvalue=1;    /*  hier noch genauer testen ?  */
  625.         return(ok);
  626.     }
  627.     if(f==ADDRESS){
  628.         if((p->left->ntyp->flags&15)!=FUNKT&&(p->left->ntyp->flags&15)!=ARRAY){
  629.             if(!p->left->lvalue){error(115);return(0);}
  630.             if(p->left->flags==IDENTIFIER){
  631.                 struct Var *v;
  632.                 v=find_var(p->left->identifier,0);
  633.                 if(!v){error(116,p->left->identifier);return(0);}
  634.                 if(v->storage_class==REGISTER)
  635.                     {error(117);return(0);}
  636.             }
  637.         }
  638.         p->ntyp=mymalloc(TYPS);
  639.         p->ntyp->flags=POINTER;
  640.         p->ntyp->next=clone_typ(p->left->ntyp);
  641.         return(ok);
  642.     }
  643.     if(f==ADDRESSA){
  644.         p->ntyp=clone_typ(p->left->ntyp);
  645.         p->ntyp->flags=POINTER;
  646.         return(ok);
  647.     }
  648.     if(f==ADDRESSS){
  649.         int i,n=-1;
  650.         for(i=0;i<p->left->ntyp->exact->count;i++)
  651.             if(!strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)) n=i;
  652.         if(n<0){ierror(0);return(0);}
  653.         p->ntyp=mymalloc(TYPS);
  654.         p->ntyp->flags=POINTER;
  655.         if(!p->left->ntyp) ierror(0);
  656.         if(!p->left->ntyp->exact) ierror(0);
  657.         if(!(*p->left->ntyp->exact->sl)[n].styp) ierror(0);
  658.         p->ntyp->next=clone_typ((*p->left->ntyp->exact->sl)[n].styp);
  659.         return(ok);
  660.     }
  661.     if(f==DSTRUCT){
  662.     /*  hier kann man bei unions einiges schneller/einfacher machen */
  663.         int i=0,f;struct Typ *t,*h;np new;zlong offset=l2zl(0L),al;
  664.         if((p->left->ntyp->flags&15)!=STRUCT&&(p->left->ntyp->flags&15)!=UNION)
  665.             {error(8);return(0);}
  666.         if(type_uncomplete(p->left->ntyp)){error(11);return(0);}
  667.         if(p->right->flags!=MEMBER)
  668.             {ierror(0);return(0);}
  669.         while(i<p->left->ntyp->exact->count&&strcmp((*p->left->ntyp->exact->sl)[i].identifier,p->right->identifier)){
  670.             t=(*p->left->ntyp->exact->sl)[i].styp;
  671.             h=t;
  672.             do{
  673.                 f=h->flags&15;
  674.                 h=h->next;
  675.             }while(f==ARRAY);
  676.             al=align[f];
  677.             offset=zlmult(zldiv(zladd(offset,zlsub(al,l2zl(1L))),al),al);
  678.             offset=zladd(offset,szof(t));
  679.             i++;
  680.         }
  681.         if(i>=p->left->ntyp->exact->count) {error(23,p->right->identifier);return(0);}
  682.  
  683.         t=(*p->left->ntyp->exact->sl)[i].styp;
  684.         h=t;
  685.         do{
  686.             f=h->flags&15;
  687.             h=h->next;
  688.         }while(f==ARRAY);
  689.         al=align[f];
  690.         offset=zlmult(zldiv(zladd(offset,zlsub(al,l2zl(1L))),al),al);
  691.         if((p->left->ntyp->flags&15)==UNION) offset=l2zl(0L);
  692.         p->flags=CONTENT;if(p->ntyp) {freetyp(p->ntyp);p->ntyp=0;}
  693.         new=mymalloc(NODES);
  694.         new->flags=ADD;
  695.         new->ntyp=0;
  696.         new->right=mymalloc(NODES);
  697.         new->right->left=new->right->right=0;
  698.         new->right->flags=PCEXPR;
  699.         new->right->ntyp=mymalloc(TYPS);
  700.         new->right->ntyp->flags=LONG;
  701.         new->right->ntyp->next=0;
  702.         new->right->val.vlong=offset;
  703.         new->left=mymalloc(NODES);
  704.         new->left->flags=ADDRESSS;
  705.         new->left->left=p->left;
  706.         new->left->right=p->right;
  707.         new->left->ntyp=0;
  708.         p->left=new;p->right=0;
  709.  
  710.         return(type_expression2(p));
  711.     }
  712.     if(f==PREINC||f==POSTINC||f==PREDEC||f==POSTDEC){
  713.         if(!p->left->lvalue){error(86);return(0);}
  714.         if(p->left->ntyp->flags&CONST){error(87);return(0);}
  715.         if(!arith(p->left->ntyp->flags&15)){
  716.             if((p->left->ntyp->flags&15)!=POINTER){
  717.                 error(24);return(0);
  718.             }else{
  719.                 if((p->left->ntyp->next->flags&15)==VOID)
  720.                     {error(95);return(0);}
  721.             }
  722.         }
  723.         p->ntyp=clone_typ(p->left->ntyp);
  724.         p->sidefx=1;
  725.         return(ok);
  726.     }
  727.     if(f==CALL){
  728.         struct argument_list *al;int i,flags=0;char *s=0;
  729.         struct struct_declaration *sd;
  730.         al=p->alist;
  731.         if((p->left->ntyp->flags&15)!=POINTER||(p->left->ntyp->next->flags&15)!=FUNKT)
  732.             {error(26);return(0);}
  733.         if(ok&&p->left->left&&p->left->left->flags==IDENTIFIER&&p->left->left->o.v->storage_class==EXTERN){
  734.             s=p->left->left->o.v->identifier;
  735.             flags=p->left->left->o.v->flags;
  736.         }
  737.         sd=p->left->ntyp->next->exact;
  738.         if(!sd){ierror(0);return(0);}
  739.         if(sd->count==0){
  740.             error(162);
  741.             if(s){
  742.                 if(!strcmp(s,"printf")||!strcmp(s,"fprintf")||!strcmp(s,"sprintf")||
  743.                    !strcmp(s,"scanf")|| !strcmp(s,"fscanf")|| !strcmp(s,"sscanf"))
  744.                     error(213);
  745.             }
  746.         }
  747.         while(al){
  748.             if(!al->arg) ierror(0);
  749.             if(!type_expression2(al->arg)) return(0);
  750.             al->arg=makepointer(al->arg);
  751.             if(type_uncomplete(al->arg->ntyp)) error(39);
  752.             al=al->next;
  753.         }
  754.         p->sidefx=1;
  755.         p->ntyp=clone_typ(p->left->ntyp->next->next);
  756.         i=0;al=p->alist;
  757.         while(al){
  758.             if(i>=sd->count) return(ok);
  759.             if(!(*sd->sl)[i].styp) return(ok); /* nur Bezeichner, aber kein Typ im Prototype */
  760.             if(!test_assignment((*sd->sl)[i].styp,al->arg)) return(0);
  761.             if(i==sd->count-1&&(flags&(PRINTFLIKE|SCANFLIKE))){
  762.                 if(al->arg->left&&al->arg->left->flags==STRING){
  763.                 /*  Argumente anhand des Formatstrings ueberpruefen */
  764.                     struct const_list *cl=(struct const_list *)al->arg->left->identifier;
  765.                     int fused=0;
  766.                     al=al->next;
  767.                     while(cl&&cl->other){
  768.                         int c,fflags=' ',at;
  769.                         struct Typ *t;
  770.                         c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  771.                         cl=cl->next;
  772.                         if(c==0){
  773.                             if(cl) error(215);
  774.                             break;
  775.                         }
  776.                         if(c!='%') continue;
  777.                         if(!cl){error(214);return(ok);}
  778.                         c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  779.                         cl=cl->next;
  780.                         while(isdigit((unsigned char)c)||
  781.                               c=='-'||c=='+'||c==' '||c=='#'||c=='.'||
  782.                               c=='h'||c=='l'||c=='L'||c=='*'){
  783.                             fused|=3;
  784.                             if(fflags!='*'&&(c=='h'||c=='l'||c=='L'||c=='*'))
  785.                                 fflags=c;
  786.                             c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  787.                             cl=cl->next;
  788.                             if(!cl){error(214);return(ok);}
  789.                         }
  790.                         if(DEBUG&1) printf("format=%c%c\n",fflags,c);
  791.                         if(c=='%') continue;
  792.                         if(fflags=='*') continue;
  793.                         if(!al){error(214);return(ok);}
  794.                         t=al->arg->ntyp;
  795.                         if(DEBUG&1){ prd(stdout,t);printf("\n");}
  796.                         if((flags&SCANFLIKE)){
  797.                             if((t->flags&15)!=POINTER){error(214);return(ok);}
  798.                             t=t->next;
  799.                         }
  800.                         at=t->flags&31;
  801.                         if(flags&PRINTFLIKE){
  802.                             switch(c){
  803.                             case 'o':
  804.                             case 'x':
  805.                             case 'X':
  806.                             case 'c':
  807.                                 at&=15;     /*  fall through    */
  808.                             case 'i':
  809.                             case 'd':
  810.                                 fused|=1;
  811.                                 if(at==LONG&&fflags!='l'){error(214);return(ok);}
  812.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  813.                                 if(at<CHAR||at>LONG){error(214);return(ok);}
  814.                                 break;
  815.                             case 'u':
  816.                                 fused=1;
  817.                                 if(al->arg->flags==CEXPR) at|=UNSIGNED;
  818.                                 if(at==(UNSIGNED|LONG)&&fflags!='l'){error(214);return(ok);}
  819.                                 if(fflags=='l'&&at!=(UNSIGNED|LONG)){error(214);return(ok);}
  820.                                 if(at<(UNSIGNED|CHAR)||at>(UNSIGNED|LONG)){error(214);return(ok);}
  821.                                 break;
  822.                             case 's':
  823.                                 fused|=1;
  824.                                 if(at!=POINTER||(t->next->flags&15)!=CHAR){error(214);return(ok);}
  825.                                 break;
  826.                             case 'f':
  827.                             case 'e':
  828.                             case 'E':
  829.                             case 'g':
  830.                             case 'G':
  831.                                 fused|=7;
  832.                                 if(at!=FLOAT&&at!=DOUBLE){error(214);return(ok);}
  833.                                 break;
  834.                             case 'p':
  835.                                 fused|=3;
  836.                                 if(at!=POINTER||(t->next->flags)!=VOID){error(214);return(ok);}
  837.                                 break;
  838.                             case 'n':
  839.                                 fused|=3;
  840.                                 if(at!=POINTER){error(214);return(ok);}
  841.                                 at=t->next->flags&31;
  842.                                 if(fflags=='h'&&at!=SHORT){error(214);return(ok);}
  843.                                 if(fflags==' '&&at!=INT){error(214);return(ok);}
  844.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  845.                                 break;
  846.                             default:
  847.                                 error(214);return(ok);
  848.                             }
  849.                         }else{
  850.                             switch(c){
  851.                             case '[':
  852.                                 fused|=3;
  853.                                 do{
  854.                                     c=(int)zul2zl(zuc2zul(cl->other->val.vchar));
  855.                                     cl=cl->next;
  856.                                     if(!cl){error(214);return(ok);}
  857.                                 }while(c!=']');     /*  fall through    */
  858.                             case 's':
  859.                             case 'c':
  860.                                 fused|=1;
  861.                                 if((at&15)!=CHAR){error(214);return(ok);}
  862.                                 break;
  863.                             case 'n':
  864.                                 fused|=3;       /*  fall through    */
  865.                             case 'd':
  866.                             case 'i':
  867.                             case 'o':
  868.                             case 'x':
  869.                                 fused|=1;
  870.                                 if(fflags=='h'&&at!=SHORT){error(214);return(ok);}
  871.                                 if(fflags==' '&&at!=INT){error(214);return(ok);}
  872.                                 if(fflags=='l'&&at!=LONG){error(214);return(ok);}
  873.                                 break;
  874.                             case 'u':
  875.                                 fused|=1;
  876.                                 if(fflags=='h'&&at!=(UNSIGNED|SHORT)){error(214);return(ok);}
  877.                                 if(fflags==' '&&at!=(UNSIGNED|INT)){error(214);return(ok);}
  878.                                 if(fflags=='l'&&at!=(UNSIGNED|LONG)){error(214);return(ok);}
  879.                                 break;
  880.                             case 'e':
  881.                             case 'f':
  882.                             case 'g':
  883.                                 fused|=7;
  884.                                 if(fflags==' '&&at!=FLOAT){error(214);return(ok);}
  885.                                 if(fflags=='l'&&at!=DOUBLE){error(214);return(ok);}
  886.                                 if(fflags=='L'&&at!=DOUBLE){error(214);return(ok);}
  887.                                 break;
  888.                             case 'p':
  889.                                 fused|=3;
  890.                                 if(at!=VOID){error(214);return(ok);}
  891.                                 break;
  892.                             default:
  893.                                 error(214);return(ok);
  894.                             }
  895.                         }
  896.                         al=al->next;
  897.                     }
  898.                     if(al){ error(214);return(ok);} /* zu viele */
  899.                     if(DEBUG&1) printf("fused=%d\n",fused);
  900.                     if(fused!=7&&s){
  901.                     /*  Wenn kein Format benutzt wird, kann man printf, */
  902.                     /*  scanf etc. durch aehnliches ersetzen.           */
  903.                         struct Var *v;char repl[MAXI+6]="__v";
  904.                         if(fused==3) fused=2;
  905.                         repl[3]=fused+'0';repl[4]=0;
  906.                         strcat(repl,s);
  907.                         if(DEBUG&1) printf("repl=%s\n",repl);
  908.                         while(fused<=2){
  909.                             v=find_var(repl,0);
  910.                             if(v&&v->storage_class==EXTERN){
  911.                                 p->left->left->o.v=v;
  912.                                 break;
  913.                             }
  914.                             fused++;repl[3]++;
  915.                         }
  916.                     }
  917.                     return(ok);
  918.                 }
  919.             }
  920.             i++;al=al->next;
  921.         }
  922.         if(i>=sd->count) return(ok);
  923.         if((*sd->sl)[i].styp&&((*sd->sl)[i].styp->flags&15)!=VOID){error(83);/*printf("sd->count=%d\n",sd->count);*/}
  924.         return(ok);
  925.     }
  926.     if(f==COND){
  927.         if(!arith(p->left->ntyp->flags&15)&&(p->left->ntyp->flags&15)!=POINTER){
  928.             error(29);
  929.             return(0);
  930.         }
  931.         if(p->left->flags==CEXPR&&!p->left->sidefx){
  932.             int null;np merk;
  933.             if(DEBUG&1) printf("constant conditional-expression simplified\n");
  934.             eval_constn(p->left);
  935.             if(zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))&&zdeqto(vdouble,d2zd(0.0))) null=1; else null=0;
  936.             free_expression(p->left);
  937.             merk=p->right;
  938.             if(null){
  939.                 free_expression(p->right->left);
  940.                 *p=*p->right->right;
  941.             }else{
  942.                 free_expression(p->right->right);
  943.                 *p=*p->right->left;
  944.             }
  945.             if(merk->ntyp) freetyp(merk->ntyp);
  946.             free(merk);
  947.             return(1);
  948.         }
  949.         p->ntyp=clone_typ(p->right->ntyp);
  950.         return(1);
  951.     }
  952.     if(f==COLON){
  953.         /*  Hier fehlt noch korrekte Behandlung der Typattribute    */
  954.         if(arith(p->left->ntyp->flags&15)&&arith(p->right->ntyp->flags&15)){
  955.             p->ntyp=arith_typ(p->left->ntyp,p->right->ntyp);
  956.             return(1);
  957.         }
  958.         if(compare_pointers(p->left->ntyp,p->right->ntyp,15)){
  959.             p->ntyp=clone_typ(p->left->ntyp);
  960.             return(1);
  961.         }
  962.         if((p->left->ntyp->flags&15)==POINTER&&(p->right->ntyp->flags&15)==POINTER){
  963.             if((p->left->ntyp->next->flags&15)==VOID){
  964.                 p->ntyp=clone_typ(p->left->ntyp);
  965.                 return(1);
  966.             }
  967.             if((p->right->ntyp->next->flags&15)==VOID){
  968.                 p->ntyp=clone_typ(p->right->ntyp);
  969.                 return(1);
  970.             }
  971.         }
  972.         if((p->left->ntyp->flags&15)==POINTER&&p->right->flags==CEXPR){
  973.             eval_constn(p->right);
  974.             if(zleqto(vlong,l2zl(0L))&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  975.                 p->ntyp=clone_typ(p->left->ntyp);
  976.                 return(1);
  977.             }
  978.         }
  979.         if((p->right->ntyp->flags&15)==POINTER&&p->left->flags==CEXPR){
  980.             eval_constn(p->left);
  981.             if(zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  982.                 p->ntyp=clone_typ(p->right->ntyp);
  983.                 return(1);
  984.             }
  985.         }
  986.         error(31);
  987.         return(0);
  988.     }
  989.     if(f) printf("type_testing fuer diesen Operator (%d) noch nicht implementiert\n",f);
  990.     return(0);
  991. }
  992.  
  993. np makepointer(np p)
  994. /*  Fuehrt automatische Zeigererzeugung fuer Baumwurzel durch   */
  995. /*  Durch mehrmaligen Aufruf von type_expression() ineffizient  */
  996. {
  997.     struct struct_declaration *sd;
  998.     if((p->ntyp->flags&15)==ARRAY||(p->ntyp->flags&15)==FUNKT){
  999.         np new=mymalloc(NODES);
  1000.         if((p->ntyp->flags&15)==ARRAY){
  1001.             new->flags=ADDRESSA;
  1002.             new->ntyp=clone_typ(p->ntyp);
  1003.             new->ntyp->flags=POINTER;
  1004. /*            new->ntyp=0;*/
  1005.         }else{
  1006.             new->flags=ADDRESS;
  1007.             new->ntyp=mymalloc(TYPS);
  1008.             new->ntyp->flags=POINTER;
  1009.             new->ntyp->next=clone_typ(p->ntyp);
  1010. /*            new->ntyp=0;*/
  1011.         }
  1012.         new->left=p;
  1013.         new->right=0;
  1014.         new->lvalue=0;  /* immer korrekt ?  */
  1015.         new->sidefx=p->sidefx;
  1016. /*        type_expression(new);*/
  1017.         return(new);
  1018.     }else return(p);
  1019. }
  1020. int alg_opt(np p)
  1021. /*  fuehrt algebraische Vereinfachungen durch                   */
  1022. /*  hier noch genau testen, was ANSI-gemaess erlaubt ist etc.   */
  1023. /*  v.a. Floating-Point ist evtl. kritisch                      */
  1024. {
  1025.     int c=0,f,komm,null1,null2,eins1,eins2;np merk;
  1026.     zdouble d1,d2;zulong u1,u2;zlong s1,s2;
  1027.     f=p->flags;
  1028.     /*  kommutativ? */
  1029.     if(f==ADD||f==MULT||f==PMULT||(f>=OR&&f<=AND)) komm=1; else komm=0;
  1030.     /*  Berechnet Wert, wenn beides Konstanten sind     */
  1031.     if(p->left->flags==CEXPR||p->left->flags==PCEXPR){
  1032.         eval_constn(p->left);
  1033.         d1=vdouble;u1=vulong;s1=vlong;c|=1;
  1034.     }
  1035.     if(p->right->flags==CEXPR||p->right->flags==PCEXPR){
  1036.         eval_constn(p->right);
  1037.         d2=vdouble;u2=vulong;s2=vlong;c|=2;
  1038.     }
  1039.     if(c==3){
  1040.         p->flags=CEXPR;
  1041.         if(DEBUG&1) printf("did simple constant folding\n");
  1042.         if(!p->left->sidefx) {free_expression(p->left);p->left=0;}
  1043.         if(!p->right->sidefx) {free_expression(p->right);p->right=0;}
  1044.         if(f==AND){
  1045.             vulong=zuland(u1,u2);
  1046.             vlong=zland(s1,s2);
  1047.         }
  1048.         if(f==OR){
  1049.             vulong=zulor(u1,u2);
  1050.             vlong=zlor(s1,s2);
  1051.         }
  1052.         if(f==XOR){
  1053.             vulong=zulxor(u1,u2);
  1054.             vlong=zlxor(s1,s2);
  1055.         }
  1056.         if(f==ADD){
  1057.             vulong=zuladd(u1,u2);
  1058.             vlong=zladd(s1,s2);
  1059.             vdouble=zdadd(d1,d2);
  1060.         }
  1061.         if(f==SUB){
  1062.             vulong=zulsub(u1,u2);
  1063.             vlong=zlsub(s1,s2);
  1064.             vdouble=zdsub(d1,d2);
  1065.         }
  1066.         if(f==MULT||f==PMULT){
  1067.             vulong=zulmult(u1,u2);
  1068.             vlong=zlmult(s1,s2);
  1069.             vdouble=zdmult(d1,d2);
  1070.             if(f==PMULT) p->flags=PCEXPR;
  1071.         }
  1072.         if(f==DIV){
  1073.             if(zleqto(l2zl(0L),s2)&&zuleqto(ul2zul(0UL),u2)&&zdeqto(d2zd(0.0),d2)){
  1074.                 error(84);
  1075.                 vlong=l2zl(0L);vulong=zl2zul(vlong);vdouble=zl2zd(vlong);
  1076.             }else{
  1077.                 if(!zuleqto(ul2zul(0UL),u2)) vulong=zuldiv(u1,u2);
  1078.                 if(!zleqto(l2zl(0L),s2)) vlong=zldiv(s1,s2);
  1079.                 if(!zdeqto(d2zd(0.0),d2)) vdouble=zddiv(d1,d2);
  1080.             }
  1081.         }
  1082.         if(f==MOD){
  1083.             if(zleqto(l2zl(0L),s2)&&zuleqto(ul2zul(0UL),u2)){
  1084.                 error(84);
  1085.                 vlong=l2zl(0L);vulong=zl2zul(vlong);
  1086.             }else{
  1087.                 if(!zuleqto(ul2zul(0UL),u2)) vulong=zulmod(u1,u2);
  1088.                 if(!zleqto(l2zl(0L),s2)) vlong=zlmod(s1,s2);
  1089.             }
  1090.         }
  1091.         if(f==LSHIFT){
  1092.             vulong=zullshift(u1,u2);
  1093.             vlong=zllshift(s1,s2);
  1094.         }
  1095.         if(f==RSHIFT){
  1096.             vulong=zulrshift(u1,u2);
  1097.             vlong=zlrshift(s1,s2);
  1098.         }
  1099.         vuint=zul2zui(vulong);vint=zl2zi(vlong);vfloat=zd2zf(vdouble);
  1100.         insert_const(p);
  1101.         return(1);
  1102.     }
  1103.     /*  Konstanten nach rechts, wenn moeglich       */
  1104.     if(c==1&&komm){
  1105.         if(DEBUG&1) printf("exchanged commutative constant operand\n");
  1106.         merk=p->left;p->left=p->right;p->right=merk;
  1107.         c=2;
  1108.         d2=d1;u2=u1;s2=s1;
  1109.     }
  1110.     /*  Vertauscht die Knoten, um Konstanten                */
  1111.     /*  besser zusammenzufassen (bei allen Type erlaubt?)   */
  1112.     /*  Hier muss noch einiges kontrolliert werden          */
  1113.     if(komm&&c==2&&p->flags==p->left->flags){
  1114.         if(p->left->right->flags==CEXPR||p->left->right->flags==PCEXPR){
  1115.             np merk;
  1116.             merk=p->right;p->right=p->left->left;p->left->left=merk;
  1117.             if(DEBUG&1) printf("Vertausche Add-Nodes\n");
  1118.             return(type_expression(p));
  1119.         }
  1120.     }
  1121.     if(zdeqto(d2zd(0.0),d1)&&zuleqto(ul2zul(0UL),u1)&&zleqto(l2zl(0L),s1)) null1=1; else null1=0;
  1122.     if(zdeqto(d2zd(0.0),d2)&&zuleqto(ul2zul(0UL),u2)&&zleqto(l2zl(0L),s2)) null2=1; else null2=0;
  1123.     eins1=eins2=0;
  1124.     vlong=l2zl(1L);vulong=zl2zul(vlong);vdouble=zl2zd(vlong);
  1125.     if(zdeqto(d1,vdouble)&&zuleqto(u1,vulong)&&zleqto(s1,vlong)) eins1=1;
  1126.     if(zdeqto(d2,vdouble)&&zuleqto(u2,vulong)&&zleqto(s2,vlong)) eins2=1;
  1127.     if(!(p->ntyp->flags&UNSIGNED)){
  1128.         vlong=l2zl(-1L);vdouble=zl2zd(vlong);
  1129.         if(zdeqto(d1,vdouble)&&zleqto(s1,vlong)) eins1=-1;
  1130.         if(zdeqto(d2,vdouble)&&zleqto(s2,vlong)) eins2=-1;
  1131.     }
  1132.     if(c==2){
  1133.         /*  a+0=a-0=a^0=a>>0=a<<0=a*1=a/1=a   */
  1134.         if(((eins2==1&&(f==MULT||f==PMULT||f==DIV))||(null2&&(f==ADD||f==SUB||f==OR||f==XOR||f==LSHIFT||f==RSHIFT)))&&!p->right->sidefx){
  1135.             if(DEBUG&1){if(f==MULT||f==PMULT||f==DIV) printf("a*/1->a\n"); else printf("a+-^0->a\n");}
  1136.             free_expression(p->right);
  1137.             merk=p->left;
  1138.             *p=*p->left;
  1139. /*            freetyp(merk->ntyp);  das war Fehler  */
  1140.             free(merk);
  1141.             return(type_expression(p));
  1142.         }
  1143.         /*  a*0=0   */
  1144.         if(null2&&(f==MULT||f==PMULT||f==AND||f==DIV||f==MOD)){
  1145.             if(DEBUG&1) printf("a*&/%%0->0\n");
  1146.             if(null2&&(f==DIV||f==MOD)) error(84);
  1147.             if(p->flags==PMULT) p->flags=PCEXPR; else p->flags=CEXPR;
  1148.             /*  hier nur int,long,float,double moeglich, hoffe ich  */
  1149.             vlong=l2zl(0L);vulong=zl2zul(vlong);
  1150.             vint=zl2zi(vlong);vuint=zul2zui(vulong);
  1151.             vdouble=zl2zd(vlong);vfloat=zd2zf(vdouble);
  1152.             insert_const(p);
  1153.             if(!p->left->sidefx){free_expression(p->left);p->left=0;} else make_cexpr(p->left);
  1154.             if(!p->right->sidefx){free_expression(p->right);p->right=0;} else make_cexpr(p->right);
  1155. /*            return(type_expression(p));   */
  1156.             return(1);
  1157.         }
  1158.         if(eins2==-1&&(f==MULT||f==PMULT||f==DIV)&&!p->right->sidefx){
  1159.             if(DEBUG&1) printf("a*/(-1)->-a\n");
  1160.             free_expression(p->right);
  1161.             p->right=0;
  1162.             p->flags=MINUS;
  1163.             return(type_expression(p));
  1164.         }
  1165.     }
  1166.     if(c==1){
  1167.         /*  0-a=-a  */
  1168.         if(((f==DIV&&eins1==-1)||(f==SUB&&null1))&&!p->left->sidefx){
  1169.             if(DEBUG&1){if(f==DIV) printf("-1/a->-a\n"); else printf("0-a->-a\n");}
  1170.             free_expression(p->left);
  1171.             p->flags=MINUS;
  1172.             p->left=p->right;
  1173.             p->right=0;
  1174.             return(type_expression(p));
  1175.         }
  1176.         /*  0/a=0   */
  1177.         if(null1&&(f==DIV||f==MOD||f==LSHIFT||f==RSHIFT)){
  1178.             if(DEBUG&1) printf("0/%%<<>>a->0\n");
  1179.             p->flags=CEXPR;
  1180.             /*  fier nur int,long,float,double moeglich, hoffe ich  */
  1181.             vlong=l2zl(0L);vulong=zl2zul(vlong);
  1182.             vint=zl2zi(vlong);vuint=zul2zui(vulong);
  1183.             vdouble=zl2zd(vlong);vfloat=zd2zf(vdouble);
  1184.             insert_const(p);
  1185.             if(!p->left->sidefx){free_expression(p->left);p->left=0;}else make_cexpr(p->left);
  1186.             if(!p->right->sidefx){free_expression(p->right);p->right=0;} else make_cexpr(p->right);
  1187.             return(type_expression(p));
  1188.         }
  1189.     }
  1190.     return(1);
  1191. }
  1192. void make_cexpr(np p)
  1193. /*  Macht aus einem Knoten, der durch constant-folding ueberfluessig    */
  1194. /*  wurde, eine PCEXPR, sofern er keine Nebenwirkungen von sich aus     */
  1195. /*  erzeugt. Hier noch ueberpruefen, ob CEXPR besser waere.             */
  1196. /*  Fuehrt rekursiven Abstieg durch. Ist das so korrekt?                */
  1197. {
  1198.     int f=p->flags;
  1199.     if(f!=ASSIGN&&f!=ASSIGNADD&&f!=CALL&&f!=POSTINC&&f!=POSTDEC&&f!=PREINC&&f!=PREDEC){
  1200.         p->flags=PCEXPR;
  1201.         if(p->left) make_cexpr(p->left);
  1202.         if(p->right) make_cexpr(p->right);
  1203.     }
  1204. }
  1205. int test_assignment(struct Typ *zt,np q)
  1206. /*  testet, ob q an Typ z zugewiesen werden darf    */
  1207. {
  1208.     struct Typ *qt=q->ntyp;
  1209.     if(arith(zt->flags&15)&&arith(qt->flags&15)){
  1210.         if((zt->flags&15)<=LONG&&(qt->flags&15)<=LONG&&
  1211.            !zlleq(sizetab[qt->flags&15],sizetab[zt->flags&15])&&q->flags!=CEXPR)
  1212.             error(166);
  1213.         return(1);
  1214.     }
  1215.     if(((zt->flags&15)==STRUCT&&(qt->flags&15)==STRUCT)||
  1216.        ((zt->flags&15)==UNION &&(qt->flags&15)==UNION )){
  1217.         if(!compare_pointers(zt,qt,255)){
  1218.             error(38);return(0);}
  1219.         else return(1);
  1220.     }
  1221.     if((zt->flags&15)==POINTER&&(qt->flags&15)==POINTER){
  1222.         if((zt->next->flags&15)==VOID&&(qt->next->flags&15)!=FUNKT) return(1);
  1223.         if((qt->next->flags&15)==VOID&&(qt->next->flags&15)!=FUNKT) return(1);
  1224.         if(!compare_pointers(zt->next,qt->next,(c_flags[7]&USEDFLAG)?31:15)){
  1225.             error(85);
  1226.         }else{
  1227.             if((qt->next->flags&CONST)&&!(zt->next->flags&CONST))
  1228.                 error(91);
  1229.             if((qt->next->flags&VOLATILE)&&!(zt->next->flags&VOLATILE))
  1230.                 error(100);
  1231.             if(qt->next->next&&zt->next->next&&!compare_pointers(zt->next->next,qt->next->next,255))
  1232.                 error(110);
  1233.         }
  1234.         return(1);
  1235.     }
  1236.     if((zt->flags&15)==POINTER&&q->flags==CEXPR){
  1237.         eval_constn(q);
  1238.         if(!(zdeqto(d2zd(0.0),vdouble)&&zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)))
  1239.             error(113);
  1240.         return(1);
  1241.     }
  1242.     error(39);return(0);
  1243. }
  1244.  
  1245.