浏览代码

fcl-passrc: adapted pasresolveeval for pas2js

git-svn-id: trunk@39946 -
Mattias Gaertner 6 年之前
父节点
当前提交
a70f58f68e
共有 1 个文件被更改,包括 107 次插入36 次删除
  1. 107 36
      packages/fcl-passrc/src/pasresolveeval.pas

+ 107 - 36
packages/fcl-passrc/src/pasresolveeval.pas

@@ -352,13 +352,18 @@ type
     revkUInt, // TResEvalUInt
     revkFloat, // TResEvalFloat
     revkCurrency, // TResEvalCurrency
-    revkString, // TResEvalString
+    {$ifdef FPC_HAS_CPSTRING}
+    revkString, // TResEvalString  rawbytestring
+    {$endif}
     revkUnicodeString, // TResEvalUTF16
     revkEnum,     // TResEvalEnum
     revkRangeInt, // range of enum, int, char, widechar, e.g. 1..2
     revkRangeUInt, // range of uint, e.g. 1..2
     revkSetOfInt  // set of enum, int, char, widechar, e.g. [1,2..3]
     );
+const
+  revkAllStrings = [{$ifdef FPC_HAS_CPSTRING}revkString,{$endif}revkUnicodeString];
+type
   TResEvalValue = class(TResolveData)
   public
     Kind: TREVKind;
@@ -1419,10 +1424,13 @@ begin
         TResEvalEnum(LeftValue).Index,TResEvalEnum(RightValue).Index);
       exit;
       end;
-  revkString,revkUnicodeString:
+  {$ifdef FPC_HAS_CPSTRING}
+  revkString,
+  {$endif}
+  revkUnicodeString:
     begin
     LeftInt:=ExprStringToOrd(LeftValue,Expr.left);
-    if RightValue.Kind in [revkString,revkUnicodeString] then
+    if RightValue.Kind in revkAllStrings then
       begin
       RightInt:=ExprStringToOrd(RightValue,Expr.right);
       if LeftInt>RightInt then
@@ -1469,13 +1477,15 @@ var
   UInt: TMaxPrecUInt;
   Flo: TMaxPrecFloat;
   aCurrency: TMaxPrecCurrency;
+  {$ifdef FPC_HAS_CPSTRING}
   LeftCP, RightCP: TSystemCodePage;
+  {$endif}
   LeftSet, RightSet: TResEvalSet;
   i: Integer;
 begin
   Result:=nil;
   try
-    {$Q+}
+    {$Q+} // enable overflow and range checks
     {$R+}
     case LeftValue.Kind of
     revkInt:
@@ -1566,6 +1576,7 @@ begin
         RaiseNotYetImplemented(20180421163819,Expr);
       end;
       end;
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       case RightValue.Kind of
       revkString:
@@ -1596,14 +1607,17 @@ begin
         {$ENDIF}
         RaiseNotYetImplemented(20170601141834,Expr);
       end;
+    {$endif}
     revkUnicodeString:
       case RightValue.Kind of
+      {$ifdef FPC_HAS_CPSTRING}
       revkString:
         begin
         Result:=TResEvalUTF16.Create;
         TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S
                                 +GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
         end;
+      {$endif}
       revkUnicodeString:
         begin
         Result:=TResEvalUTF16.Create;
@@ -2807,6 +2821,7 @@ begin
         Result.Free;
         RaiseNotYetImplemented(20180421165438,Expr);
       end;
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       case RightValue.Kind of
       revkString:
@@ -2825,11 +2840,14 @@ begin
         Result.Free;
         RaiseNotYetImplemented(20170711175409,Expr);
       end;
+    {$endif}
     revkUnicodeString:
       case RightValue.Kind of
+      {$ifdef FPC_HAS_CPSTRING}
       revkString:
         TResEvalBool(Result).B:=TResEvalUTF16(LeftValue).S
                                =GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
+      {$endif}
       revkUnicodeString:
         TResEvalBool(Result).B:=TResEvalUTF16(LeftValue).S
                                =TResEvalUTF16(RightValue).S;
@@ -3128,6 +3146,7 @@ begin
         Result.Free;
         RaiseNotYetImplemented(20180421165752,Expr);
       end;
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       case RightValue.Kind of
       revkString:
@@ -3155,11 +3174,14 @@ begin
         Result.Free;
         RaiseNotYetImplemented(20170711175629,Expr);
       end;
+    {$endif}
     revkUnicodeString:
       case RightValue.Kind of
+      {$ifdef FPC_HAS_CPSTRING}
       revkString:
         CmpUnicode(TResEvalUTF16(LeftValue).S,
                    GetUnicodeStr(TResEvalString(RightValue).S,Expr.right));
+      {$endif}
       revkUnicodeString:
         CmpUnicode(TResEvalUTF16(LeftValue).S,TResEvalUTF16(RightValue).S);
       else
@@ -3264,12 +3286,14 @@ begin
         RaiseMsg(20170714123700,nRangeCheckError,sRangeCheckError,[],Expr)
       else
         Int:=TResEvalUInt(LeftValue).UInt;
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       if length(TResEvalString(LeftValue).S)<>1 then
         RaiseMsg(20170714124231,nXExpectedButYFound,sXExpectedButYFound,
           ['char','string'],Expr)
       else
         Int:=ord(TResEvalString(LeftValue).S[1]);
+    {$endif}
     revkUnicodeString:
       if length(TResEvalUTF16(LeftValue).S)<>1 then
         RaiseMsg(20170714124320,nXExpectedButYFound,sXExpectedButYFound,
@@ -3387,7 +3411,10 @@ begin
   IndexValue:=nil;
   try
     case ArrayValue.Kind of
-    revkString,revkUnicodeString:
+    {$ifdef FPC_HAS_CPSTRING}
+    revkString,
+    {$endif}
+    revkUnicodeString:
       begin
       // string[index]
       Param0:=Expr.Params[0];
@@ -3412,15 +3439,19 @@ begin
         {$ENDIF}
         RaiseNotYetImplemented(20170711182100,Expr);
       end;
+      {$ifdef FPC_HAS_CPSTRING}
       if ArrayValue.Kind=revkString then
         MaxIndex:=length(TResEvalString(ArrayValue).S)
       else
+      {$endif}
         MaxIndex:=length(TResEvalUTF16(ArrayValue).S);
       if (Int<1) or (Int>MaxIndex) then
         EmitRangeCheckConst(20170711183058,IntToStr(Int),'1',IntToStr(MaxIndex),Param0,mtError);
+      {$ifdef FPC_HAS_CPSTRING}
       if ArrayValue.Kind=revkString then
         Result:=TResEvalString.CreateValue(TResEvalString(ArrayValue).S[Int])
       else
+      {$endif}
         Result:=TResEvalUTF16.CreateValue(TResEvalUTF16(ArrayValue).S[Int]);
       exit;
       end;
@@ -3514,6 +3545,7 @@ begin
         RangeStart:=TResEvalUInt(Value).UInt;
         RangeEnd:=RangeStart;
         end;
+      {$ifdef FPC_HAS_CPSTRING}
       revkString:
         begin
         if Result.ElKind=revskNone then
@@ -3529,6 +3561,7 @@ begin
         RangeStart:=ord(TResEvalString(Value).S[1]);
         RangeEnd:=RangeStart;
         end;
+      {$endif}
       revkUnicodeString:
         begin
         if Result.ElKind=revskNone then
@@ -3837,9 +3870,12 @@ end;
 function TResExprEvaluator.ExprStringToOrd(Value: TResEvalValue;
   PosEl: TPasElement): longword;
 var
+  {$ifdef FPC_HAS_CPSTRING}
   S: RawByteString;
+  {$endif}
   U: UnicodeString;
 begin
+  {$ifdef FPC_HAS_CPSTRING}
   if Value.Kind=revkString then
     begin
     // ord(ansichar)
@@ -3850,7 +3886,9 @@ begin
     else
       Result:=ord(S[1]);
     end
-  else if Value.Kind=revkUnicodeString then
+  else
+  {$endif}
+  if Value.Kind=revkUnicodeString then
     begin
     // ord(widechar)
     U:=TResEvalUTF16(Value).S;
@@ -3884,15 +3922,18 @@ function TResExprEvaluator.EvalPrimitiveExprString(Expr: TPrimitiveExpr
 
   procedure Add(h: String);
   begin
+    {$ifdef FPC_HAS_CPSTRING}
     if Result.Kind=revkString then
       TResEvalString(Result).S:=TResEvalString(Result).S+h
     else
-      begin
       TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+GetUnicodeStr(h,Expr);
-      end;
+    {$else}
+    TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+h;
+    {$endif}
   end;
 
   procedure AddHash(u: longword);
+  {$ifdef FPC_HAS_CPSTRING}
   var
     h: RawByteString;
   begin
@@ -3909,9 +3950,14 @@ function TResExprEvaluator.EvalPrimitiveExprString(Expr: TPrimitiveExpr
     else
       TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+WideChar(u);
   end;
+  {$else}
+  begin
+    TResEvalUTF16(Result).S:=TResEvalUTF16(Result).S+WideChar(u);
+  end;
+  {$endif}
 
 var
-  p, StartP: PChar;
+  p, StartP, l: integer;
   c: Char;
   u: longword;
   S: String;
@@ -3921,29 +3967,36 @@ begin
   {$IFDEF VerbosePasResEval}
   //writeln('TResExprEvaluator.EvalPrimitiveExprString (',S,')');
   {$ENDIF}
-  if S='' then
+  l:=length(S);
+  if l=0 then
     RaiseInternalError(20170523113809);
+  {$ifdef FPC_HAS_CPSTRING}
   Result:=TResEvalString.Create;
-  p:=PChar(S);
-  repeat
-    case p^ of
+  {$else}
+  Result:=TResEvalUTF16.Create;
+  {$endif}
+  p:=1;
+  while p<=l do
+    case S[p] of
+    {$ifdef UsePChar}
     #0: break;
+    {$endif}
     '''':
       begin
       inc(p);
       StartP:=p;
       repeat
-        c:=p^;
-        case c of
-        #0:
+        if p>l then
           RaiseInternalError(20170523113938);
+        c:=S[p];
+        case c of
         '''':
           begin
           if p>StartP then
-            Add(copy(S,StartP-PChar(S)+1,p-StartP));
+            Add(copy(S,StartP,p-StartP));
           inc(p);
           StartP:=p;
-          if p^<>'''' then
+          if (p>l) or (S[p]<>'''') then
             break;
           Add('''');
           inc(p);
@@ -3954,21 +4007,23 @@ begin
         end;
       until false;
       if p>StartP then
-        Add(copy(S,StartP-PChar(S)+1,p-StartP));
+        Add(copy(S,StartP,p-StartP));
       end;
     '#':
       begin
       inc(p);
-      if p^='$' then
+      if p>l then
+        RaiseInternalError(20181016121354);
+      if S[p]='$' then
         begin
         // #$hexnumber
         inc(p);
         StartP:=p;
         u:=0;
-        repeat
-          c:=p^;
+        while p<=l do
+          begin
+          c:=S[p];
           case c of
-          #0: break;
           '0'..'9': u:=u*16+ord(c)-ord('0');
           'a'..'f': u:=u*16+ord(c)-ord('a')+10;
           'A'..'F': u:=u*16+ord(c)-ord('A')+10;
@@ -3977,7 +4032,7 @@ begin
           if u>$10FFFF then
             RangeError(20170523115712);
           inc(p);
-        until false;
+          end;
         if p=StartP then
           RaiseInternalError(20170207164956);
         if u>$ffff then
@@ -3995,17 +4050,17 @@ begin
         // #decimalnumber
         StartP:=p;
         u:=0;
-        repeat
-          c:=p^;
+        while p<=l do
+          begin
+          c:=S[p];
           case c of
-          #0: break;
           '0'..'9': u:=u*10+ord(c)-ord('0');
           else break;
           end;
           if u>$ffff then
             RangeError(20170523123137);
           inc(p);
-        until false;
+          end;
         if p=StartP then
           RaiseInternalError(20170523123806);
         AddHash(u);
@@ -4015,7 +4070,9 @@ begin
       begin
       // ^A is #1
       inc(p);
-      c:=p^;
+      if p>l then
+        RaiseInternalError(20181016121520);
+      c:=S[p];
       case c of
       'a'..'z': AddHash(ord(c)-ord('a')+1);
       'A'..'Z': AddHash(ord(c)-ord('A')+1);
@@ -4024,9 +4081,8 @@ begin
       inc(p);
       end;
     else
-      RaiseNotYetImplemented(20170523123815,Expr,'ord='+IntToStr(ord(p^)));
+      RaiseNotYetImplemented(20170523123815,Expr,'ord='+IntToStr(ord(S[p])));
     end;
-  until false;
   {$IFDEF VerbosePasResEval}
   //writeln('TResExprEvaluator.EvalPrimitiveExprString Result=',Result.AsString);
   {$ENDIF}
@@ -4044,7 +4100,9 @@ constructor TResExprEvaluator.Create;
 begin
   inherited Create;
   FAllowedInts:=ReitDefaults;
+  {$ifdef FPC_HAS_CPSTRING}
   FDefaultEncoding:=CP_ACP;
+  {$endif}
 end;
 
 function TResExprEvaluator.Eval(Expr: TPasExpr; Flags: TResEvalFlags
@@ -4253,7 +4311,7 @@ begin
           RaiseNotYetImplemented(20170522215906,ValueExpr);
           end;
       revskChar:
-        if Value.Kind in [revkString,revkUnicodeString] then
+        if Value.Kind in revkAllStrings then
           begin
           // string in char..char
           CharIndex:=ExprStringToOrd(Value,ValueExpr);
@@ -4450,10 +4508,12 @@ begin
         Int:=TResEvalInt(Value).Int;
       if (Int<0) or (Int>$ffff) then
         EmitRangeCheckConst(20170711195747,Value.AsString,0,$ffff,ErrorEl,mtError);
-      if Int>$ff then
-        Result:=TResEvalUTF16.CreateValue(WideChar(Int))
+      {$ifdef FPC_HAS_CPSTRING}
+      if Int<=$ff then
+        Result:=TResEvalString.CreateValue(chr(Int))
       else
-        Result:=TResEvalString.CreateValue(chr(Int));
+      {$endif}
+        Result:=TResEvalUTF16.CreateValue(WideChar(Int))
       end;
   else
     {$IFDEF VerbosePasResEval}
@@ -4474,11 +4534,13 @@ begin
         Result:=TResEvalInt.CreateValue(0);
     revkInt,revkUInt:
       Result:=Value;
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       if length(TResEvalString(Value).S)<>1 then
         RaiseRangeCheck(20170624160128,ErrorEl)
       else
         Result:=TResEvalInt.CreateValue(ord(TResEvalString(Value).S[1]));
+    {$endif}
     revkUnicodeString:
       if length(TResEvalUTF16(Value).S)<>1 then
         RaiseRangeCheck(20170624160129,ErrorEl)
@@ -4504,8 +4566,10 @@ begin
       PredInt(TResEvalInt(Value),ErrorEl);
     revkUInt:
       PredUInt(TResEvalUInt(Value),ErrorEl);
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       PredString(TResEvalString(Value),ErrorEl);
+    {$endif}
     revkUnicodeString:
       PredUnicodeString(TResEvalUTF16(Value),ErrorEl);
     revkEnum:
@@ -4529,8 +4593,10 @@ begin
       SuccInt(TResEvalInt(Value),ErrorEl);
     revkUInt:
       SuccUInt(TResEvalUInt(Value),ErrorEl);
+    {$ifdef FPC_HAS_CPSTRING}
     revkString:
       SuccString(TResEvalString(Value),ErrorEl);
+    {$endif}
     revkUnicodeString:
       SuccUnicodeString(TResEvalUTF16(Value),ErrorEl);
     revkEnum:
@@ -4639,7 +4705,7 @@ begin
         begin
         ValStr:=TResEvalEnum(Value).AsString;
         if Format1>0 then
-          ValStr:=Space(Format1)+ValStr;
+          ValStr:=StringOfChar(' ',Format1)+ValStr;
         end;
       else
         AllConst:=false;
@@ -4653,7 +4719,11 @@ begin
     S:=S+ValStr;
   end;
   if AllConst then
+    {$ifdef FPC_HAS_CPSTRING}
     Result:=TResEvalString.CreateValue(S);
+    {$else}
+    Result:=TResEvalUTF16.CreateValue(S);
+    {$endif}
 end;
 
 function TResExprEvaluator.EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
@@ -5545,6 +5615,7 @@ begin
     exit(l)
   else
     exit(m);
+  Result:=-1;
 end;
 
 function TResEvalSet.Intersects(aRangeStart, aRangeEnd: TMaxPrecInt): integer;