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);
}
}
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)
{

View File

@ -595,6 +595,26 @@ public class Interpreter : AST.IExprVisitor<Env, object>
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();
consume(TokenType.Is, "Expect 'is' after expression.");
List<Binding> cases = new List<Binding>();
List<VarBinding> cases = new List<VarBinding>();
cases.Add(parseCase());
while (match(TokenType.Comma))
{
@ -316,7 +316,7 @@ class Parser
}
return new When(head, cases.ToArray());
Binding parseCase()
VarBinding parseCase()
{
Pattern pat = pattern();
consume(TokenType.DoubleArrow, "Expect '=>' after pattern.");

View File

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