nushell/crates/nu-protocol/src/engine/evaluation_context.rs

136 lines
3.4 KiB
Rust
Raw Normal View History

2021-09-02 20:21:37 +02:00
use super::EngineState;
2021-08-16 00:33:34 +02:00
use std::{cell::RefCell, collections::HashMap, rc::Rc};
2021-10-09 03:02:01 +02:00
use crate::{Example, ShellError, Signature, Value, VarId};
2021-08-16 00:33:34 +02:00
2021-09-03 04:57:18 +02:00
#[derive(Clone)]
2021-09-02 20:21:37 +02:00
pub struct EvaluationContext {
2021-10-25 06:01:02 +02:00
pub engine_state: Box<EngineState>,
2021-08-16 00:33:34 +02:00
pub stack: Stack,
}
2021-09-02 20:21:37 +02:00
impl EvaluationContext {
2021-08-16 00:33:34 +02:00
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
self.stack.get_var(var_id)
}
2021-09-02 20:21:37 +02:00
pub fn enter_scope(&self) -> EvaluationContext {
2021-08-16 00:33:34 +02:00
Self {
2021-09-02 10:25:22 +02:00
engine_state: self.engine_state.clone(),
2021-08-16 00:33:34 +02:00
stack: self.stack.clone().enter_scope(),
}
}
2021-10-25 06:01:02 +02:00
pub fn add_var(&mut self, var_id: VarId, value: Value) {
2021-08-16 00:33:34 +02:00
self.stack.add_var(var_id, value);
}
2021-10-25 06:01:02 +02:00
pub fn add_env_var(&mut self, var: String, value: String) {
2021-08-16 00:33:34 +02:00
self.stack.add_env_var(var, value);
}
pub fn print_stack(&self) {
self.stack.print_stack();
}
2021-10-01 23:53:13 +02:00
2021-10-09 03:02:01 +02:00
pub fn get_signatures(&self) -> Vec<Signature> {
2021-10-25 06:01:02 +02:00
self.engine_state.get_signatures()
2021-10-09 03:02:01 +02:00
}
pub fn get_signatures_with_examples(&self) -> Vec<(Signature, Vec<Example>)> {
2021-10-25 06:01:02 +02:00
self.engine_state.get_signatures_with_examples()
2021-10-01 23:53:13 +02:00
}
2021-08-16 00:33:34 +02:00
}
2021-10-25 06:01:02 +02:00
#[derive(Debug, Clone)]
2021-08-16 00:33:34 +02:00
pub struct StackFrame {
pub vars: HashMap<VarId, Value>,
pub env_vars: HashMap<String, String>,
}
#[derive(Clone, Debug)]
2021-10-25 06:01:02 +02:00
pub struct Stack(Vec<StackFrame>);
2021-08-16 00:33:34 +02:00
impl Default for Stack {
fn default() -> Self {
Self::new()
}
}
impl Stack {
pub fn new() -> Stack {
2021-10-25 06:01:02 +02:00
Stack(vec![StackFrame {
2021-08-16 00:33:34 +02:00
vars: HashMap::new(),
env_vars: HashMap::new(),
2021-10-25 06:01:02 +02:00
}])
2021-08-16 00:33:34 +02:00
}
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
2021-10-25 06:01:02 +02:00
for frame in self.0.iter().rev() {
if let Some(v) = frame.vars.get(&var_id) {
return Ok(v.clone());
2021-08-16 00:33:34 +02:00
}
}
2021-10-25 06:01:02 +02:00
Err(ShellError::InternalError("variable not found".into()))
2021-08-16 00:33:34 +02:00
}
2021-10-25 06:01:02 +02:00
pub fn add_var(&mut self, var_id: VarId, value: Value) {
let frame = self
.0
.last_mut()
.expect("internal error: can't access stack frame");
frame.vars.insert(var_id, value);
2021-08-16 00:33:34 +02:00
}
2021-10-25 06:01:02 +02:00
pub fn add_env_var(&mut self, var: String, value: String) {
let frame = self
.0
.last_mut()
.expect("internal error: can't access stack frame");
frame.env_vars.insert(var, value);
2021-08-16 00:33:34 +02:00
}
2021-10-25 06:01:02 +02:00
pub fn enter_scope(&self) -> Stack {
// FIXME: VERY EXPENSIVE to clone entire stack
let mut output = self.clone();
output.0.push(StackFrame {
2021-08-16 00:33:34 +02:00
vars: HashMap::new(),
env_vars: HashMap::new(),
2021-10-25 06:01:02 +02:00
});
output
2021-08-16 00:33:34 +02:00
}
2021-09-19 21:29:58 +02:00
pub fn get_env_vars(&self) -> HashMap<String, String> {
2021-10-25 06:01:02 +02:00
let mut output = HashMap::new();
for frame in &self.0 {
output.extend(frame.env_vars.clone().into_iter());
}
output
2021-09-19 21:29:58 +02:00
}
2021-10-02 15:10:28 +02:00
pub fn get_env_var(&self, name: &str) -> Option<String> {
2021-10-25 06:01:02 +02:00
for frame in self.0.iter().rev() {
if let Some(v) = frame.env_vars.get(name) {
return Some(v.to_string());
}
}
None
2021-10-02 15:10:28 +02:00
}
2021-08-16 00:33:34 +02:00
pub fn print_stack(&self) {
2021-10-25 06:01:02 +02:00
for frame in self.0.iter().rev() {
println!("===frame===");
println!("vars:");
for (var, val) in &frame.vars {
println!(" {}: {:?}", var, val);
}
println!("env vars:");
for (var, val) in &frame.env_vars {
println!(" {}: {:?}", var, val);
}
2021-08-16 00:33:34 +02:00
}
}
}