Parse variants
This commit is contained in:
parent
8de88c0ce3
commit
5b0ca1ca6d
@ -74,4 +74,13 @@ class ASTPrinter : IVisitor<string>
|
||||
{
|
||||
return parenthesize("list", expr.Elements);
|
||||
}
|
||||
|
||||
public string visitVariantExpr(Variant expr)
|
||||
{
|
||||
if (expr.Argument == null)
|
||||
{
|
||||
return parenthesize("variant", new Identifier { Value = expr.Tag });
|
||||
}
|
||||
return parenthesize("variant", new Identifier { Value = expr.Tag }, expr.Argument);
|
||||
}
|
||||
}
|
||||
|
10
Expr.g.cs
10
Expr.g.cs
@ -19,6 +19,7 @@ public interface IVisitor<T> {
|
||||
T visitIfExpr(If expr);
|
||||
T visitIdentifierExpr(Identifier expr);
|
||||
T visitListExpr(List expr);
|
||||
T visitVariantExpr(Variant expr);
|
||||
T visitSelectorExpr(Selector expr);
|
||||
}
|
||||
public class Sequence : Expr
|
||||
@ -91,6 +92,15 @@ public class List : Expr
|
||||
return visitor.visitListExpr(this);
|
||||
}
|
||||
}
|
||||
public class Variant : Expr
|
||||
{
|
||||
public required Name Tag { get; init; }
|
||||
public required Expr? Argument { get; init; }
|
||||
public override T accept<T>(IVisitor<T> visitor)
|
||||
{
|
||||
return visitor.visitVariantExpr(this);
|
||||
}
|
||||
}
|
||||
public class Selector : Expr
|
||||
{
|
||||
public required Expr Left { get; init; }
|
||||
|
21
Parser.cs
21
Parser.cs
@ -303,14 +303,31 @@ class Parser
|
||||
}
|
||||
|
||||
private Expr? variant()
|
||||
{
|
||||
if (!match(TokenType.Backtick))
|
||||
{
|
||||
return null;
|
||||
// throw new NotImplementedException("TODO variant");
|
||||
}
|
||||
Name? tag = name();
|
||||
Expr? argument = null;
|
||||
if (tag == null)
|
||||
{
|
||||
throw error(peek(), "Expect identifier after backtick.");
|
||||
}
|
||||
if (match(TokenType.LParen))
|
||||
{
|
||||
if (!match(TokenType.RParen))
|
||||
{
|
||||
argument = expression();
|
||||
consume(TokenType.RParen, "Expect ')' after variant argument.");
|
||||
}
|
||||
}
|
||||
return new Variant { Tag = tag, Argument = argument };
|
||||
}
|
||||
|
||||
private Expr? record()
|
||||
{
|
||||
return null;
|
||||
// throw new NotImplementedException("TODO record");
|
||||
// TODO record
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ let types =
|
||||
Fields = [ { Type = "Name"; Name = "Value" } ] }
|
||||
{ Name = "List"
|
||||
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
|
||||
{ Name = "Variant"
|
||||
Fields = [ { Type = "Name"; Name = "Tag" }; { Type = "Expr?"; Name = "Argument" } ] }
|
||||
{ Name = "Selector"
|
||||
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user