Skip to content

Commit

Permalink
Syntax fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Oct 31, 2024
1 parent 1990d06 commit ae6d486
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 40 deletions.
75 changes: 35 additions & 40 deletions src/Draco.Compiler/Internal/Syntax/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private ExpressionParserDelegate BinaryRight(params TokenKind[] operators) => le
TokenKind.Plus,
TokenKind.Minus,
TokenKind.Star,
TokenKind.KeywordThis
TokenKind.KeywordThis,
];

/// <summary>
Expand Down Expand Up @@ -384,8 +384,7 @@ private DeclarationSyntax ParseDeclaration(DeclarationContext context)

case TokenKind.KeywordValue:
case TokenKind.KeywordClass:
// TODO: Attributes?
return this.ParseClassDeclaration(visibility);
return this.ParseClassDeclaration(attributes, visibility);

case TokenKind.KeywordFunc:
return this.ParseFunctionDeclaration(attributes, visibility, context);
Expand Down Expand Up @@ -539,9 +538,10 @@ private ImportPathSyntax ParseImportPath()
/// <summary>
/// Parses a class declaration.
/// </summary>
/// <param name="attributes">Optional attributes on the class.</param>
/// <param name="visibility">Optional visibility modifier token.</param>
/// <returns>The parsed <see cref="ClassDeclarationSyntax"/>.</returns>
private ClassDeclarationSyntax ParseClassDeclaration(SyntaxToken? visibility)
private ClassDeclarationSyntax ParseClassDeclaration(SyntaxList<AttributeSyntax>? attributes, SyntaxToken? visibility)
{
this.Matches(TokenKind.KeywordValue, out var valueModifier);

Expand All @@ -568,42 +568,40 @@ private ClassDeclarationSyntax ParseClassDeclaration(SyntaxToken? visibility)
/// Parses the body of a class.
/// </summary>
/// <returns>The parsed <see cref="ClassBodySyntax"/>.</returns>
private ClassBodySyntax ParseClassBody() => this.PeekKind() switch
private ClassBodySyntax ParseClassBody()
{
TokenKind.Semicolon => this.ParseEmptyClassBody(),
TokenKind.CurlyOpen => this.ParseBlockClassBody(),
_ => throw new NotImplementedException()
};

/// <summary>
/// Parses an empty class body, which is just a semicolon.
/// </summary>
/// <returns>The parsed <see cref="EmptyClassBodySyntax"/>.</returns>
private EmptyClassBodySyntax ParseEmptyClassBody()
{
var semicolon = this.Expect(TokenKind.Semicolon);
return new EmptyClassBodySyntax(semicolon);
}

/// <summary>
/// Parses a block class body declared with curly braces.
/// </summary>
/// <returns>The parsed <see cref="BlockClassBodySyntax"/>.</returns>
private BlockClassBodySyntax ParseBlockClassBody()
{
var openBrace = this.Expect(TokenKind.CurlyOpen);
var decls = SyntaxList.CreateBuilder<DeclarationSyntax>();
while (true)
if (this.Matches(TokenKind.Semicolon, out var semicolon))
{
return new EmptyClassBodySyntax(semicolon);
}
else if (this.Matches(TokenKind.CurlyOpen, out var openBrace))
{
// Break on the end of the block
if (this.PeekKind() is TokenKind.EndOfInput or TokenKind.CurlyClose) break;
var decls = SyntaxList.CreateBuilder<DeclarationSyntax>();
while (true)
{
// Break on the end of the block
if (this.PeekKind() is TokenKind.EndOfInput or TokenKind.CurlyClose) break;

// Parse a declaration
var decl = this.ParseDeclaration(DeclarationContext.Global);
decls.Add(decl);
// Parse a declaration
var decl = this.ParseDeclaration(DeclarationContext.Global);
decls.Add(decl);
}
var closeBrace = this.Expect(TokenKind.CurlyClose);
return new BlockClassBodySyntax(openBrace, decls.ToSyntaxList(), closeBrace);
}
else
{
var input = this.Synchronize(t => t.Kind switch
{
TokenKind.Semicolon or TokenKind.CurlyClose => false,
_ when this.IsDeclarationStarter(DeclarationContext.Global) => false,
_ => true,
});
var info = DiagnosticInfo.Create(SyntaxErrors.UnexpectedInput, formatArgs: "class body");
var node = new UnexpectedClassBodySyntax(input);
this.AddDiagnostic(node, info);
return node;
}
var closeBrace = this.Expect(TokenKind.CurlyClose);
return new(openBrace, decls.ToSyntaxList(), closeBrace);
}

/// <summary>
Expand Down Expand Up @@ -631,7 +629,7 @@ private VariableDeclarationSyntax ParseVariableDeclaration(

// Global modifier
this.Matches(TokenKind.KeywordGlobal, out var globalModifier);
// TODO: Check where this is correct
// TODO: We need more info to check, if this is an error

// Field modifier
this.Matches(TokenKind.KeywordField, out var fieldModifier);
Expand Down Expand Up @@ -672,7 +670,6 @@ private VariableDeclarationSyntax ParseVariableDeclaration(
semicolon);
}


/// <summary>
/// Parses a function declaration.
/// </summary>
Expand Down Expand Up @@ -1665,8 +1662,6 @@ private SeparatedSyntaxList<TNode> ParseSeparatedSyntaxList<TNode>(

private SyntaxToken? ParseVisibilityModifier() => IsVisibilityModifier(this.PeekKind()) ? this.Advance() : null;

private SyntaxToken? ParseGlobalModifier() => this.PeekKind() == TokenKind.KeywordGlobal ? this.Advance() : null;

private bool CanBailOut(SyntaxNode node)
{
if (parserMode != ParserMode.Repl) return false;
Expand Down
12 changes: 12 additions & 0 deletions src/Draco.Compiler/Internal/Syntax/Syntax.xml
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,18 @@
</Field>
</Node>

<Node Name="UnexpectedClassBodySyntax" Base="ClassBodySyntax">
<Documentation>
Unexpected input in class body context.
</Documentation>

<Field Name="Nodes" Type="SyntaxList&lt;SyntaxNode&gt;">
<Documentation>
The unexpected syntax nodes.
</Documentation>
</Field>
</Node>

<Node Name="FunctionDeclarationSyntax" Base="DeclarationSyntax">
<Documentation>
A function declaration.
Expand Down

0 comments on commit ae6d486

Please sign in to comment.