Parse sequencing expressions
This commit is contained in:
parent
b72c6e9992
commit
84a888738a
@ -48,4 +48,9 @@ class ASTPrinter : IVisitor<string>
|
||||
{
|
||||
return parenthesize("if", expr.Condition, expr.Then, expr.Else);
|
||||
}
|
||||
|
||||
public string visitSequenceExpr(Sequence expr)
|
||||
{
|
||||
return parenthesize("seq", expr.Left, expr.Right);
|
||||
}
|
||||
}
|
||||
|
10
Expr.g.cs
10
Expr.g.cs
@ -10,12 +10,22 @@ public abstract class Expr {
|
||||
public abstract T accept<T>(IVisitor<T> visitor);
|
||||
}
|
||||
public interface IVisitor<T> {
|
||||
T visitSequenceExpr(Sequence expr);
|
||||
T visitBinaryExpr(Binary expr);
|
||||
T visitGroupingExpr(Grouping expr);
|
||||
T visitLiteralExpr(Literal expr);
|
||||
T visitUnaryExpr(Unary 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 required Expr Left { get; init; }
|
||||
|
@ -121,7 +121,13 @@ class Parser
|
||||
|
||||
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()
|
||||
|
@ -94,6 +94,7 @@ public enum TokenType
|
||||
Backtick,
|
||||
At,
|
||||
Comma,
|
||||
Semicolon,
|
||||
Period,
|
||||
Equal,
|
||||
Plus, Minus, Asterisk, Slash,
|
||||
@ -284,6 +285,7 @@ class Scanner
|
||||
case '`': addToken(TokenType.Backtick); break;
|
||||
case '@': addToken(TokenType.At); break;
|
||||
case ',': addToken(TokenType.Comma); break;
|
||||
case ';': addToken(TokenType.Semicolon); break;
|
||||
case '.': addToken(TokenType.Period); break;
|
||||
case '*': addToken(TokenType.Asterisk); break;
|
||||
case '/': addToken(TokenType.Slash); break;
|
||||
|
@ -2,7 +2,9 @@ type Field = { Type: string; Name: string }
|
||||
type Type = { Name: string; Fields: list<Field> }
|
||||
|
||||
let types =
|
||||
[ { Name = "Binary"
|
||||
[ { Name = "Sequence"
|
||||
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] }
|
||||
{ Name = "Binary"
|
||||
Fields =
|
||||
[ { Type = "Expr"; Name = "Left" }
|
||||
{ Type = "Token"; Name = "Op" }
|
||||
|
22
grammar.txt
22
grammar.txt
@ -1,20 +1,16 @@
|
||||
expression ->
|
||||
| literal
|
||||
// | identifier
|
||||
// | sequence
|
||||
| sequence
|
||||
// | apply
|
||||
| unary
|
||||
| binary
|
||||
// | let
|
||||
// | when
|
||||
| if
|
||||
| variant
|
||||
| record
|
||||
| list
|
||||
| compound
|
||||
| control
|
||||
| field
|
||||
| index
|
||||
| grouping ;
|
||||
// | identifier
|
||||
| primary
|
||||
|
||||
literal -> NUMBER | STRING ;
|
||||
identifier -> IDENTIFIER | "@" STRING ;
|
||||
grouping -> "(" expression ")" ;
|
||||
unary -> ( "-" | "!" ) expression ;
|
||||
@ -24,11 +20,15 @@ operator ->
|
||||
| "+" | "-" | "*" | "/"
|
||||
// | "|>" | "<|" | ">>" | "<<"
|
||||
| "++" ;
|
||||
control ->
|
||||
| if
|
||||
// | when
|
||||
if -> "if" expression "then" expression "else" expression ;
|
||||
compound -> variant | record | list ;
|
||||
variant -> "`" identifier ( "(" ( expression ( "," expression)* )? ")" )? ;
|
||||
record ->
|
||||
"{" ( identifier "=" expression ( "," identifier "=" expression )* )? "}" ;
|
||||
list -> "[" ( expression ( "," expression )* )? "]" ;
|
||||
field -> expression "." identifier ;
|
||||
index -> expression "[" expression "]" ;
|
||||
grouping -> "(" expression ")" ;
|
||||
primary -> NUMBER | STRING | "(" expression ")" ;
|
||||
|
Loading…
Reference in New Issue
Block a user