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), |     UndefinedVariable(String), | ||||||
|     InternalError(String), |     InternalError(String), | ||||||
|     InvalidAssignmentTarget(String), |     InvalidAssignmentTarget(String), | ||||||
|  |     RuntimeError(String), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
|  |  | ||||||
|  | @ -33,8 +33,9 @@ impl Callable { | ||||||
| 
 | 
 | ||||||
| // Representation of an in-language value.
 | // Representation of an in-language value.
 | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| enum Value { | pub enum Value { | ||||||
|     Literal(Literal), |     Literal(Literal), | ||||||
|  |     Callable(Callable), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl From<Literal> for Value { | impl From<Literal> for Value { | ||||||
|  | @ -235,7 +236,7 @@ impl Interpreter { | ||||||
|             Expr::Binary(binary) => self.eval_binary(binary), |             Expr::Binary(binary) => self.eval_binary(binary), | ||||||
|             Expr::Variable(var) => self.get_var(var), |             Expr::Variable(var) => self.get_var(var), | ||||||
|             Expr::Logical(log) => self.eval_logical(log), |             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.
 | // Interpreter functions not dependent on interpreter-state.
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue