Browse Source

fcl-passrc: resolver: assert()

git-svn-id: trunk@37984 -
Mattias Gaertner 7 years ago
parent
commit
8ae94b7a70
2 changed files with 94 additions and 34 deletions
  1. 43 2
      packages/fcl-passrc/src/pasresolver.pp
  2. 51 32
      packages/fcl-passrc/tests/tcresolver.pas

+ 43 - 2
packages/fcl-passrc/src/pasresolver.pp

@@ -414,7 +414,8 @@ type
     bfCopyArray,
     bfCopyArray,
     bfInsertArray,
     bfInsertArray,
     bfDeleteArray,
     bfDeleteArray,
-    bfTypeInfo
+    bfTypeInfo,
+    bfAssert
     );
     );
   TResolverBuiltInProcs = set of TResolverBuiltInProc;
   TResolverBuiltInProcs = set of TResolverBuiltInProc;
 const
 const
@@ -442,7 +443,8 @@ const
     'Copy',
     'Copy',
     'Insert',
     'Insert',
     'Delete',
     'Delete',
-    'TypeInfo'
+    'TypeInfo',
+    'Assert'
     );
     );
   bfAllStandardProcs = [Succ(bfCustom)..high(TResolverBuiltInProc)];
   bfAllStandardProcs = [Succ(bfCustom)..high(TResolverBuiltInProc)];
 
 
