Parse if-expressions
This commit is contained in:
parent
1264aca7f3
commit
ba5283694e
@ -43,4 +43,9 @@ class ASTPrinter : IVisitor<string>
|
|||||||
{
|
{
|
||||||
return parenthesize(expr.Op.lexeme, expr.Right);
|
return parenthesize(expr.Op.lexeme, expr.Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string visitIfExpr(If expr)
|
||||||
|
{
|
||||||
|
return parenthesize("if", expr.Condition, expr.Then, expr.Else);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
11
Expr.g.cs
11
Expr.g.cs
@ -14,6 +14,7 @@ public interface IVisitor<T> {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
public class Binary : Expr
|
public class Binary : Expr
|
||||||
{
|
{
|
||||||
@ -50,3 +51,13 @@ public class Unary : Expr
|
|||||||
return visitor.visitUnaryExpr(this);
|
return visitor.visitUnaryExpr(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public class If : Expr
|
||||||
|
{
|
||||||
|
public required Expr Condition { get; init; }
|
||||||
|
public required Expr Then { get; init; }
|
||||||
|
public required Expr Else { get; init; }
|
||||||
|
public override T accept<T>(IVisitor<T> visitor)
|
||||||
|
{
|
||||||
|
return visitor.visitIfExpr(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
16
Parser.cs
16
Parser.cs
@ -143,6 +143,7 @@ class Parser
|
|||||||
private Expr sum() => binaryLeft(product, TokenType.Minus, TokenType.Plus);
|
private Expr sum() => binaryLeft(product, TokenType.Minus, TokenType.Plus);
|
||||||
|
|
||||||
private Expr product() => binaryLeft(unary, TokenType.Slash, TokenType.Asterisk);
|
private Expr product() => binaryLeft(unary, TokenType.Slash, TokenType.Asterisk);
|
||||||
|
|
||||||
private Expr unary()
|
private Expr unary()
|
||||||
{
|
{
|
||||||
if (match(TokenType.Bang, TokenType.Minus))
|
if (match(TokenType.Bang, TokenType.Minus))
|
||||||
@ -151,6 +152,21 @@ class Parser
|
|||||||
Expr right = unary();
|
Expr right = unary();
|
||||||
return new Unary { Op = op, Right = right };
|
return new Unary { Op = op, Right = right };
|
||||||
}
|
}
|
||||||
|
return ifExpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Expr ifExpr()
|
||||||
|
{
|
||||||
|
if (match(TokenType.If))
|
||||||
|
{
|
||||||
|
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 = condition, Then = thenCase, Else = elseCase };
|
||||||
|
}
|
||||||
|
|
||||||
return primary();
|
return primary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ public enum TokenType
|
|||||||
PipeLeft,
|
PipeLeft,
|
||||||
ComposeRight,
|
ComposeRight,
|
||||||
ComposeLeft,
|
ComposeLeft,
|
||||||
|
If, Then, Else,
|
||||||
When,
|
When,
|
||||||
Is,
|
Is,
|
||||||
Let,
|
Let,
|
||||||
@ -136,6 +137,9 @@ class Scanner
|
|||||||
private static readonly Dictionary<String, TokenType> keywords = new Dictionary<string, TokenType>()
|
private static readonly Dictionary<String, TokenType> keywords = new Dictionary<string, TokenType>()
|
||||||
{
|
{
|
||||||
{"def", TokenType.Def},
|
{"def", TokenType.Def},
|
||||||
|
{"if", TokenType.If},
|
||||||
|
{"then", TokenType.Then},
|
||||||
|
{"else", TokenType.Else},
|
||||||
{"when", TokenType.When},
|
{"when", TokenType.When},
|
||||||
{"is", TokenType.Is},
|
{"is", TokenType.Is},
|
||||||
{"let", TokenType.Let},
|
{"let", TokenType.Let},
|
||||||
|
@ -14,7 +14,12 @@ let types =
|
|||||||
[ { Type = "System.Object"
|
[ { Type = "System.Object"
|
||||||
Name = "Value" } ] }
|
Name = "Value" } ] }
|
||||||
{ Name = "Unary"
|
{ Name = "Unary"
|
||||||
Fields = [ { Type = "Token"; Name = "Op" }; { Type = "Expr"; Name = "Right" } ] } ]
|
Fields = [ { Type = "Token"; Name = "Op" }; { Type = "Expr"; Name = "Right" } ] }
|
||||||
|
{ Name = "If"
|
||||||
|
Fields =
|
||||||
|
[ { Type = "Expr"; Name = "Condition" }
|
||||||
|
{ Type = "Expr"; Name = "Then" }
|
||||||
|
{ Type = "Expr"; Name = "Else" } ] } ]
|
||||||
|
|
||||||
let visitorMethod baseName t = $"visit{t.Name}{baseName}"
|
let visitorMethod baseName t = $"visit{t.Name}{baseName}"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user