mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
104 lines
2.4 KiB
Rust
104 lines
2.4 KiB
Rust
|
|
use std::fmt::{Debug, Display};
|
||
|
|
|
||
|
|
use crate::parser::Stmt;
|
||
|
|
|
||
|
|
use super::environment::{Environment, Scope};
|
||
|
|
use super::interpret::EvalResult;
|
||
|
|
use super::Value;
|
||
|
|
|
||
|
|
#[derive(Debug, Clone)]
|
||
|
|
pub struct LoxFunction {
|
||
|
|
name: String,
|
||
|
|
closure: Scope,
|
||
|
|
param_names: Vec<String>,
|
||
|
|
body: Box<Stmt>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl LoxFunction {
|
||
|
|
pub fn new(name: impl Into<String>, param_names: Vec<String>, body: Stmt) -> Self {
|
||
|
|
let name = name.into();
|
||
|
|
let body = Box::new(body);
|
||
|
|
LoxFunction {
|
||
|
|
name,
|
||
|
|
closure: Scope::new(),
|
||
|
|
param_names,
|
||
|
|
body,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn arity(&self) -> usize {
|
||
|
|
self.param_names.len()
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn name(&self) -> &str {
|
||
|
|
&self.name
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn closure(&self) -> &Scope {
|
||
|
|
&self.closure
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn param_names(&self) -> impl Iterator<Item = &String> {
|
||
|
|
self.param_names.iter()
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn body(&self) -> &Stmt {
|
||
|
|
&self.body
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Display for LoxFunction {
|
||
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
|
write!(f, "<fun {}>", self.name)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*====================================================================================================================*/
|
||
|
|
|
||
|
|
pub type ExternFunClosure = fn(Vec<Value>, &mut Environment) -> EvalResult<Value>;
|
||
|
|
|
||
|
|
#[derive(Clone)]
|
||
|
|
pub struct LoxExternFunction {
|
||
|
|
name: String,
|
||
|
|
|
||
|
|
closure: ExternFunClosure,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl LoxExternFunction {
|
||
|
|
pub fn new(name: impl Into<String>, closure: ExternFunClosure) -> Self {
|
||
|
|
let name = name.into();
|
||
|
|
|
||
|
|
LoxExternFunction { name, closure }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn register(self, env: &mut Environment) {
|
||
|
|
let name = self.name.clone();
|
||
|
|
let fun = Value::extern_function(self);
|
||
|
|
env.define(name, fun);
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn call(&self, args: Vec<Value>, env: &mut Environment) -> EvalResult<Value> {
|
||
|
|
(self.closure)(args, env)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Display for LoxExternFunction {
|
||
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
|
write!(f, "<extern fun {}>", self.name)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Debug for LoxExternFunction {
|
||
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
|
f.debug_struct("LoxExternFunction")
|
||
|
|
.field("name", &self.name)
|
||
|
|
.field("closure", &"<closure>")
|
||
|
|
.finish()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl PartialEq for LoxExternFunction {
|
||
|
|
fn eq(&self, other: &Self) -> bool {
|
||
|
|
self.name == other.name
|
||
|
|
}
|
||
|
|
}
|