From f67002c1a9e7635db299676f17562b4ec84782ec Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Thu, 10 Feb 2022 23:31:55 +0700 Subject: [PATCH] (#72) Parser: support basic struct parsing --- Cesium.Ast/Declarations.cs | 28 +++++- Cesium.CodeGen/Ir/DeclarationInfo.cs | 2 +- Cesium.CodeGen/Ir/ParametersInfo.cs | 2 +- ...larationParserTests.CliImport.verified.txt | 2 +- ...ts.InitializerDeclarationTest.verified.txt | 2 +- ...nParserTests.MultiDeclaration.verified.txt | 2 +- ...Tests.AnonymousArrayParameter.verified.txt | 4 +- ...erTests.ArrayOfArrayParameter.verified.txt | 4 +- ...ullParserTests.ArrayParameter.verified.txt | 4 +- .../FullParserTests.CharLiteral.verified.txt | 6 +- .../FullParserTests.CliImport.verified.txt | 6 +- ...ullParserTests.ExpressionTest.verified.txt | 2 +- ...lParserTests.FunctionCallTest.verified.txt | 6 +- .../FullParserTests.IntParameter.verified.txt | 4 +- ...FullParserTests.MainSignature.verified.txt | 6 +- ...arserTests.MinimalProgramTest.verified.txt | 2 +- .../FullParserTests.NegationTest.verified.txt | 4 +- ...erTests.PointerArrayParameter.verified.txt | 4 +- ...lParserTests.PointerParameter.verified.txt | 4 +- ...rserTests.PrefixIncrementTest.verified.txt | 4 +- .../FullParserTests.ReturnTest.verified.txt | 2 +- ...rTests.SimpleStructDefinition.verified.txt | 62 ++++++++++++ ...arserTests.SimpleVariableTest.verified.txt | 4 +- ...FullParserTests.StringLiteral.verified.txt | 2 +- ...ullParserTests.StringVariable.verified.txt | 4 +- ...rTests.VariableArithmeticTest.verified.txt | 4 +- .../FullParserTests.VariableTest.verified.txt | 4 +- .../ParserTests/FullParserTests.cs | 4 +- ...CompoundStatementWithVariable.verified.txt | 2 +- Cesium.Parser/CParser.cs | 95 ++++++++++++++++--- Cesium.Test.Framework/ParserTestBase.cs | 3 +- 31 files changed, 223 insertions(+), 61 deletions(-) create mode 100644 Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleStructDefinition.verified.txt diff --git a/Cesium.Ast/Declarations.cs b/Cesium.Ast/Declarations.cs index b1f7e5ed..72e60062 100644 --- a/Cesium.Ast/Declarations.cs +++ b/Cesium.Ast/Declarations.cs @@ -10,11 +10,35 @@ public record Declaration( public record InitDeclarator(Declarator Declarator, Initializer? Initializer = null); public interface IDeclarationSpecifier { } + +// 6.7.1 Storage-class specifiers +public record StorageClassSpecifier(string Name) : IDeclarationSpecifier; + // 6.7.2 Type specifiers -public record TypeSpecifier(string TypeName) : IDeclarationSpecifier; +public interface ITypeSpecifier : ISpecifierQualifierListItem, IDeclarationSpecifier { } + +public record SimpleTypeSpecifier(string TypeName) : ITypeSpecifier; +public record StructOrUnionSpecifier( + ComplexTypeKind TypeKind, + string? Identifier, + ImmutableArray StructDeclarations) : ITypeSpecifier; + +// 6.7.2.1 Structure and union specifiers +public enum ComplexTypeKind +{ + Struct +} + +public record StructDeclaration( + ImmutableArray SpecifiersQualifiers, + ImmutableArray? Declarators); + +public interface ISpecifierQualifierListItem {} + +public record StructDeclarator(Declarator Declarator); // 6.7.3 Type qualifiers -public record TypeQualifier(string Name) : IDeclarationSpecifier; +public record TypeQualifier(string Name) : IDeclarationSpecifier, ISpecifierQualifierListItem; // 6.7.7 Type names public record AbstractDeclarator(Pointer? Pointer = null, IDirectAbstractDeclarator? DirectAbstractDeclarator = null); diff --git a/Cesium.CodeGen/Ir/DeclarationInfo.cs b/Cesium.CodeGen/Ir/DeclarationInfo.cs index 43b0f853..4ca798b1 100644 --- a/Cesium.CodeGen/Ir/DeclarationInfo.cs +++ b/Cesium.CodeGen/Ir/DeclarationInfo.cs @@ -89,7 +89,7 @@ private static (IType, string? cliImportMemberName) GetPrimitiveInfo( { switch (specifier) { - case TypeSpecifier ts: + case SimpleTypeSpecifier ts: if (type != null) throw new NotSupportedException( $"Unsupported type definition after already resolved type {type}: {ts}."); diff --git a/Cesium.CodeGen/Ir/ParametersInfo.cs b/Cesium.CodeGen/Ir/ParametersInfo.cs index 7d2b9041..c5daecd3 100644 --- a/Cesium.CodeGen/Ir/ParametersInfo.cs +++ b/Cesium.CodeGen/Ir/ParametersInfo.cs @@ -17,7 +17,7 @@ public static ParametersInfo Of(ParameterTypeList parameters) if (specifiers.Length != 1 || declarator != null || abstractDeclarator != null) isVoid = false; else { - isVoid = specifiers.Single() is TypeSpecifier { TypeName: "void" }; + isVoid = specifiers.Single() is SimpleTypeSpecifier { TypeName: "void" }; } } else isVoid = false; diff --git a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.CliImport.verified.txt b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.CliImport.verified.txt index 0c2d57d8..ccb95e17 100644 --- a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.CliImport.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.CliImport.verified.txt @@ -6,7 +6,7 @@ "MemberName": "System.Runtime.InteropServices.Marshal::AllocHGlobal" }, { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], diff --git a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.InitializerDeclarationTest.verified.txt b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.InitializerDeclarationTest.verified.txt index a2f0a553..a113217f 100644 --- a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.InitializerDeclarationTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.InitializerDeclarationTest.verified.txt @@ -2,7 +2,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.MultiDeclaration.verified.txt b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.MultiDeclaration.verified.txt index fb344954..c5cc6d29 100644 --- a/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.MultiDeclaration.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/DeclarationParserTests.MultiDeclaration.verified.txt @@ -2,7 +2,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.AnonymousArrayParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.AnonymousArrayParameter.verified.txt index d8166d05..6fe5736e 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.AnonymousArrayParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.AnonymousArrayParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayOfArrayParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayOfArrayParameter.verified.txt index 13470be7..f113da7f 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayOfArrayParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayOfArrayParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayParameter.verified.txt index a2d00eb7..cec76951 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.ArrayParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.CharLiteral.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.CharLiteral.verified.txt index 4b65c433..011140c2 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.CharLiteral.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.CharLiteral.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], @@ -63,7 +63,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.CliImport.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.CliImport.verified.txt index 556e1219..d686166a 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.CliImport.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.CliImport.verified.txt @@ -11,7 +11,7 @@ "MemberName": "Foo.Bar::Baz" }, { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -40,7 +40,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -65,7 +65,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.ExpressionTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.ExpressionTest.verified.txt index 91db7bfa..b07536b6 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.ExpressionTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.ExpressionTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.FunctionCallTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.FunctionCallTest.verified.txt index 0dcc0f66..aedbabaf 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.FunctionCallTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.FunctionCallTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -43,7 +43,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -68,7 +68,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.IntParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.IntParameter.verified.txt index 60cdd534..1fbc6c0d 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.IntParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.IntParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.MainSignature.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.MainSignature.verified.txt index 8917813a..2d712ece 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.MainSignature.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.MainSignature.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -45,7 +45,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.MinimalProgramTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.MinimalProgramTest.verified.txt index 889aff17..974d9510 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.MinimalProgramTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.MinimalProgramTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.NegationTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.NegationTest.verified.txt index e5f48ad0..16e56d71 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.NegationTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.NegationTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerArrayParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerArrayParameter.verified.txt index 33e1013e..80b1da3b 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerArrayParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerArrayParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerParameter.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerParameter.verified.txt index 8094a603..ab4c7b7f 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerParameter.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.PointerParameter.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -26,7 +26,7 @@ "$type": "Cesium.Ast.ParameterDeclaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.PrefixIncrementTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.PrefixIncrementTest.verified.txt index 8ac8eb36..8c8d86c2 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.PrefixIncrementTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.PrefixIncrementTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.ReturnTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.ReturnTest.verified.txt index bd5650d8..d813162e 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.ReturnTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.ReturnTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleStructDefinition.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleStructDefinition.verified.txt new file mode 100644 index 00000000..2ff585e9 --- /dev/null +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleStructDefinition.verified.txt @@ -0,0 +1,62 @@ +{ + "$type": "Cesium.Ast.TranslationUnit, Cesium.Ast", + "Declarations": [ + { + "$type": "Cesium.Ast.SymbolDeclaration, Cesium.Ast", + "Declaration": { + "$type": "Cesium.Ast.Declaration, Cesium.Ast", + "Specifiers": [ + { + "$type": "Cesium.Ast.StorageClassSpecifier, Cesium.Ast", + "Name": "typedef" + }, + { + "$type": "Cesium.Ast.StructOrUnionSpecifier, Cesium.Ast", + "TypeKind": "Struct", + "Identifier": null, + "StructDeclarations": [ + { + "$type": "Cesium.Ast.StructDeclaration, Cesium.Ast", + "SpecifiersQualifiers": [ + { + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", + "TypeName": "int" + } + ], + "Declarators": [ + { + "$type": "Cesium.Ast.StructDeclarator, Cesium.Ast", + "Declarator": { + "$type": "Cesium.Ast.Declarator, Cesium.Ast", + "Pointer": null, + "DirectDeclarator": { + "$type": "Cesium.Ast.IdentifierDirectDeclarator, Cesium.Ast", + "Identifier": "x", + "Base": null + } + } + } + ] + } + ] + } + ], + "InitDeclarators": [ + { + "$type": "Cesium.Ast.InitDeclarator, Cesium.Ast", + "Declarator": { + "$type": "Cesium.Ast.Declarator, Cesium.Ast", + "Pointer": null, + "DirectDeclarator": { + "$type": "Cesium.Ast.IdentifierDirectDeclarator, Cesium.Ast", + "Identifier": "foo", + "Base": null + } + }, + "Initializer": null + } + ] + } + } + ] +} \ No newline at end of file diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleVariableTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleVariableTest.verified.txt index a27a1547..e34ca27d 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleVariableTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.SimpleVariableTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "void" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.StringLiteral.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.StringLiteral.verified.txt index 1a565723..89111ec6 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.StringLiteral.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.StringLiteral.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.StringVariable.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.StringVariable.verified.txt index 47719403..318f20f1 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.StringVariable.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.StringVariable.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -34,7 +34,7 @@ "Name": "const" }, { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "char" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableArithmeticTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableArithmeticTest.verified.txt index 2f3e2b6d..77abfcb2 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableArithmeticTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableArithmeticTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableTest.verified.txt b/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableTest.verified.txt index a4e2da94..1258c7ce 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableTest.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.VariableTest.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.FunctionDefinition, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], @@ -30,7 +30,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser.Tests/ParserTests/FullParserTests.cs b/Cesium.Parser.Tests/ParserTests/FullParserTests.cs index e94d759b..ebe5645f 100644 --- a/Cesium.Parser.Tests/ParserTests/FullParserTests.cs +++ b/Cesium.Parser.Tests/ParserTests/FullParserTests.cs @@ -1,7 +1,6 @@ using Cesium.Test.Framework; using Xunit.Sdk; using Yoakke.C.Syntax; -using Yoakke.Streams; namespace Cesium.Parser.Tests.ParserTests; @@ -118,4 +117,7 @@ public Task PrefixIncrementTest() => DoTest(@"int main() ++x; return x; }"); + + [Fact] + public Task SimpleStructDefinition() => DoTest(@"typedef struct { int x; } foo;"); } diff --git a/Cesium.Parser.Tests/ParserTests/StatementParserTests.CompoundStatementWithVariable.verified.txt b/Cesium.Parser.Tests/ParserTests/StatementParserTests.CompoundStatementWithVariable.verified.txt index d1c13973..413a02af 100644 --- a/Cesium.Parser.Tests/ParserTests/StatementParserTests.CompoundStatementWithVariable.verified.txt +++ b/Cesium.Parser.Tests/ParserTests/StatementParserTests.CompoundStatementWithVariable.verified.txt @@ -5,7 +5,7 @@ "$type": "Cesium.Ast.Declaration, Cesium.Ast", "Specifiers": [ { - "$type": "Cesium.Ast.TypeSpecifier, Cesium.Ast", + "$type": "Cesium.Ast.SimpleTypeSpecifier, Cesium.Ast", "TypeName": "int" } ], diff --git a/Cesium.Parser/CParser.cs b/Cesium.Parser/CParser.cs index 8c58aa8e..a95fbc51 100644 --- a/Cesium.Parser/CParser.cs +++ b/Cesium.Parser/CParser.cs @@ -15,6 +15,9 @@ namespace Cesium.Parser; using IdentifierList = ImmutableArray; using InitDeclaratorList = ImmutableArray; using ParameterList = ImmutableArray; +using SpecifierQualifierList = ImmutableArray; +using StructDeclarationList = ImmutableArray; +using StructDeclaratorList = ImmutableArray; using TypeQualifierList = ImmutableArray; /// See the section 6 of the C17 standard. @@ -176,18 +179,13 @@ private static Declaration MakeDeclaration( InitDeclaratorList? initDeclarators, IToken _) => new(specifiers, initDeclarators); - // TODO: [Rule("declaration_specifiers: storage_class_specifier declaration_specifiers?")] + [Rule("declaration_specifiers: storage_class_specifier declaration_specifiers?")] [Rule("declaration_specifiers: type_specifier declaration_specifiers?")] - private static DeclarationSpecifiers MakeDeclarationSpecifiers( - TypeSpecifier typeSpecifier, - DeclarationSpecifiers? rest) => - rest?.Insert(0, typeSpecifier) ?? ImmutableArray.Create(typeSpecifier); - [Rule("declaration_specifiers: type_qualifier declaration_specifiers?")] private static DeclarationSpecifiers MakeDeclarationSpecifiers( - TypeQualifier typeQualifier, + IDeclarationSpecifier storageClassSpecifier, DeclarationSpecifiers? rest) => - rest?.Insert(0, typeQualifier) ?? ImmutableArray.Create(typeQualifier); + rest?.Insert(0, storageClassSpecifier) ?? ImmutableArray.Create(storageClassSpecifier); // TODO: [Rule("declaration_specifiers: function_specifier declaration_specifiers?")] // TODO: [Rule("declaration_specifiers: alignment_specifier declaration_specifiers?")] @@ -207,7 +205,17 @@ private static InitDeclaratorList MakeInitDeclaratorList(InitDeclaratorList prev private static InitDeclarator MakeInitDeclarator(Declarator declarator, IToken _, Initializer initializer) => new(declarator, initializer); - // TODO: 6.7.1 Storage_class specifiers + // 6.7.1 Storage-class specifiers + [Rule("storage_class_specifier: 'typedef'")] + private static StorageClassSpecifier MakeStorageClassSpecifier(IToken keyword) => new(keyword.Text); + + // TODO: + // storage-class-specifier: + // extern + // static + // _Thread_local + // auto + // register // 6.7.2 Type specifiers [Rule("type_specifier: 'void'")] @@ -221,11 +229,76 @@ private static InitDeclarator MakeInitDeclarator(Declarator declarator, IToken _ [Rule("type_specifier: 'unsigned'")] [Rule("type_specifier: '_Bool'")] [Rule("type_specifier: '_Complex'")] + private static ITypeSpecifier MakeSimpleTypeSpecifier(ICToken specifier) => new SimpleTypeSpecifier(specifier.Text); + // TODO: [Rule("type_specifier: atomic_type_specifier")] - // TODO: [Rule("type_specifier: struct_or_union_specifier")] + + [Rule("type_specifier: struct_or_union_specifier")] + private static ITypeSpecifier MakeComplexTypeSpecifier(StructOrUnionSpecifier structOrUnionSpecifier) => + structOrUnionSpecifier; + // TODO: [Rule("type_specifier: enum_specifier")] // TODO: [Rule("type_specifier: typedef_name")] - private static TypeSpecifier MakeTypeSpecifier(ICToken specifier) => new(specifier.Text); + + // 6.7.2.1 Structure and union specifiers + + [Rule("struct_or_union_specifier: struct_or_union Identifier? '{' struct_declaration_list '}'")] + private static StructOrUnionSpecifier MakeStructOrUnionSpecifier( + ComplexTypeKind structOrUnion, + IToken? identifier, + IToken _, + StructDeclarationList structDeclarationList, + IToken __) => new StructOrUnionSpecifier(structOrUnion, identifier?.Text, structDeclarationList); + + // TODO: struct-or-union-specifier: struct-or-union identifier + + [Rule("struct_or_union: 'struct'")] + private static ComplexTypeKind MakeStructComplexTypeKind(IToken _) => ComplexTypeKind.Struct; + // TODO: struct-or-union: union + + [Rule("struct_declaration_list: struct_declaration")] + private static StructDeclarationList MakeStructDeclarationList(StructDeclaration structDeclaration) => + ImmutableArray.Create(structDeclaration); + + [Rule("struct_declaration_list: struct_declaration_list struct_declaration")] + private static StructDeclarationList MakeStructDeclarationList( + StructDeclarationList prev, + StructDeclaration structDeclaration) => prev.Add(structDeclaration); + + [Rule("struct_declaration: specifier_qualifier_list struct_declarator_list? ';'")] + private static StructDeclaration MakeStructDeclaration( + SpecifierQualifierList specifiersQualifiers, + StructDeclaratorList? structDeclarators, + IToken _) => new(specifiersQualifiers, structDeclarators); + + // TODO: struct-declaration: static_assert-declaration + + [Rule("specifier_qualifier_list: type_specifier specifier_qualifier_list?")] + [Rule("specifier_qualifier_list: type_qualifier specifier_qualifier_list?")] + private SpecifierQualifierList MakeSpecifierQualifierList( + ISpecifierQualifierListItem item, + SpecifierQualifierList? rest) => rest?.Insert(0, item) ?? ImmutableArray.Create(item); + + // TODO: specifier-qualifier-list: alignment-specifier specifier-qualifier-list? + + [Rule("struct_declarator_list: struct_declarator")] + private static StructDeclaratorList MakeStructDeclaratorList(StructDeclarator structDeclarator) => + ImmutableArray.Create(structDeclarator); + + [Rule("struct_declarator_list: struct_declarator_list ',' struct_declarator")] + private static StructDeclaratorList MakeStructDeclaratorList( + StructDeclaratorList prev, + IToken _, + StructDeclarator next) => prev.Add(next); + + [Rule("struct_declarator: declarator")] + private static StructDeclarator MakeStructDeclarator(Declarator declarator) => new StructDeclarator(declarator); + + // TODO: struct-declarator: declarator? : constant-expression + + // TODO: 6.7.2.2 Enumeration specifiers + // TODO: 6.7.2.3 Tags + // TODO: 6.7.2.4 Atomic type specifiers // 6.7.3 Type qualifiers [Rule("type_qualifier: 'const'")] diff --git a/Cesium.Test.Framework/ParserTestBase.cs b/Cesium.Test.Framework/ParserTestBase.cs index da6d3fcd..26e9a04c 100644 --- a/Cesium.Test.Framework/ParserTestBase.cs +++ b/Cesium.Test.Framework/ParserTestBase.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using Yoakke.C.Syntax; namespace Cesium.Test.Framework; @@ -8,7 +9,7 @@ public abstract class ParserTestBase : VerifyTestBase private static readonly JsonSerializerSettings SerializerOptions = new() { Formatting = Formatting.Indented, - Converters = { new TokenConverter() }, + Converters = { new TokenConverter(), new StringEnumConverter() }, TypeNameHandling = TypeNameHandling.Objects };