Interpreter - Made the interpreter state partially public
* This allows Callable to be public, which is required for Value * State internals are still hidden behind pub(super)
This commit is contained in:
parent
10223cbb4e
commit
c97ad0ad7e
2 changed files with 30 additions and 17 deletions
|
@ -5,7 +5,7 @@ use crate::errors::SloxResult;
|
||||||
use super::{InterpreterState, Value};
|
use super::{InterpreterState, Value};
|
||||||
|
|
||||||
/// A callable is some object that supports being called.
|
/// A callable is some object that supports being called.
|
||||||
pub(super) trait Callable: Debug + ToString {
|
pub trait Callable: Debug + ToString {
|
||||||
/// Return the amount of arguments supported by the callable.
|
/// Return the amount of arguments supported by the callable.
|
||||||
fn arity(&self) -> usize;
|
fn arity(&self) -> usize;
|
||||||
|
|
||||||
|
@ -15,4 +15,4 @@ pub(super) trait Callable: Debug + ToString {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reference to a callable.
|
/// A reference to a callable.
|
||||||
pub(super) type CallableRef = Rc<RefCell<dyn Callable>>;
|
pub type CallableRef = Rc<RefCell<dyn Callable>>;
|
||||||
|
|
|
@ -10,12 +10,7 @@ use crate::{
|
||||||
|
|
||||||
/// Evaluate an interpretable, returning its value.
|
/// Evaluate an interpretable, returning its value.
|
||||||
pub fn evaluate(ast: &ast::ProgramNode, vars: ResolvedVariables) -> SloxResult<Value> {
|
pub fn evaluate(ast: &ast::ProgramNode, vars: ResolvedVariables) -> SloxResult<Value> {
|
||||||
let env = Rc::new(RefCell::new(Environment::default()));
|
let mut state = InterpreterState::new(&vars);
|
||||||
let mut state = InterpreterState{
|
|
||||||
environment: env.clone(),
|
|
||||||
globals: env,
|
|
||||||
variables: &vars,
|
|
||||||
};
|
|
||||||
ast.interpret(&mut state).map(|v| v.result())
|
ast.interpret(&mut state).map(|v| v.result())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +20,36 @@ pub fn evaluate(ast: &ast::ProgramNode, vars: ResolvedVariables) -> SloxResult<V
|
||||||
|
|
||||||
/// The state of the interpreter.
|
/// The state of the interpreter.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct InterpreterState<'a> {
|
pub struct InterpreterState<'a> {
|
||||||
pub(super) globals: EnvironmentRef,
|
pub(super) globals: EnvironmentRef,
|
||||||
pub(super) environment: EnvironmentRef,
|
pub(super) environment: EnvironmentRef,
|
||||||
pub(super) variables: &'a ResolvedVariables,
|
pub(super) variables: &'a ResolvedVariables,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> InterpreterState<'a> {
|
||||||
|
/// Initialize the interpreter state from the resolved variables map.
|
||||||
|
fn new(vars: &'a ResolvedVariables) -> Self {
|
||||||
|
let env = Rc::new(RefCell::new(Environment::default()));
|
||||||
|
Self {
|
||||||
|
environment: env.clone(),
|
||||||
|
globals: env,
|
||||||
|
variables: &vars,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a child state.
|
||||||
|
fn create_child<'b>(parent: &InterpreterState<'b>) -> Self
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
|
InterpreterState {
|
||||||
|
environment: Environment::create_child(&parent.environment),
|
||||||
|
globals: parent.globals.clone(),
|
||||||
|
variables: parent.variables,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Interpreter flow control, which may be either a value, a loop break or a
|
/// Interpreter flow control, which may be either a value, a loop break or a
|
||||||
/// loop continuation.
|
/// loop continuation.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -129,9 +148,7 @@ impl Interpretable for ast::StmtNode {
|
||||||
is_break,
|
is_break,
|
||||||
loop_name,
|
loop_name,
|
||||||
} => self.on_loop_control_statemement(*is_break, loop_name),
|
} => self.on_loop_control_statemement(*is_break, loop_name),
|
||||||
ast::StmtNode::Return { token: _, value } => {
|
ast::StmtNode::Return { token: _, value } => self.on_return_statement(es, value),
|
||||||
self.on_return_statement(es, value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,11 +201,7 @@ impl ast::StmtNode {
|
||||||
|
|
||||||
/// Execute the contents of a block.
|
/// Execute the contents of a block.
|
||||||
fn on_block(&self, es: &mut InterpreterState, stmts: &[ast::StmtNode]) -> InterpreterResult {
|
fn on_block(&self, es: &mut InterpreterState, stmts: &[ast::StmtNode]) -> InterpreterResult {
|
||||||
let mut child = InterpreterState{
|
let mut child = InterpreterState::create_child(es);
|
||||||
environment: Environment::create_child(&es.environment),
|
|
||||||
globals: es.globals.clone(),
|
|
||||||
variables: es.variables,
|
|
||||||
};
|
|
||||||
for stmt in stmts.iter() {
|
for stmt in stmts.iter() {
|
||||||
let result = stmt.interpret(&mut child)?;
|
let result = stmt.interpret(&mut child)?;
|
||||||
if result.is_flow_control() {
|
if result.is_flow_control() {
|
||||||
|
|
Loading…
Reference in a new issue