浏览代码

* extract calculation of a NOT value to a separate function

git-svn-id: trunk@45050 -
svenbarth 5 年之前
父节点
当前提交
89434f0124
共有 2 个文件被更改,包括 59 次插入46 次删除
  1. 57 0
      compiler/defutil.pas
  2. 2 46
      compiler/nmat.pas

+ 57 - 0
compiler/defutil.pas

@@ -349,6 +349,10 @@ interface
         signdness, the result will also get that signdness }
         signdness, the result will also get that signdness }
     function get_common_intdef(ld, rd: torddef; keep_sign_if_equal: boolean): torddef;
     function get_common_intdef(ld, rd: torddef; keep_sign_if_equal: boolean): torddef;
 
 
+    { # calculates "not v" based on the provided def; returns true if the def
+        was negatable, false otherwise }
+    function calc_not_ordvalue(var v:Tconstexprint; var def:tdef):boolean;
+
     { # returns whether the type is potentially a valid type of/for an "univ" parameter
     { # returns whether the type is potentially a valid type of/for an "univ" parameter
         (basically: it must have a compile-time size) }
         (basically: it must have a compile-time size) }
     function is_valid_univ_para_type(def: tdef): boolean;
     function is_valid_univ_para_type(def: tdef): boolean;
@@ -1747,6 +1751,59 @@ implementation
       end;
       end;
 
 
 
 
+    function calc_not_ordvalue(var v:Tconstexprint;var def:tdef):boolean;
+      begin
+        if not assigned(def) or (def.typ<>orddef) then
+          exit(false);
+        result:=true;
+        case torddef(def).ordtype of
+          pasbool1,
+          pasbool8,
+          pasbool16,
+          pasbool32,
+          pasbool64:
+            v:=byte(not(boolean(int64(v))));
+          bool8bit,
+          bool16bit,
+          bool32bit,
+          bool64bit:
+            begin
+              if v=0 then
+                v:=-1
+              else
+                v:=0;
+            end;
+          uchar,
+          uwidechar,
+          u8bit,
+          s8bit,
+          u16bit,
+          s16bit,
+          s32bit,
+          u32bit,
+          s64bit,
+          u64bit:
+            begin
+              { unsigned, equal or bigger than the native int size? }
+              if (torddef(def).ordtype in [u64bit,u32bit,u16bit,u8bit,uchar,uwidechar]) and
+                 (is_nativeord(def) or is_oversizedord(def)) then
+                begin
+                  { Delphi-compatible: not dword = dword (not word = longint) }
+                  { Extension: not qword = qword                              }
+                  v:=qword(not qword(v));
+                  { will be truncated by the ordconstnode for u32bit }
+                end
+              else
+                begin
+                  v:=int64(not int64(v));
+                  def:=get_common_intdef(torddef(def),torddef(sinttype),false);
+                end;
+            end;
+          else
+            result:=false;
+        end;
+      end;
+
     function is_valid_univ_para_type(def: tdef): boolean;
     function is_valid_univ_para_type(def: tdef): boolean;
       begin
       begin
         result:=
         result:=

+ 2 - 46
compiler/nmat.pas

@@ -1176,52 +1176,8 @@ implementation
           begin
           begin
              v:=tordconstnode(left).value;
              v:=tordconstnode(left).value;
              def:=left.resultdef;
              def:=left.resultdef;
-             case torddef(left.resultdef).ordtype of
-               pasbool1,
-               pasbool8,
-               pasbool16,
-               pasbool32,
-               pasbool64:
-                 v:=byte(not(boolean(int64(v))));
-               bool8bit,
-               bool16bit,
-               bool32bit,
-               bool64bit:
-                 begin
-                   if v=0 then
-                     v:=-1
-                   else
-                     v:=0;
-                 end;
-               uchar,
-               uwidechar,
-               u8bit,
-               s8bit,
-               u16bit,
-               s16bit,
-               s32bit,
-               u32bit,
-               s64bit,
-               u64bit:
-                 begin
-                   { unsigned, equal or bigger than the native int size? }
-                   if (torddef(left.resultdef).ordtype in [u64bit,u32bit,u16bit,u8bit,uchar,uwidechar]) and
-                      (is_nativeord(left.resultdef) or is_oversizedord(left.resultdef)) then
-                     begin
-                       { Delphi-compatible: not dword = dword (not word = longint) }
-                       { Extension: not qword = qword                              }
-                       v:=qword(not qword(v));
-                       { will be truncated by the ordconstnode for u32bit }
-                     end
-                   else
-                     begin
-                       v:=int64(not int64(v));
-                       def:=get_common_intdef(torddef(left.resultdef),torddef(sinttype),false);
-                     end;
-                 end;
-               else
-                 CGMessage(type_e_mismatch);
-             end;
+             if not calc_not_ordvalue(v,def) then
+               CGMessage(type_e_mismatch);
              { not-nodes are not range checked by the code generator -> also
              { not-nodes are not range checked by the code generator -> also
                don't range check while inlining; the resultdef is a bit tricky
                don't range check while inlining; the resultdef is a bit tricky
                though: the node's resultdef gets changed in most cases compared
                though: the node's resultdef gets changed in most cases compared