@@ -1275,6 +1277,8 @@ type
       Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
       Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
     procedure BI_TypeInfo_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
     procedure BI_TypeInfo_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
       {%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
       {%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
+    function BI_Assert_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
+      Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
   public
   public
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
@@ -10178,6 +10182,40 @@ begin
   SetResolverTypeExpr(ResolvedEl,btPointer,FBaseTypes[btPointer],[rrfReadable]);
   SetResolverTypeExpr(ResolvedEl,btPointer,FBaseTypes[btPointer],[rrfReadable]);
 end;
 end;
 
 
+function TPasResolver.BI_Assert_OnGetCallCompatibility(
+  Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
+// check params of built-in procedure 'Assert'
+//  Assert(bool)
+//  Assert(bool,string)
+var
+  Params: TParamsExpr;
+  Param: TPasExpr;
+  ParamResolved: TPasResolverResult;
+begin
+  if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
+    exit(cIncompatible);
+  Params:=TParamsExpr(Expr);
+
+  // first param: boolean
+  Param:=Params.Params[0];
+  ComputeElement(Param,ParamResolved,[]);
+  if not (rrfReadable in ParamResolved.Flags)
+     or not (ParamResolved.BaseType in btAllBooleans) then
+    exit(CheckRaiseTypeArgNo(20180117123819,1,Param,ParamResolved,'boolean',RaiseOnError));
+
+  // optional second parameter: string
+  if length(Params.Params)>1 then
+    begin
+    Param:=Params.Params[1];
+    ComputeElement(Param,ParamResolved,[]);
+    if not (rrfReadable in ParamResolved.Flags)
+       or not (ParamResolved.BaseType in btAllStringAndChars) then
+      exit(CheckRaiseTypeArgNo(20180117123932,2,Param,ParamResolved,'string',RaiseOnError));
+    end;
+
+  Result:=CheckBuiltInMaxParamCount(Proc,Params,2,RaiseOnError);
+end;
+
 constructor TPasResolver.Create;
 constructor TPasResolver.Create;
 begin
 begin
   inherited Create;
   inherited Create;
@@ -11139,6 +11177,9 @@ begin
     AddBuiltInProc('TypeInfo','function TypeInfo(type or var identifier): Pointer',
     AddBuiltInProc('TypeInfo','function TypeInfo(type or var identifier): Pointer',
         @BI_TypeInfo_OnGetCallCompatibility,@BI_TypeInfo_OnGetCallResult,
         @BI_TypeInfo_OnGetCallCompatibility,@BI_TypeInfo_OnGetCallResult,
         nil,nil,bfTypeInfo);
         nil,nil,bfTypeInfo);
+  if bfAssert in TheBaseProcs then
+    AddBuiltInProc('Assert','procedure Assert(bool[,string])',
+        @BI_Assert_OnGetCallCompatibility,nil,nil,nil,bfAssert,[bipfCanBeStatement]);
 end;
 end;
 
 
 function TPasResolver.AddBaseType(const aName: string; Typ: TResolverBaseType
 function TPasResolver.AddBaseType(const aName: string; Typ: TResolverBaseType

+ 51 - 32
packages/fcl-passrc/tests/tcresolver.pas

@@ -202,12 +202,15 @@ type
     Procedure TestConstIntOperators;
     Procedure TestConstIntOperators;
     Procedure TestConstBitwiseOps;
     Procedure TestConstBitwiseOps;
     Procedure TestIntegerTypeCast;
     Procedure TestIntegerTypeCast;
-    Procedure TestConstBoolOperators;
-    Procedure TestBoolTypeCast;
     Procedure TestConstFloatOperators;
     Procedure TestConstFloatOperators;
     Procedure TestFloatTypeCast;
     Procedure TestFloatTypeCast;
+
+    // boolean
+    Procedure TestBoolTypeCast;
+    Procedure TestConstBoolOperators;
     Procedure TestBoolSet_Const;
     Procedure TestBoolSet_Const;
     Procedure TestBool_ForIn;
     Procedure TestBool_ForIn;
+    Procedure TestBool_Assert;
 
 
     // integer range
     // integer range
     Procedure TestIntegerRange;
     Procedure TestIntegerRange;
@@ -2386,36 +2389,6 @@ begin
   CheckResolverUnexpectedHints;
   CheckResolverUnexpectedHints;
 end;
 end;
 
 
-procedure TTestResolver.TestConstBoolOperators;
-begin
-  StartProgram(false);
-  Add([
-  'const',
-  '  a=true and false;',
-  '  b=true or false;',
-  '  c=true xor false;',
-  '  d=not b;',
-  '  e=a=b;',
-  '  f=a<>b;',
-  '  g=low(boolean) or high(boolean);',
-  '  h=succ(false) or pred(true);',
-  '  i=ord(false)+ord(true);',
-  'begin']);
-  ParseProgram;
-  CheckResolverUnexpectedHints;
-end;
-
-procedure TTestResolver.TestBoolTypeCast;
-begin
-  StartProgram(false);
-  Add('var');
-  Add('  a: boolean = boolean(0);');
-  Add('  b: boolean = boolean(1);');
-  Add('begin');
-  ParseProgram;
-  CheckResolverUnexpectedHints;
-end;
-
 procedure TTestResolver.TestConstFloatOperators;
 procedure TTestResolver.TestConstFloatOperators;
 begin
 begin
   StartProgram(false);
   StartProgram(false);
@@ -2453,6 +2426,36 @@ begin
   CheckResolverUnexpectedHints;
   CheckResolverUnexpectedHints;
 end;
 end;
 
 
+procedure TTestResolver.TestBoolTypeCast;
+begin
+  StartProgram(false);
+  Add('var');
+  Add('  a: boolean = boolean(0);');
+  Add('  b: boolean = boolean(1);');
+  Add('begin');
+  ParseProgram;
+  CheckResolverUnexpectedHints;
+end;
+
+procedure TTestResolver.TestConstBoolOperators;
+begin
+  StartProgram(false);
+  Add([
+  'const',
+  '  a=true and false;',
+  '  b=true or false;',
+  '  c=true xor false;',
+  '  d=not b;',
+  '  e=a=b;',
+  '  f=a<>b;',
+  '  g=low(boolean) or high(boolean);',
+  '  h=succ(false) or pred(true);',
+  '  i=ord(false)+ord(true);',
+  'begin']);
+  ParseProgram;
+  CheckResolverUnexpectedHints;
+end;
+
 procedure TTestResolver.TestBoolSet_Const;
 procedure TTestResolver.TestBoolSet_Const;
 begin
 begin
   StartProgram(false);
   StartProgram(false);
@@ -2497,6 +2500,22 @@ begin
   ParseProgram;
   ParseProgram;
 end;
 end;
 
 
+procedure TTestResolver.TestBool_Assert;
+begin
+  StartProgram(false);
+  Add([
+  'var',
+  '  b : boolean;',
+  '  s: string;',
+  'begin',
+  '  Assert(true);',
+  '  Assert(b);',
+  '  Assert(b,''error'');',
+  '  Assert(false,''error''+s);',
+  '']);
+  ParseProgram;
+end;
+
 procedure TTestResolver.TestIntegerRange;
 procedure TTestResolver.TestIntegerRange;
 begin
 begin
   StartProgram(false);
   StartProgram(false);