Parse list literals

This commit is contained in:
Brandon Dyck 2023-07-01 23:13:24 -06:00
parent 6ab36fc489
commit 8de88c0ce3
4 changed files with 54 additions and 5 deletions

View File

@ -69,4 +69,9 @@ class ASTPrinter : IVisitor<string>
{
return parenthesize(".", expr.Left, new Identifier { Value = expr.FieldName });
}
public string visitListExpr(List expr)
{
return parenthesize("list", expr.Elements);
}
}

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////
using System;
namespace Finn.AST;
public abstract class Expr {
@ -17,6 +18,7 @@ public interface IVisitor<T> {
T visitUnaryExpr(Unary expr);
T visitIfExpr(If expr);
T visitIdentifierExpr(Identifier expr);
T visitListExpr(List expr);
T visitSelectorExpr(Selector expr);
}
public class Sequence : Expr
@ -81,6 +83,14 @@ public class Identifier : Expr
return visitor.visitIdentifierExpr(this);
}
}
public class List : Expr
{
public required Expr[] Elements { get; init; }
public override T accept<T>(IVisitor<T> visitor)
{
return visitor.visitListExpr(this);
}
}
public class Selector : Expr
{
public required Expr Left { get; init; }

View File

@ -246,9 +246,9 @@ class Parser
if (match(TokenType.LParen))
{
Expr expr = expression();
Expr groupedExpr = expression();
consume(TokenType.RParen, "Expect ')' after expression.");
return new Grouping { Expression = expr };
return new Grouping { Expression = groupedExpr };
}
Expr? expr;
@ -270,16 +270,47 @@ class Parser
private Expr? list()
{
throw new NotImplementedException("TODO list");
if (!match(TokenType.LBracket))
{
return null;
}
List<Expr> elements = new List<Expr>();
if (!match(TokenType.RBracket))
{
elements.Add(expression());
while (!match(TokenType.RBracket))
{
if (match(TokenType.Comma))
{
if (match(TokenType.RBracket))
{
break;
}
else
{
elements.Add(expression());
}
}
else
{
throw error(previous(), "Expect comma between list elements.");
}
}
}
return new Finn.AST.List { Elements = elements.ToArray() };
}
private Expr? variant()
{
throw new NotImplementedException("TODO variant");
return null;
// throw new NotImplementedException("TODO variant");
}
private Expr? record()
{
throw new NotImplementedException("TODO record");
return null;
// throw new NotImplementedException("TODO record");
}
}

View File

@ -24,6 +24,8 @@ let types =
{ Type = "Expr"; Name = "Else" } ] }
{ Name = "Identifier"
Fields = [ { Type = "Name"; Name = "Value" } ] }
{ Name = "List"
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
{ Name = "Selector"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
@ -64,6 +66,7 @@ let renderAST outputDir baseName types =
////////////////////////////////////////////////////////////
using System;
namespace Finn.AST;
public abstract class {baseName} {{