Browse Source

* fix for overloading of shr shl mod and div

pierre 26 years ago
parent
commit
df71a1433b
2 changed files with 127 additions and 101 deletions
  1. 114 99
      compiler/tcadd.pas
  2. 13 2
      compiler/tcmat.pas

+ 114 - 99
compiler/tcadd.pas

@@ -27,6 +27,7 @@ interface
       tree;
       tree;
 
 
     procedure firstadd(var p : ptree);
     procedure firstadd(var p : ptree);
+    function isbinaryoverloaded(var p : ptree) : boolean;
 
 
 
 
 implementation
 implementation
@@ -39,6 +40,113 @@ implementation
       cpubase,tccnv
       cpubase,tccnv
       ;
       ;
 
 
+    function isbinaryoverloaded(var p : ptree) : boolean;
+
+     var
+         rd,ld   : pdef;
+         t : ptree;
+         optoken : ttoken;
+
+      begin
+        isbinaryoverloaded:=false;
+        { overloaded operator ? }
+        { load easier access variables }
+        rd:=p^.right^.resulttype;
+        ld:=p^.left^.resulttype;
+        if (p^.treetype=starstarn) or
+           (ld^.deftype=recorddef) or
+           ((ld^.deftype=arraydef) and
+             not((cs_mmx in aktlocalswitches) and
+             is_mmx_able_array(ld)) and
+            (not (rd^.deftype in [orddef])) and
+            (not is_chararray(ld))
+           ) or
+           { <> and = are defined for classes }
+           ((ld^.deftype=objectdef) and
+            (not(pobjectdef(ld)^.is_class) or
+             not(p^.treetype in [equaln,unequaln])
+            )
+           ) or
+           (rd^.deftype=recorddef) or
+           ((rd^.deftype=arraydef) and
+             not((cs_mmx in aktlocalswitches) and
+             is_mmx_able_array(rd)) and
+            (not (ld^.deftype in [orddef])) and
+            (not is_chararray(rd))
+           ) or
+           { <> and = are defined for classes }
+           ((rd^.deftype=objectdef) and
+            (not(pobjectdef(rd)^.is_class) or
+             not(p^.treetype in [equaln,unequaln])
+            )
+           ) then
+          begin
+             isbinaryoverloaded:=true;
+             {!!!!!!!!! handle paras }
+             case p^.treetype of
+                { the nil as symtable signs firstcalln that this is
+                  an overloaded operator }
+                addn:
+                  optoken:=_PLUS;
+                subn:
+                  optoken:=_MINUS;
+                muln:
+                  optoken:=_STAR;
+                starstarn:
+                  optoken:=_STARSTAR;
+                slashn:
+                  optoken:=_SLASH;
+                ltn:
+                  optoken:=tokens._lt;
+                gtn:
+                  optoken:=tokens._gt;
+                lten:
+                  optoken:=_lte;
+                gten:
+                  optoken:=_gte;
+                equaln,unequaln :
+                  optoken:=_EQUAL;
+                symdifn :
+                  optoken:=_SYMDIF;
+                modn :
+                  optoken:=_OP_MOD;
+                orn :
+                  optoken:=_OP_OR;
+                xorn :
+                  optoken:=_OP_XOR;
+                andn :
+                  optoken:=_OP_AND;
+                divn :
+                  optoken:=_OP_DIV;
+                shln :
+                  optoken:=_OP_SHL;
+                shrn :
+                  optoken:=_OP_SHR;
+                else
+                  exit;
+             end;
+             t:=gencallnode(overloaded_operators[optoken],nil);
+             { we have to convert p^.left and p^.right into
+              callparanodes }
+             if t^.symtableprocentry=nil then
+               begin
+                  CGMessage(parser_e_operator_not_overloaded);
+                  putnode(t);
+               end
+             else
+               begin
+                  inc(t^.symtableprocentry^.refs);
+                  t^.left:=gencallparanode(p^.left,nil);
+                  t^.left:=gencallparanode(p^.right,t^.left);
+                  if p^.treetype=unequaln then
+                   t:=gensinglenode(notn,t);
+                  firstpass(t);
+                  putnode(p);
+                  p:=t;
+               end;
+          end;
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                                 FirstAdd
                                 FirstAdd
 *****************************************************************************}
 *****************************************************************************}
@@ -79,15 +187,10 @@ implementation
          resultset : pconstset;
          resultset : pconstset;
          i : longint;
          i : longint;
          b : boolean;
          b : boolean;
-         optoken : ttoken;
          convdone : boolean;
          convdone : boolean;
          s1,s2 : pchar;
          s1,s2 : pchar;
          l1,l2 : longint;
          l1,l2 : longint;
 
 
-         { this totally forgets to set the pi_do_call flag !! }
-      label
-         no_overload;
-
       begin
       begin
          { first do the two subtrees }
          { first do the two subtrees }
          firstpass(p^.left);
          firstpass(p^.left);
@@ -113,99 +216,8 @@ implementation
          ld:=p^.left^.resulttype;
          ld:=p^.left^.resulttype;
          convdone:=false;
          convdone:=false;
 
 
