Interpreter - Data structure for functions
This commit is contained in:
parent
f02d15fa83
commit
ca3ec46bdc
1 changed files with 65 additions and 0 deletions
|
@ -0,0 +1,65 @@
|
||||||
|
use itertools::izip;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast,
|
||||||
|
errors::InterpreterError,
|
||||||
|
interpreter::{Environment, Interpretable},
|
||||||
|
tokens::Token,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Callable, EnvironmentRef, Value};
|
||||||
|
|
||||||
|
/// A function implemented in the Lox-ish language.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Function {
|
||||||
|
name: Token,
|
||||||
|
params: Vec<Token>,
|
||||||
|
body: Vec<ast::StmtNode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ast::StmtNode> for Function {
|
||||||
|
fn from(node: &ast::StmtNode) -> Self {
|
||||||
|
if let ast::StmtNode::FunDecl { name, params, body } = node {
|
||||||
|
Self {
|
||||||
|
name: name.clone(),
|
||||||
|
params: params.clone(),
|
||||||
|
body: body.clone(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("initializing Function from non-function statement");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Callable for Function {
|
||||||
|
fn arity(&self) -> usize {
|
||||||
|
self.params.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(
|
||||||
|
&self,
|
||||||
|
environment: &EnvironmentRef,
|
||||||
|
arguments: Vec<Value>,
|
||||||
|
) -> Result<Value, InterpreterError> {
|
||||||
|
assert_eq!(arguments.len(), self.arity());
|
||||||
|
let param_env = Environment::create_child(environment);
|
||||||
|
for (arg, value) in izip!(self.params.iter(), arguments.into_iter()) {
|
||||||
|
param_env.borrow_mut().define(&arg, Some(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
let child = Environment::create_child(¶m_env);
|
||||||
|
for stmt in self.body.iter() {
|
||||||
|
let result = stmt.interpret(&child)?;
|
||||||
|
if result.is_flow_control() {
|
||||||
|
panic!("unexpected flow control");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Value::Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Function {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
format!("<fun {}>", self.name.lexeme)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue