diff --git a/ASTPrinter.cs b/ASTPrinter.cs index fbcb93f..4d25244 100644 --- a/ASTPrinter.cs +++ b/ASTPrinter.cs @@ -69,4 +69,9 @@ class ASTPrinter : IVisitor { return parenthesize(".", expr.Left, new Identifier { Value = expr.FieldName }); } + + public string visitListExpr(List expr) + { + return parenthesize("list", expr.Elements); + } } diff --git a/Expr.g.cs b/Expr.g.cs index 5b7533f..e9ae9a7 100644 --- a/Expr.g.cs +++ b/Expr.g.cs @@ -4,6 +4,7 @@ //////////////////////////////////////////////////////////// using System; + namespace Finn.AST; public abstract class Expr { @@ -17,6 +18,7 @@ public interface IVisitor { 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(IVisitor visitor) + { + return visitor.visitListExpr(this); + } +} public class Selector : Expr { public required Expr Left { get; init; } diff --git a/Parser.cs b/Parser.cs index 92399aa..f241ad7 100644 --- a/Parser.cs +++ b/Parser.cs @@ -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 elements = new List(); + + 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"); } } diff --git a/ast_classes.fsx b/ast_classes.fsx index 6945bb1..07a2ef5 100644 --- a/ast_classes.fsx +++ b/ast_classes.fsx @@ -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} {{