Parse variants

This commit is contained in:
Brandon Dyck 2023-07-01 23:30:24 -06:00
parent 8de88c0ce3
commit 5b0ca1ca6d
4 changed files with 41 additions and 3 deletions

View File

@ -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);
}
}

View File

@ -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; }

View File

@ -304,13 +304,30 @@ class Parser
private Expr? variant()
{
return null;
// throw new NotImplementedException("TODO variant");
if (!match(TokenType.Backtick))
{
return null;
}
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
}
}

View File

@ -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" } ] } ]