Evaluate when-exprs
This commit is contained in:
		| @@ -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) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -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."); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -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."); | ||||||
|   | |||||||
| @@ -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" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user