Parse when-expressions
This commit is contained in:
parent
86a9241632
commit
d498cc627b
@ -25,6 +25,7 @@ public interface IExprVisitor<T> {
|
|||||||
T visitIndexerExpr(Indexer expr);
|
T visitIndexerExpr(Indexer expr);
|
||||||
T visitCallExpr(Call expr);
|
T visitCallExpr(Call expr);
|
||||||
T visitLetExpr(Let expr);
|
T visitLetExpr(Let expr);
|
||||||
|
T visitWhenExpr(When expr);
|
||||||
}
|
}
|
||||||
public partial record Sequence(Expr Left, Expr Right) : Expr()
|
public partial record Sequence(Expr Left, Expr Right) : Expr()
|
||||||
{
|
{
|
||||||
@ -124,3 +125,10 @@ public partial record Let(Binding[] Bindings, Expr Body) : Expr()
|
|||||||
return visitor.visitLetExpr(this);
|
return visitor.visitLetExpr(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public partial record When(Expr Head, Binding[] Cases) : Expr()
|
||||||
|
{
|
||||||
|
public override T accept<T>(IExprVisitor<T> visitor)
|
||||||
|
{
|
||||||
|
return visitor.visitWhenExpr(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
55
Parser.cs
55
Parser.cs
@ -245,9 +245,10 @@ class Parser
|
|||||||
{
|
{
|
||||||
if (!match(TokenType.Let))
|
if (!match(TokenType.Let))
|
||||||
{
|
{
|
||||||
return control();
|
return ifExpr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Add function bindings.
|
||||||
List<Binding> bindings = new List<Binding>();
|
List<Binding> bindings = new List<Binding>();
|
||||||
Pattern p = pattern();
|
Pattern p = pattern();
|
||||||
consume(TokenType.Equal, "Expect '=' after pattern.");
|
consume(TokenType.Equal, "Expect '=' after pattern.");
|
||||||
@ -263,24 +264,64 @@ class Parser
|
|||||||
return new Let(bindings.ToArray(), body);
|
return new Let(bindings.ToArray(), body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr control()
|
private Expr ifExpr()
|
||||||
{
|
{
|
||||||
switch (peek().type)
|
if (!match(TokenType.If))
|
||||||
{
|
{
|
||||||
case TokenType.If:
|
return when();
|
||||||
advance();
|
}
|
||||||
Expr condition = expression();
|
Expr condition = expression();
|
||||||
consume(TokenType.Then, "Expect 'then' after condition.");
|
consume(TokenType.Then, "Expect 'then' after condition.");
|
||||||
Expr thenCase = expression();
|
Expr thenCase = expression();
|
||||||
consume(TokenType.Else, "Expect 'else' after 'then' case.");
|
consume(TokenType.Else, "Expect 'else' after 'then' case.");
|
||||||
Expr elseCase = expression();
|
Expr elseCase = expression();
|
||||||
return new If(condition, thenCase, elseCase);
|
return new If(condition, thenCase, elseCase);
|
||||||
case TokenType.When:
|
|
||||||
throw new NotImplementedException("TODO when");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private Expr control()
|
||||||
|
// {
|
||||||
|
// switch (peek().type)
|
||||||
|
// {
|
||||||
|
// case TokenType.If:
|
||||||
|
// advance();
|
||||||
|
// Expr condition = expression();
|
||||||
|
// consume(TokenType.Then, "Expect 'then' after condition.");
|
||||||
|
// Expr thenCase = expression();
|
||||||
|
// consume(TokenType.Else, "Expect 'else' after 'then' case.");
|
||||||
|
// Expr elseCase = expression();
|
||||||
|
// return new If(condition, thenCase, elseCase);
|
||||||
|
// case TokenType.When:
|
||||||
|
// throw new NotImplementedException("TODO when");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return primary();
|
||||||
|
// }
|
||||||
|
|
||||||
|
private Expr when()
|
||||||
|
{
|
||||||
|
if (!match(TokenType.When))
|
||||||
|
{
|
||||||
return primary();
|
return primary();
|
||||||
}
|
}
|
||||||
|
Expr head = expression();
|
||||||
|
consume(TokenType.Is, "Expect 'is' after expression.");
|
||||||
|
|
||||||
|
List<Binding> cases = new List<Binding>();
|
||||||
|
cases.Add(parseCase());
|
||||||
|
while (match(TokenType.Comma))
|
||||||
|
{
|
||||||
|
cases.Add(parseCase());
|
||||||
|
}
|
||||||
|
return new When(head, cases.ToArray());
|
||||||
|
|
||||||
|
Binding parseCase()
|
||||||
|
{
|
||||||
|
Pattern pat = pattern();
|
||||||
|
consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");
|
||||||
|
Expr value = expression();
|
||||||
|
return new(pat, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Name? name()
|
private Name? name()
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,9 @@ let exprTypes =
|
|||||||
Fields =
|
Fields =
|
||||||
[ { Type = "Binding[]"
|
[ { Type = "Binding[]"
|
||||||
Name = "Bindings" }
|
Name = "Bindings" }
|
||||||
{ Type = "Expr"; Name = "Body" } ] } ]
|
{ Type = "Expr"; Name = "Body" } ] }
|
||||||
|
{ Name = "When"
|
||||||
|
Fields = [ { Type = "Expr"; Name = "Head" }; { Type = "Binding[]"; Name = "Cases" } ] } ]
|
||||||
|
|
||||||
let patternTypes =
|
let patternTypes =
|
||||||
[ { Name = "SimplePattern"
|
[ { Name = "SimplePattern"
|
||||||
|
@ -4,7 +4,8 @@ expression ->
|
|||||||
| unary
|
| unary
|
||||||
| binary
|
| binary
|
||||||
| let
|
| let
|
||||||
| control
|
| if
|
||||||
|
| when
|
||||||
| primary
|
| primary
|
||||||
|
|
||||||
grouping -> "(" expression ")" ;
|
grouping -> "(" expression ")" ;
|
||||||
@ -19,11 +20,8 @@ record_pattern -> "{" ( identifier ( "=" pattern )? ( "," identifier ( "=" patte
|
|||||||
variant_pattern -> "`" identifier ( "(" ( "_" | compound_pattern | identifier ) ")" )? ;
|
variant_pattern -> "`" identifier ( "(" ( "_" | compound_pattern | identifier ) ")" )? ;
|
||||||
parameters -> "(" ( identifier ( "," identifier )* )?")"
|
parameters -> "(" ( identifier ( "," identifier )* )?")"
|
||||||
let -> "let" ( identifier parameters? | pattern ) "=" expression ( "and" ( identifier parameters? | pattern ) "=" expression )* "in" expression ;
|
let -> "let" ( identifier parameters? | pattern ) "=" expression ( "and" ( identifier parameters? | pattern ) "=" expression )* "in" expression ;
|
||||||
control ->
|
|
||||||
| if
|
|
||||||
| when
|
|
||||||
if -> "if" expression "then" expression "else" expression ;
|
if -> "if" expression "then" expression "else" expression ;
|
||||||
when -> "when" expression "is" ( ( identifier | pattern ) "=>" expression )+ ;
|
when -> "when" expression "is" ( identifier | pattern ) "=>" expression ( "," ( identifier | pattern ) "=>" expression )* ;
|
||||||
variant -> "`" identifier ( "(" expression ")" )? ;
|
variant -> "`" identifier ( "(" expression ")" )? ;
|
||||||
base_record -> expression ( "with" identifier "=" expression ( "," identifier "=" expression )* ","? )?
|
base_record -> expression ( "with" identifier "=" expression ( "," identifier "=" expression )* ","? )?
|
||||||
record ->
|
record ->
|
||||||
|
Loading…
Reference in New Issue
Block a user