Browse Source

compiler:
- parse operator return type the same way as we parse function return type - which pushing structures into the symtable and allowing self references,
- this change allows class operators to have return type = structure where they are defined
- extend test to check LogicalNot operator which can be finally compiled now

git-svn-id: trunk@16627 -

paul 14 years ago
parent
commit
8c8c1fc151
2 changed files with 85 additions and 47 deletions
  1. 50 42
      compiler/pdecsub.pas
  2. 35 5
      tests/test/terecs6.pp

+ 50 - 42
compiler/pdecsub.pas

@@ -1183,11 +1183,52 @@ implementation
       var
       var
         pd : tprocdef;
         pd : tprocdef;
         locationstr: string;
         locationstr: string;
-        old_parse_generic: boolean;
-        popclass: integer;
-        old_current_structdef: tabstractrecorddef;
-        old_current_genericdef,
-        old_current_specializedef: tobjectdef;
+
+        procedure read_returndef(pd: tprocdef);
+          var
+            popclass: integer;
+            old_parse_generic: boolean;
+            old_current_structdef: tabstractrecorddef;
+            old_current_genericdef,
+            old_current_specializedef: tobjectdef;
+          begin
+            old_parse_generic:=parse_generic;
+            inc(testcurobject);
+            { Add ObjectSymtable to be able to find generic type definitions }
+            popclass:=0;
+            if assigned(pd.struct) and
+               (pd.parast.symtablelevel=normal_function_level) and
+               not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
+              begin
+                popclass:=push_nested_hierarchy(pd.struct);
+                parse_generic:=(df_generic in pd.struct.defoptions);
+                old_current_structdef:=current_structdef;
+                old_current_genericdef:=current_genericdef;
+                old_current_specializedef:=current_specializedef;
+                current_structdef:=pd.struct;
+                if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
+                  current_genericdef:=tobjectdef(current_structdef);
+                if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
+                  current_specializedef:=tobjectdef(current_structdef);
+              end;
+            single_type(pd.returndef,false,false);
+
+            if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then
+              Message1(type_e_not_automatable,pd.returndef.typename);
+
+            if popclass>0 then
+              begin
+                current_structdef:=old_current_structdef;
+                current_genericdef:=old_current_genericdef;
+                current_specializedef:=old_current_specializedef;
+                dec(popclass,pop_nested_hierarchy(pd.struct));
+                if popclass<>0 then
+                  internalerror(201012020);
+              end;
+            dec(testcurobject);
+            parse_generic:=old_parse_generic;
+          end;
+
       begin
       begin
         locationstr:='';
         locationstr:='';
         pd:=nil;
         pd:=nil;
@@ -1202,42 +1243,7 @@ implementation
                     begin
                     begin
                       if try_to_consume(_COLON) then
                       if try_to_consume(_COLON) then
                        begin
                        begin
-                         old_parse_generic:=parse_generic;
-                         inc(testcurobject);
-                         { Add ObjectSymtable to be able to find generic type definitions }
-                         popclass:=0;
-                         if assigned(pd.struct) and
-                            (pd.parast.symtablelevel=normal_function_level) and
-                            not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
-                           begin
-                             popclass:=push_nested_hierarchy(pd.struct);
-                             parse_generic:=(df_generic in pd.struct.defoptions);
-                             old_current_structdef:=current_structdef;
-                             old_current_genericdef:=current_genericdef;
-                             old_current_specializedef:=current_specializedef;
-                             current_structdef:=pd.struct;
-                             if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
-                               current_genericdef:=tobjectdef(current_structdef);
-                             if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
-                               current_specializedef:=tobjectdef(current_structdef);
-                           end;
-                         single_type(pd.returndef,false,false);
-
-                         if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then
-                           Message1(type_e_not_automatable,pd.returndef.typename);
-
-                         if popclass>0 then
-                           begin
-                             current_structdef:=old_current_structdef;
-                             current_genericdef:=old_current_genericdef;
-                             current_specializedef:=old_current_specializedef;
-                             dec(popclass,pop_nested_hierarchy(pd.struct));
-                             if popclass<>0 then
-                               internalerror(201012020);
-                           end;
-                         dec(testcurobject);
-                         parse_generic:=old_parse_generic;
-
+                         read_returndef(pd);
                          if (target_info.system in [system_m68k_amiga]) then
                          if (target_info.system in [system_m68k_amiga]) then
                           begin
                           begin
                            if (idtoken=_LOCATION) then
                            if (idtoken=_LOCATION) then
