feat(tazjin/rlox): Implement function call evaluation
Change-Id: I6767c3a1a9654475b4066415f8c026b9c5b5907a Reviewed-on: https://cl.tvl.fyi/c/depot/+/2382 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									090c96eae9
								
							
						
					
					
						commit
						26544aa5f0
					
				
					 2 changed files with 34 additions and 2 deletions
				
			
		|  | @ -12,6 +12,7 @@ pub enum ErrorKind { | |||
|     UndefinedVariable(String), | ||||
|     InternalError(String), | ||||
|     InvalidAssignmentTarget(String), | ||||
|     RuntimeError(String), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
|  |  | |||
|  | @ -33,8 +33,9 @@ impl Callable { | |||
| 
 | ||||
| // Representation of an in-language value.
 | ||||
| #[derive(Clone, Debug)] | ||||
| enum Value { | ||||
| pub enum Value { | ||||
|     Literal(Literal), | ||||
|     Callable(Callable), | ||||
| } | ||||
| 
 | ||||
| impl From<Literal> for Value { | ||||
|  | @ -235,7 +236,7 @@ impl Interpreter { | |||
|             Expr::Binary(binary) => self.eval_binary(binary), | ||||
|             Expr::Variable(var) => self.get_var(var), | ||||
|             Expr::Logical(log) => self.eval_logical(log), | ||||
|             Expr::Call(_) => unimplemented!(), | ||||
|             Expr::Call(call) => self.eval_call(call), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -321,6 +322,36 @@ impl Interpreter { | |||
|             }), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn eval_call<'a>(&mut self, call: &parser::Call<'a>) -> Result<Value, Error> { | ||||
|         let callable = match self.eval(&call.callee)? { | ||||
|             Value::Callable(c) => c, | ||||
|             Value::Literal(v) => { | ||||
|                 return Err(Error { | ||||
|                     line: call.paren.line, | ||||
|                     kind: ErrorKind::RuntimeError(format!("not callable: {:?}", v)), | ||||
|                 }) | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         let mut args = vec![]; | ||||
|         for arg in &call.args { | ||||
|             args.push(self.eval(arg)?); | ||||
|         } | ||||
| 
 | ||||
|         if callable.arity() != args.len() { | ||||
|             return Err(Error { | ||||
|                 line: call.paren.line, | ||||
|                 kind: ErrorKind::RuntimeError(format!( | ||||
|                     "Expected {} arguments, but got {}", | ||||
|                     callable.arity(), | ||||
|                     args.len(), | ||||
|                 )), | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         callable.call(args) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Interpreter functions not dependent on interpreter-state.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue