Evaluate when-exprs

This commit is contained in:
Brandon Dyck 2023-07-11 13:55:06 -06:00
parent 7741b7c4ad
commit 9ea27888cb
4 changed files with 25 additions and 5 deletions

View File

@ -125,7 +125,7 @@ public partial record Let(Binding[] Bindings, Expr Body) : Expr()
return visitor.visitLetExpr(context, this); return visitor.visitLetExpr(context, this);
} }
} }
public partial record When(Expr Head, Binding[] Cases) : Expr() public partial record When(Expr Head, VarBinding[] Cases) : Expr()
{ {
public override TResult accept<TContext, TResult>(TContext context, IExprVisitor<TContext, TResult> visitor) public override TResult accept<TContext, TResult>(TContext context, IExprVisitor<TContext, TResult> visitor)
{ {

View File

@ -595,6 +595,26 @@ public class Interpreter : AST.IExprVisitor<Env, object>
public object visitWhenExpr(Env env, AST.When expr) public object visitWhenExpr(Env env, AST.When expr)
{ {
throw new System.NotImplementedException(); var head = evaluate(env, expr.Head);
// TODO use real info
var tok = new Token(TokenType.When, "when", null, 1);
foreach (var c in expr.Cases)
{
try
{
var newEnv = new Env(env);
c.Pattern.accept((head, newEnv), new PatternBinder());
return evaluate(newEnv, c.Value);
}
catch (PatternTagMismatchException)
{
continue;
}
catch (PatternTypeMismatchException e)
{
throw new RuntimeError(tok, e.Message);
}
}
throw new RuntimeError(tok, "No matching patterns.");
} }
} }

View File

@ -308,7 +308,7 @@ class Parser
Expr head = expression(); Expr head = expression();
consume(TokenType.Is, "Expect 'is' after expression."); consume(TokenType.Is, "Expect 'is' after expression.");
List<Binding> cases = new List<Binding>(); List<VarBinding> cases = new List<VarBinding>();
cases.Add(parseCase()); cases.Add(parseCase());
while (match(TokenType.Comma)) while (match(TokenType.Comma))
{ {
@ -316,7 +316,7 @@ class Parser
} }
return new When(head, cases.ToArray()); return new When(head, cases.ToArray());
Binding parseCase() VarBinding parseCase()
{ {
Pattern pat = pattern(); Pattern pat = pattern();
consume(TokenType.DoubleArrow, "Expect '=>' after pattern."); consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");

View File

@ -45,7 +45,7 @@ let exprTypes =
Name = "Bindings" } Name = "Bindings" }
{ Type = "Expr"; Name = "Body" } ] } { Type = "Expr"; Name = "Body" } ] }
{ Name = "When" { Name = "When"
Fields = [ { Type = "Expr"; Name = "Head" }; { Type = "Binding[]"; Name = "Cases" } ] } ] Fields = [ { Type = "Expr"; Name = "Head" }; { Type = "VarBinding[]"; Name = "Cases" } ] } ]
let patternTypes = let patternTypes =
[ { Name = "SimplePattern" [ { Name = "SimplePattern"