-         { overloaded operator ? }
-         if (p^.treetype=starstarn) or
-            (ld^.deftype=recorddef) or
-            ((ld^.deftype=arraydef) and
-              not((cs_mmx in aktlocalswitches) and
-              is_mmx_able_array(ld)) and
-             (not (rd^.deftype in [orddef])) and
-             (not is_chararray(ld))
-            ) or
-            { <> and = are defined for classes }
-            ((ld^.deftype=objectdef) and
-             (not(pobjectdef(ld)^.is_class) or
-              not(p^.treetype in [equaln,unequaln])
-             )
-            ) or
-            (rd^.deftype=recorddef) or
-            ((rd^.deftype=arraydef) and
-              not((cs_mmx in aktlocalswitches) and
-              is_mmx_able_array(rd)) and
-             (not (ld^.deftype in [orddef])) and
-             (not is_chararray(rd))
-            ) or
-            { <> and = are defined for classes }
-            ((rd^.deftype=objectdef) and
-             (not(pobjectdef(rd)^.is_class) or
-              not(p^.treetype in [equaln,unequaln])
-             )
-            ) then
-           begin
-              {!!!!!!!!! handle paras }
-              case p^.treetype of
-                 { the nil as symtable signs firstcalln that this is
-                   an overloaded operator }
-                 addn:
-                   optoken:=_PLUS;
-                 subn:
-                   optoken:=_MINUS;
-                 muln:
-                   optoken:=_STAR;
-                 starstarn:
-                   optoken:=_STARSTAR;
-                 slashn:
-                   optoken:=_SLASH;
-                 ltn:
-                   optoken:=tokens._lt;
-                 gtn:
-                   optoken:=tokens._gt;
-                 lten:
-                   optoken:=_lte;
-                 gten:
-                   optoken:=_gte;
-                 equaln,unequaln :
-                   optoken:=_EQUAL;
-                 symdifn :
-                   optoken:=_SYMDIF;
-                 modn :
-                   optoken:=_OP_MOD;
-                 orn :
-                   optoken:=_OP_OR;
-                 xorn :
-                   optoken:=_OP_XOR;
-                 andn :
-                   optoken:=_OP_AND;
-                 divn :
-                   optoken:=_OP_DIV;
-                 shln :
-                   optoken:=_OP_SHL;
-                 shrn :
-                   optoken:=_OP_SHR;
-                 else goto no_overload;
-              end;
-              t:=gencallnode(overloaded_operators[optoken],nil);
-              { we have to convert p^.left and p^.right into
-               callparanodes }
-              if t^.symtableprocentry=nil then
-                begin
-                   CGMessage(parser_e_operator_not_overloaded);
-                   putnode(t);
-                end
-              else
-                begin
-                   inc(t^.symtableprocentry^.refs);
-                   t^.left:=gencallparanode(p^.left,nil);
-                   t^.left:=gencallparanode(p^.right,t^.left);
-                   if p^.treetype=unequaln then
-                    t:=gensinglenode(notn,t);
-                   firstpass(t);
-                   putnode(p);
-                   p:=t;
-                   exit;
-                end;
-           end;
-         no_overload:
+         if isbinaryoverloaded(p) then
+           exit;
          { compact consts }
          { compact consts }
 
 
          { convert int consts to real consts, if the }
          { convert int consts to real consts, if the }
@@ -1175,7 +1187,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.56  1999-11-18 15:34:48  pierre
+  Revision 1.57  1999-11-26 13:51:29  pierre
+   * fix for overloading of shr shl mod and div
+
+  Revision 1.56  1999/11/18 15:34:48  pierre
     * Notes/Hints for local syms changed to
     * Notes/Hints for local syms changed to
       Set_varstate function
       Set_varstate function
 
 

+ 13 - 2
compiler/tcmat.pas

@@ -38,7 +38,9 @@ implementation
       globtype,systems,tokens,
       globtype,systems,tokens,
       cobjects,verbose,globals,
       cobjects,verbose,globals,
       symconst,symtable,aasm,types,
       symconst,symtable,aasm,types,
-      hcodegen,htypechk,pass_1,cpubase;
+      hcodegen,htypechk,pass_1,cpubase,
+      { for isbinaryoverloaded function }
+      tcadd;
 
 
 {*****************************************************************************
 {*****************************************************************************
                              FirstModDiv
                              FirstModDiv
@@ -58,6 +60,9 @@ implementation
          if codegenerror then
          if codegenerror then
            exit;
            exit;
 
 
+         if isbinaryoverloaded(p) then
+           exit;
+
          { check for division by zero }
          { check for division by zero }
          rv:=p^.right^.value;
          rv:=p^.right^.value;
          lv:=p^.left^.value;
          lv:=p^.left^.value;
@@ -158,6 +163,9 @@ implementation
          if codegenerror then
          if codegenerror then
            exit;
            exit;
 
 
+         if isbinaryoverloaded(p) then
+           exit;
+
          if is_constintnode(p^.left) and is_constintnode(p^.right) then
          if is_constintnode(p^.left) and is_constintnode(p^.right) then
            begin
            begin
               case p^.treetype of
               case p^.treetype of
@@ -414,7 +422,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.23  1999-11-18 15:34:50  pierre
+  Revision 1.24  1999-11-26 13:51:29  pierre
+   * fix for overloading of shr shl mod and div
+
+  Revision 1.23  1999/11/18 15:34:50  pierre
     * Notes/Hints for local syms changed to
     * Notes/Hints for local syms changed to
       Set_varstate function
       Set_varstate function