Jelajahi Sumber

* better error message when no operator is found for equal

peter 22 tahun lalu
induk
melakukan
409bc6f4dc
2 mengubah file dengan 80 tambahan dan 13 penghapusan
  1. 32 12
      compiler/htypechk.pas
  2. 48 1
      compiler/symsym.pas

+ 32 - 12
compiler/htypechk.pas

@@ -442,18 +442,21 @@ implementation
      var
      var
          rd,ld   : tdef;
          rd,ld   : tdef;
          optoken : ttoken;
          optoken : ttoken;
+         operpd  : tprocdef;
          ht      : tnode;
          ht      : tnode;
       begin
       begin
         isbinaryoverloaded:=false;
         isbinaryoverloaded:=false;
-        { overloaded operator ? }
+        operpd:=nil;
         { load easier access variables }
         { load easier access variables }
         rd:=tbinarynode(t).right.resulttype.def;
         rd:=tbinarynode(t).right.resulttype.def;
         ld:=tbinarynode(t).left.resulttype.def;
         ld:=tbinarynode(t).left.resulttype.def;
         if isbinaryoperatoroverloadable(ld,rd,voidtype.def,t.nodetype) then
         if isbinaryoperatoroverloadable(ld,rd,voidtype.def,t.nodetype) then
           begin
           begin
              isbinaryoverloaded:=true;
              isbinaryoverloaded:=true;
-             {!!!!!!!!! handle paras }
              case t.nodetype of
              case t.nodetype of
+                equaln,
+                unequaln :
+                  optoken:=_EQUAL;
                 addn:
                 addn:
                   optoken:=_PLUS;
                   optoken:=_PLUS;
                 subn:
                 subn:
@@ -472,8 +475,6 @@ implementation
                   optoken:=_lte;
                   optoken:=_lte;
                 gten:
                 gten:
                   optoken:=_gte;
                   optoken:=_gte;
-                equaln,unequaln :
-                  optoken:=_EQUAL;
                 symdifn :
                 symdifn :
                   optoken:=_SYMDIF;
                   optoken:=_SYMDIF;
                 modn :
                 modn :
@@ -493,19 +494,35 @@ implementation
                 else
                 else
                   exit;
                   exit;
              end;
              end;
-             { the nil as symtable signs firstcalln that this is
-               an overloaded operator }
-             ht:=ccallnode.create(nil,overloaded_operators[optoken],nil,nil);
-             { we have to convert p^.left and p^.right into
-              callparanodes }
-             if tcallnode(ht).symtableprocentry=nil then
+             { check if the operator contains overloaded procdefs }
+             if overloaded_operators[optoken]=nil then
                begin
                begin
                   CGMessage(parser_e_operator_not_overloaded);
                   CGMessage(parser_e_operator_not_overloaded);
-                  ht.free;
                   isbinaryoverloaded:=false;
                   isbinaryoverloaded:=false;
                   exit;
                   exit;
                end;
                end;
+
+             { Check if the assignment is available, if not then
+               give a message that the types are not compatible }
+             if optoken in [_EQUAL] then
+              begin
+                operpd:=overloaded_operators[optoken].search_procdef_binary_operator(ld,rd);
+                if not assigned(operpd) then
+                 begin
+                   CGMessage2(type_e_incompatible_types,ld.typename,rd.typename);
+                   isbinaryoverloaded:=false;
+                   exit;
+                 end;
+               end;
+
+             { the nil as symtable signs firstcalln that this is
+               an overloaded operator }
+             ht:=ccallnode.create(nil,overloaded_operators[optoken],nil,nil);
              inc(tcallnode(ht).symtableprocentry.refs);
              inc(tcallnode(ht).symtableprocentry.refs);
+             { we already know the procdef to use for equal, so it can
+               skip the overload choosing in callnode.det_resulttype }
+             if assigned(operpd) then
+               tcallnode(ht).procdefinition:=operpd;
              { we need copies, because the originals will be destroyed when we give a }
              { we need copies, because the originals will be destroyed when we give a }
              { changed node back to firstpass! (JM)                                   }
              { changed node back to firstpass! (JM)                                   }
              if assigned(tbinarynode(t).left) then
              if assigned(tbinarynode(t).left) then
@@ -1111,7 +1128,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.52  2002-11-27 22:11:59  peter
+  Revision 1.53  2002-12-11 22:39:24  peter
+    * better error message when no operator is found for equal
+
+  Revision 1.52  2002/11/27 22:11:59  peter
     * rewrote isbinaryoverloadable to use a case. it's now much easier
     * rewrote isbinaryoverloadable to use a case. it's now much easier
       to understand what is happening
       to understand what is happening
 
 

+ 48 - 1
compiler/symsym.pas

@@ -144,6 +144,7 @@ interface
           function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
           function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
           function search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
           function search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
           function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
           function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
+          function search_procdef_binary_operator(def1,def2:tdef):Tprocdef;
           function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
           function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
 {$ifdef GDB}
 {$ifdef GDB}
           function stabstring : pchar;override;
           function stabstring : pchar;override;
@@ -1123,6 +1124,49 @@ implementation
       end;
       end;
 
 
 
 
+    function Tprocsym.search_procdef_binary_operator(def1,def2:tdef):Tprocdef;
+      var
+        convtyp : tconverttype;
+        pd : pprocdeflist;
+        bestpd : tprocdef;
+        eq1,eq2 : tequaltype;
+        eqlev,
+        bestlev : byte;
+        hpd : tprocdef;
+      begin
+        search_procdef_binary_operator:=nil;
+        bestpd:=nil;
+        bestlev:=0;
+        pd:=defs;
+        while assigned(pd) do
+          begin
+            eq1:=compare_defs_ext(def1,Tparaitem(pd^.def.para.first).paratype.def,
+                                 nothingn,false,false,convtyp,hpd);
+            if eq1<>te_incompatible then
+             begin
+               eq2:=compare_defs_ext(def1,Tparaitem(pd^.def.para.first).paratype.def,
+                                    nothingn,false,false,convtyp,hpd);
+               if eq2<>te_incompatible then
+                begin
+                  eqlev:=byte(eq1)+byte(eq2);
+                  if eqlev=(byte(te_exact)+byte(te_exact)) then
+                   begin
+                     search_procdef_binary_operator:=pd^.def;
+                     exit;
+                   end;
+                  if eqlev>bestlev then
+                   begin
+                     bestpd:=pd^.def;
+                     bestlev:=eqlev;
+                   end;
+                end;
+             end;
+            pd:=pd^.next;
+          end;
+        search_procdef_binary_operator:=bestpd;
+      end;
+
+
     procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
     procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
       var
       var
          p : pprocdeflist;
          p : pprocdeflist;
@@ -2460,7 +2504,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.81  2002-12-07 14:27:10  carl
+  Revision 1.82  2002-12-11 22:39:23  peter
+    * better error message when no operator is found for equal
+
+  Revision 1.81  2002/12/07 14:27:10  carl
     * 3% memory optimization
     * 3% memory optimization
     * changed some types
     * changed some types
     + added type checking with different size for call node and for
     + added type checking with different size for call node and for