Parse list literals
This commit is contained in:
parent
6ab36fc489
commit
8de88c0ce3
@ -69,4 +69,9 @@ class ASTPrinter : IVisitor<string>
|
|||||||
{
|
{
|
||||||
return parenthesize(".", expr.Left, new Identifier { Value = expr.FieldName });
|
return parenthesize(".", expr.Left, new Identifier { Value = expr.FieldName });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string visitListExpr(List expr)
|
||||||
|
{
|
||||||
|
return parenthesize("list", expr.Elements);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
Expr.g.cs
10
Expr.g.cs
@ -4,6 +4,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Finn.AST;
|
namespace Finn.AST;
|
||||||
|
|
||||||
public abstract class Expr {
|
public abstract class Expr {
|
||||||
@ -17,6 +18,7 @@ public interface IVisitor<T> {
|
|||||||
T visitUnaryExpr(Unary expr);
|
T visitUnaryExpr(Unary expr);
|
||||||
T visitIfExpr(If expr);
|
T visitIfExpr(If expr);
|
||||||
T visitIdentifierExpr(Identifier expr);
|
T visitIdentifierExpr(Identifier expr);
|
||||||
|
T visitListExpr(List expr);
|
||||||
T visitSelectorExpr(Selector expr);
|
T visitSelectorExpr(Selector expr);
|
||||||
}
|
}
|
||||||
public class Sequence : Expr
|
public class Sequence : Expr
|
||||||
@ -81,6 +83,14 @@ public class Identifier : Expr
|
|||||||
return visitor.visitIdentifierExpr(this);
|
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 class Selector : Expr
|
||||||
{
|
{
|
||||||
public required Expr Left { get; init; }
|
public required Expr Left { get; init; }
|
||||||
|
41
Parser.cs
41
Parser.cs
@ -246,9 +246,9 @@ class Parser
|
|||||||
|
|
||||||
if (match(TokenType.LParen))
|
if (match(TokenType.LParen))
|
||||||
{
|
{
|
||||||
Expr expr = expression();
|
Expr groupedExpr = expression();
|
||||||
consume(TokenType.RParen, "Expect ')' after expression.");
|
consume(TokenType.RParen, "Expect ')' after expression.");
|
||||||
return new Grouping { Expression = expr };
|
return new Grouping { Expression = groupedExpr };
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr? expr;
|
Expr? expr;
|
||||||
@ -270,16 +270,47 @@ class Parser
|
|||||||
|
|
||||||
private Expr? list()
|
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()
|
private Expr? variant()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("TODO variant");
|
return null;
|
||||||
|
// throw new NotImplementedException("TODO variant");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr? record()
|
private Expr? record()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("TODO record");
|
return null;
|
||||||
|
// throw new NotImplementedException("TODO record");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ let types =
|
|||||||
{ Type = "Expr"; Name = "Else" } ] }
|
{ Type = "Expr"; Name = "Else" } ] }
|
||||||
{ Name = "Identifier"
|
{ Name = "Identifier"
|
||||||
Fields = [ { Type = "Name"; Name = "Value" } ] }
|
Fields = [ { Type = "Name"; Name = "Value" } ] }
|
||||||
|
{ Name = "List"
|
||||||
|
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
|
||||||
{ Name = "Selector"
|
{ Name = "Selector"
|
||||||
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
|
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] } ]
|
||||||
|
|
||||||
@ -64,6 +66,7 @@ let renderAST outputDir baseName types =
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Finn.AST;
|
namespace Finn.AST;
|
||||||
|
|
||||||
public abstract class {baseName} {{
|
public abstract class {baseName} {{
|
||||||
|
Loading…
Reference in New Issue
Block a user