Browse Source

* Empty record constants

Michaël Van Canneyt 3 years ago
parent
commit
3271d1aac7

+ 57 - 47
packages/fcl-passrc/src/pparser.pp

@@ -2921,55 +2921,65 @@ begin
     else
       begin
       NextToken;
-      x:=DoParseConstValueExpression(AParent);
-      case CurToken of
-        tkComma: // array of values (a,b,c);
-          ReadArrayValues(x);
-
-        tkColon: // record field (a:xxx;b:yyy;c:zzz);
-          begin
-          if not (x is TPrimitiveExpr) then
-            CheckToken(tkBraceClose);
-          r:=nil;
-          try
-            n:=GetExprIdent(x);
-            r:=CreateRecordValues(AParent);
-            NextToken;
-            v:=DoParseConstValueExpression(r);
-            r.AddField(TPrimitiveExpr(x), v);
-            x:=nil;
-            if not lastfield then
-              repeat
-                n:=ExpectIdentifier;
-                x:=CreatePrimitiveExpr(r,pekIdent,n);
-                ExpectToken(tkColon);
-                NextToken;
-                v:=DoParseConstValueExpression(AParent);
-                r.AddField(TPrimitiveExpr(x), v);
-                x:=nil;
-              until lastfield; // CurToken<>tkSemicolon;
-            Result:=r;
-          finally
-            if Result=nil then
-              begin
-              r.Free;
-              x.Free;
-              end;
-          end;
-          end;
-      else
-        // Binary expression!  ((128 div sizeof(longint)) - 3);
-        Result:=DoParseExpression(AParent,x);
-        if CurToken<>tkBraceClose then
-          begin
-          ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
-          ParseExc(nParserExpectedCommaRBracket,SParserExpectedCommaRBracket);
-          end;
+      // Empty record constant: a: Record .. end = ();
+      if (CurToken=tkBraceClose) then
+        begin
+        Result:=CreateRecordValues(AParent);
         NextToken;
-        if CurToken <> tkSemicolon then // the continue of expression
-          Result:=DoParseExpression(AParent,Result);
         Exit;
-      end;
+        end
+      else
+        begin
+        x:=DoParseConstValueExpression(AParent);
+        case CurToken of
+          tkComma: // array of values (a,b,c);
+            ReadArrayValues(x);
+
+          tkColon: // record field (a:xxx;b:yyy;c:zzz);
+            begin
+            if not (x is TPrimitiveExpr) then
+              CheckToken(tkBraceClose);
+            r:=nil;
+            try
+              n:=GetExprIdent(x);
+              r:=CreateRecordValues(AParent);
+              NextToken;
+              v:=DoParseConstValueExpression(r);
+              r.AddField(TPrimitiveExpr(x), v);
+              x:=nil;
+              if not lastfield then
+                repeat
+                  n:=ExpectIdentifier;
+                  x:=CreatePrimitiveExpr(r,pekIdent,n);
+                  ExpectToken(tkColon);
+                  NextToken;
+                  v:=DoParseConstValueExpression(AParent);
+                  r.AddField(TPrimitiveExpr(x), v);
+                  x:=nil;
+                until lastfield; // CurToken<>tkSemicolon;
+              Result:=r;
+            finally
+              if Result=nil then
+                begin
+                r.Free;
+                x.Free;
+                end;
+            end;
+            end;
+        else
+          // Binary expression!  ((128 div sizeof(longint)) - 3);
+          Result:=DoParseExpression(AParent,x);
+          if CurToken<>tkBraceClose then
+            begin
+            ReleaseAndNil(TPasElement(Result){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
+            ParseExc(nParserExpectedCommaRBracket,SParserExpectedCommaRBracket);
+            end;
+          NextToken;
+          if CurToken <> tkSemicolon then // the continue of expression
+            Result:=DoParseExpression(AParent,Result);
+          Exit;
+        end;
+        end;
       end;
     if CurToken<>tkBraceClose then
       begin

+ 22 - 0
packages/fcl-passrc/tests/tconstparser.pas

@@ -78,6 +78,7 @@ Type
     Procedure TestTypedSetConst;
     Procedure TestTypedExprConst;
     Procedure TestRecordConst;
+    Procedure TestRecordConstEmpty;
     Procedure TestArrayConst;
     Procedure TestRangeConst;
     Procedure TestRangeConstUnTyped;
@@ -511,6 +512,27 @@ begin
   AssertExpression('Field 2 value',Fi.ValueExp,pekNumber,'2');
 end;
 
+procedure TTestConstParser.TestRecordConstEmpty;
+Var
+  R : TRecordValues;
+  Fi : TRecordValuesItem;
+begin
+  Typed := 'TPoint';
+  ParseConst('()');
+  AssertEquals('Record Values',TRecordValues,TheExpr.ClassType);
+  R:=TheExpr as TRecordValues;
+  AssertEquals('Expression list of ',pekListOfExp,TheExpr.Kind);
+  AssertEquals('0 elements',0,Length(R.Fields));
+(*
+FI:=R.Fields[0];
+  AssertEquals('Name field 1','x',Fi.Name);
+  AssertExpression('Field 1 value',Fi.ValueExp,pekNumber,'1');
+  FI:=R.Fields[1];
+  AssertEquals('Name field 2','y',Fi.Name);
+  AssertExpression('Field 2 value',Fi.ValueExp,pekNumber,'2');
+  *)
+end;
+
 procedure TTestConstParser.TestArrayConst;
 
 Var

+ 2 - 2
packages/fcl-passrc/tests/testpassrc.lpi

@@ -24,13 +24,13 @@
     </PublishOptions>
     <RunParams>
       <local>
-        <CommandLineParams Value="--suite=TTestVarParser.TestVarCVarExport"/>
+        <CommandLineParams Value="--suite=TTestConstParser.TestRecordConstEmpty"/>
       </local>
       <FormatVersion Value="2"/>
       <Modes Count="1">
         <Mode0 Name="default">
           <local>
-            <CommandLineParams Value="--suite=TTestVarParser.TestVarCVarExport"/>
+            <CommandLineParams Value="--suite=TTestConstParser.TestRecordConstEmpty"/>
           </local>
         </Mode0>
       </Modes>