Parse variants
This commit is contained in:
parent
8de88c0ce3
commit
5b0ca1ca6d
@ -74,4 +74,13 @@ class ASTPrinter : IVisitor<string>
|
|||||||
{
|
{
|
||||||
return parenthesize("list", expr.Elements);
|
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 visitIfExpr(If expr);
|
||||||
T visitIdentifierExpr(Identifier expr);
|
T visitIdentifierExpr(Identifier expr);
|
||||||
T visitListExpr(List expr);
|
T visitListExpr(List expr);
|
||||||
|
T visitVariantExpr(Variant expr);
|
||||||
T visitSelectorExpr(Selector expr);
|
T visitSelectorExpr(Selector expr);
|
||||||
}
|
}
|
||||||
public class Sequence : Expr
|
public class Sequence : Expr
|
||||||
@ -91,6 +92,15 @@ public class List : Expr
|
|||||||
return visitor.visitListExpr(this);
|
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 class Selector : Expr
|
||||||
{
|
{
|
||||||
public required Expr Left { get; init; }
|
public required Expr Left { get; init; }
|
||||||
|
23
Parser.cs
23
Parser.cs
@ -304,13 +304,30 @@ class Parser
|
|||||||
|
|
||||||
private Expr? variant()
|
private Expr? variant()
|
||||||
{
|
{
|
||||||
return null;
|
if (!match(TokenType.Backtick))
|
||||||
// throw new NotImplementedException("TODO variant");
|
{
|
||||||
|
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()
|
private Expr? record()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
// throw new NotImplementedException("TODO record");
|
// TODO record
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ let types =
|
|||||||
Fields = [ { Type = "Name"; Name = "Value" } ] }
|
Fields = [ { Type = "Name"; Name = "Value" } ] }
|
||||||
{ Name = "List"
|
{ Name = "List"
|
||||||
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
|
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
|
||||||
|
{ Name = "Variant"
|
||||||
|
Fields = [ { Type = "Name"; Name = "Tag" }; { Type = "Expr?"; Name = "Argument" } ] }
|
||||||
{ Name = "Selector"
|
{ Name = "Selector"
|
||||||
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
|
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user