@@ -1349,6 +1355,8 @@ implementation
                   include(pd.procoptions,po_overload);
                   include(pd.procoptions,po_overload);
                   if pd.parast.symtablelevel>normal_function_level then
                   if pd.parast.symtablelevel>normal_function_level then
                     Message(parser_e_no_local_operator);
                     Message(parser_e_no_local_operator);
+                  if isclassmethod then
+                    include(pd.procoptions,po_classmethod);
                   if token<>_ID then
                   if token<>_ID then
                     begin
                     begin
                        if not(m_result in current_settings.modeswitches) then
                        if not(m_result in current_settings.modeswitches) then
@@ -1367,7 +1375,7 @@ implementation
                     end
                     end
                   else
                   else
                    begin
                    begin
-                     single_type(pd.returndef,false,false);
+                     read_returndef(pd);
                      if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE,_OP_IN]) and
                      if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE,_OP_IN]) and
                         ((pd.returndef.typ<>orddef) or
                         ((pd.returndef.typ<>orddef) or
                          (torddef(pd.returndef).ordtype<>pasbool)) then
                          (torddef(pd.returndef).ordtype<>pasbool)) then

+ 35 - 5
tests/test/terecs6.pp

@@ -1,4 +1,4 @@
-program Project1;
+program terecs6;
 
 
 {$mode delphi}
 {$mode delphi}
 {$apptype console}
 {$apptype console}
@@ -26,10 +26,10 @@ type
     class operator LogicalOr(a, b: TFoo): Boolean;
     class operator LogicalOr(a, b: TFoo): Boolean;
     class operator LogicalAnd(a, b: TFoo): Boolean;
     class operator LogicalAnd(a, b: TFoo): Boolean;
     class operator LogicalXor(a, b: TFoo): Boolean;
     class operator LogicalXor(a, b: TFoo): Boolean;
-//    class operator LogicalNot(a: TFoo): TFoo;
-//    class operator BitwiseOr(a, b: TFoo): TFoo;
-//    class operator BitwiseAnd(a, b: TFoo): TFoo;
-//    class operator BitwiseXor(a, b: TFoo): TFoo;
+    class operator LogicalNot(a: TFoo): TFoo;
+    class operator BitwiseOr(a, b: TFoo): TFoo;
+    class operator BitwiseAnd(a, b: TFoo): TFoo;
+    class operator BitwiseXor(a, b: TFoo): TFoo;
 //    class operator Inc(a: TFoo): TFoo;
 //    class operator Inc(a: TFoo): TFoo;
 //    class operator Dec(a: TFoo): TFoo;
 //    class operator Dec(a: TFoo): TFoo;
  end;
  end;
@@ -124,6 +124,26 @@ begin
   Result := (a.F xor b.F) <> 0;
   Result := (a.F xor b.F) <> 0;
 end;
 end;
 
 
+class operator TFoo.LogicalNot(a: TFoo): TFoo;
+begin
+  Result.F := not a.F;
+end;
+
+class operator TFoo.BitwiseOr(a, b: TFoo): TFoo;
+begin
+  Result.F := a.F or b.F;
+end;
+
+class operator TFoo.BitwiseAnd(a, b: TFoo): TFoo;
+begin
+  Result.F := a.F and b.F;
+end;
+
+class operator TFoo.BitwiseXor(a, b: TFoo): TFoo;
+begin
+  Result.F := a.F xor b.F;
+end;
+
 var
 var
   a, b: TFoo;
   a, b: TFoo;
 begin
 begin
@@ -167,5 +187,15 @@ begin
     halt(18);
     halt(18);
   if not (a xor b) then
   if not (a xor b) then
     halt(19);
     halt(19);
+  if (not a).F <> (not 1) then
+    halt(20);
+{ bitwise operators current does not work if logical are defined
+  if (a or b).F <> (a.F or b.F) then
+    halt(21);
+  if (a and b).F <> (a.F and b.F) then
+    halt(22);
+  if (a xor b).F <> (a.F xor b.F) then
+    halt(23);
+}
   WriteLn('ok');
   WriteLn('ok');
 end.
 end.