浏览代码

compiler: implement IN operator which was known by compiler but was not supported. + test

git-svn-id: trunk@16622 -
paul 14 年之前
父节点
当前提交
d97cf8ed9d
共有 5 个文件被更改,包括 46 次插入8 次删除
  1. 1 0
      .gitattributes
  2. 3 1
      compiler/htypechk.pas
  3. 13 6
      compiler/nset.pas
  4. 1 1
      compiler/pdecsub.pas
  5. 28 0
      tests/test/toperator9.pp

+ 1 - 0
.gitattributes

@@ -9602,6 +9602,7 @@ tests/test/toperator5.pp svneol=native#text/plain
 tests/test/toperator6.pp svneol=native#text/plain
 tests/test/toperator7.pp svneol=native#text/plain
 tests/test/toperator8.pp svneol=native#text/pascal
+tests/test/toperator9.pp svneol=native#text/pascal
 tests/test/tover1.pp svneol=native#text/plain
 tests/test/tover2.pp svneol=native#text/plain
 tests/test/tover3.pp svneol=native#text/plain

+ 3 - 1
compiler/htypechk.pas

@@ -109,7 +109,7 @@ interface
         (tok:_SYMDIF    ;nod:symdifn;op_overloading_supported:true),   { binary overloading supported }
         (tok:_STARSTAR  ;nod:starstarn;op_overloading_supported:true), { binary overloading supported }
         (tok:_OP_AS     ;nod:asn;op_overloading_supported:false),      { binary overloading NOT supported }
-        (tok:_OP_IN     ;nod:inn;op_overloading_supported:false),      { binary overloading NOT supported }
+        (tok:_OP_IN     ;nod:inn;op_overloading_supported:true),       { binary overloading supported }
         (tok:_OP_IS     ;nod:isn;op_overloading_supported:false),      { binary overloading NOT supported }
         (tok:_OP_OR     ;nod:orn;op_overloading_supported:true),       { binary overloading supported }
         (tok:_OP_AND    ;nod:andn;op_overloading_supported:true),      { binary overloading supported }
@@ -685,6 +685,8 @@ implementation
              optoken:=_OP_SHL;
            shrn :
              optoken:=_OP_SHR;
+           inn :
+             optoken:=_OP_IN;
            else
              begin
                CGMessage(parser_e_operator_not_overloaded);

+ 13 - 6
compiler/nset.pas

@@ -229,12 +229,6 @@ implementation
              exit;
           end;
 
-         if right.resultdef.typ<>setdef then
-           CGMessage(sym_e_set_expected);
-
-         if codegenerror then
-           exit;
-
          if (right.nodetype=typen) then
            begin
              { we need to create a setconstn }
@@ -254,6 +248,19 @@ implementation
          if not assigned(left.resultdef) then
            internalerror(20021126);
 
+         t:=self;
+         if isbinaryoverloaded(t) then
+           begin
+              result:=t;
+              exit;
+           end;
+
+         if right.resultdef.typ<>setdef then
+           CGMessage(sym_e_set_expected);
+
+         if codegenerror then
+           exit;
+
          if (m_tp7 in current_settings.modeswitches) then
            begin
              { insert a hint that a range check error might occur on non-byte

+ 1 - 1
compiler/pdecsub.pas

@@ -1315,7 +1315,7 @@ implementation
                   else
                    begin
                      single_type(pd.returndef,false,false);
-                     if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE]) and
+                     if (optoken in [_EQ,_NE,_GT,_LT,_GTE,_LTE,_OP_IN]) and
                         ((pd.returndef.typ<>orddef) or
                          (torddef(pd.returndef).ordtype<>pasbool)) then
                         Message(parser_e_comparative_operator_return_boolean);

+ 28 - 0
tests/test/toperator9.pp

@@ -0,0 +1,28 @@
+program toperator9;
+
+// Check IN operator support
+
+{$mode objfpc}{$H+}
+{$apptype console}
+
+type
+  TFoo = record
+    F: Integer;
+  end;
+
+operator in(const I: Integer; const Foo: TFoo): Boolean;
+begin
+  Result := Foo.F = I;
+end;
+
+var
+  Foo: TFoo;
+begin
+  Foo.F := 1;
+  if not (1 in Foo) then
+    halt(1);
+  if 2 in Foo then
+    halt(2);
+  WriteLn('ok');
+end.
+