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);
|
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 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; }
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
@ -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" }
|
||||||
|
22
grammar.txt
22
grammar.txt
@ -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 ")" ;
|
||||||
|
Loading…
Reference in New Issue
Block a user