Parse sequencing expressions

This commit is contained in:
Brandon Dyck 2023-06-28 17:18:31 -06:00
parent b72c6e9992
commit 84a888738a
6 changed files with 38 additions and 13 deletions

View File

@ -48,4 +48,9 @@ class ASTPrinter : IVisitor<string>
{ {
return parenthesize("if", expr.Condition, expr.Then, expr.Else); return parenthesize("if", expr.Condition, expr.Then, expr.Else);
} }
public string visitSequenceExpr(Sequence expr)
{
return parenthesize("seq", expr.Left, expr.Right);
}
} }

View File

@ -10,12 +10,22 @@ public abstract class Expr {
public abstract T accept<T>(IVisitor<T> visitor); public abstract T accept<T>(IVisitor<T> visitor);
} }
public interface IVisitor<T> { public interface IVisitor<T> {
T visitSequenceExpr(Sequence expr);
T visitBinaryExpr(Binary expr); T visitBinaryExpr(Binary expr);
T visitGroupingExpr(Grouping expr); T visitGroupingExpr(Grouping expr);
T visitLiteralExpr(Literal expr); T visitLiteralExpr(Literal expr);
T visitUnaryExpr(Unary expr); T visitUnaryExpr(Unary expr);
T visitIfExpr(If expr); T visitIfExpr(If expr);
} }
public class Sequence : Expr
{
public required Expr Left { get; init; }
public required Expr Right { get; init; }
public override T accept<T>(IVisitor<T> visitor)
{
return visitor.visitSequenceExpr(this);
}
}
public class Binary : Expr public class Binary : Expr
{ {
public required Expr Left { get; init; } public required Expr Left { get; init; }

View File

@ -121,7 +121,13 @@ class Parser
private Expr expression() private Expr expression()
{ {
return equality(); var expr = equality();
while (match(TokenType.Semicolon))
{
var right = equality();
expr = new Sequence { Left = expr, Right = right };
}
return expr;
} }
private Expr equality() private Expr equality()

View File

@ -94,6 +94,7 @@ public enum TokenType
Backtick, Backtick,
At, At,
Comma, Comma,
Semicolon,
Period, Period,
Equal, Equal,
Plus, Minus, Asterisk, Slash, Plus, Minus, Asterisk, Slash,
@ -284,6 +285,7 @@ class Scanner
case '`': addToken(TokenType.Backtick); break; case '`': addToken(TokenType.Backtick); break;
case '@': addToken(TokenType.At); break; case '@': addToken(TokenType.At); break;
case ',': addToken(TokenType.Comma); break; case ',': addToken(TokenType.Comma); break;
case ';': addToken(TokenType.Semicolon); break;
case '.': addToken(TokenType.Period); break; case '.': addToken(TokenType.Period); break;
case '*': addToken(TokenType.Asterisk); break; case '*': addToken(TokenType.Asterisk); break;
case '/': addToken(TokenType.Slash); break; case '/': addToken(TokenType.Slash); break;

View File

@ -2,7 +2,9 @@ type Field = { Type: string; Name: string }
type Type = { Name: string; Fields: list<Field> } type Type = { Name: string; Fields: list<Field> }
let types = let types =
[ { Name = "Binary" [ { Name = "Sequence"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] }
{ Name = "Binary"
Fields = Fields =
[ { Type = "Expr"; Name = "Left" } [ { Type = "Expr"; Name = "Left" }
{ Type = "Token"; Name = "Op" } { Type = "Token"; Name = "Op" }

View File

@ -1,20 +1,16 @@
expression -> expression ->
| literal | sequence
// | identifier // | apply
// | sequence
| unary | unary
| binary | binary
// | let // | let
// | when | compound
| if | control
| variant
| record
| list
| field | field
| index | index
| grouping ; // | identifier
| primary
literal -> NUMBER | STRING ;
identifier -> IDENTIFIER | "@" STRING ; identifier -> IDENTIFIER | "@" STRING ;
grouping -> "(" expression ")" ; grouping -> "(" expression ")" ;
unary -> ( "-" | "!" ) expression ; unary -> ( "-" | "!" ) expression ;
@ -24,11 +20,15 @@ operator ->
| "+" | "-" | "*" | "/" | "+" | "-" | "*" | "/"
// | "|>" | "<|" | ">>" | "<<" // | "|>" | "<|" | ">>" | "<<"
| "++" ; | "++" ;
control ->
| if
// | when
if -> "if" expression "then" expression "else" expression ; if -> "if" expression "then" expression "else" expression ;
compound -> variant | record | list ;
variant -> "`" identifier ( "(" ( expression ( "," expression)* )? ")" )? ; variant -> "`" identifier ( "(" ( expression ( "," expression)* )? ")" )? ;
record -> record ->
"{" ( identifier "=" expression ( "," identifier "=" expression )* )? "}" ; "{" ( identifier "=" expression ( "," identifier "=" expression )* )? "}" ;
list -> "[" ( expression ( "," expression )* )? "]" ; list -> "[" ( expression ( "," expression )* )? "]" ;
field -> expression "." identifier ; field -> expression "." identifier ;
index -> expression "[" expression "]" ; index -> expression "[" expression "]" ;
grouping -> "(" expression ")" ; primary -> NUMBER | STRING | "(" expression ")" ;