2021-10-25 16:58:58 +00:00
|
|
|
use std::collections::HashMap;
|
2021-08-15 22:33:34 +00:00
|
|
|
|
2021-10-25 17:46:26 +00:00
|
|
|
use crate::{ShellError, Value, VarId};
|
2021-08-15 22:33:34 +00:00
|
|
|
|
2021-10-25 04:01:02 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2021-10-25 20:04:23 +00:00
|
|
|
pub struct Stack {
|
2021-08-15 22:33:34 +00:00
|
|
|
pub vars: HashMap<VarId, Value>,
|
|
|
|
pub env_vars: HashMap<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Stack {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Stack {
|
|
|
|
pub fn new() -> Stack {
|
2021-10-25 20:04:23 +00:00
|
|
|
Stack {
|
2021-08-15 22:33:34 +00:00
|
|
|
vars: HashMap::new(),
|
|
|
|
env_vars: HashMap::new(),
|
2021-10-25 20:04:23 +00:00
|
|
|
}
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
|
2021-10-25 20:04:23 +00:00
|
|
|
if let Some(v) = self.vars.get(&var_id) {
|
|
|
|
return Ok(v.clone());
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
2021-10-25 04:01:02 +00:00
|
|
|
Err(ShellError::InternalError("variable not found".into()))
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 04:01:02 +00:00
|
|
|
pub fn add_var(&mut self, var_id: VarId, value: Value) {
|
2021-10-25 20:04:23 +00:00
|
|
|
self.vars.insert(var_id, value);
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 04:01:02 +00:00
|
|
|
pub fn add_env_var(&mut self, var: String, value: String) {
|
2021-10-25 20:04:23 +00:00
|
|
|
self.env_vars.insert(var, value);
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 20:04:23 +00:00
|
|
|
pub fn collect_captures(&self, captures: &[VarId]) -> Stack {
|
|
|
|
let mut output = Stack::new();
|
|
|
|
|
|
|
|
for capture in captures {
|
|
|
|
output.vars.insert(
|
|
|
|
*capture,
|
|
|
|
self.get_var(*capture)
|
|
|
|
.expect("internal error: capture of missing variable"),
|
|
|
|
);
|
|
|
|
}
|
2021-10-25 04:01:02 +00:00
|
|
|
|
|
|
|
output
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
|
2021-10-25 20:04:23 +00:00
|
|
|
// pub fn enter_scope(&self) -> Stack {
|
|
|
|
// // FIXME: VERY EXPENSIVE to clone entire stack
|
|
|
|
// let mut output = self.clone();
|
|
|
|
// output.0.push(StackFrame {
|
|
|
|
// vars: HashMap::new(),
|
|
|
|
// env_vars: HashMap::new(),
|
|
|
|
// });
|
|
|
|
|
|
|
|
// output
|
|
|
|
// }
|
|
|
|
|
2021-09-19 19:29:58 +00:00
|
|
|
pub fn get_env_vars(&self) -> HashMap<String, String> {
|
2021-10-25 20:04:23 +00:00
|
|
|
// let mut output = HashMap::new();
|
2021-10-25 04:01:02 +00:00
|
|
|
|
2021-10-25 20:04:23 +00:00
|
|
|
// for frame in &self.0 {
|
|
|
|
// output.extend(frame.env_vars.clone().into_iter());
|
|
|
|
// }
|
2021-10-25 04:01:02 +00:00
|
|
|
|
2021-10-25 20:04:23 +00:00
|
|
|
// output
|
|
|
|
self.env_vars.clone()
|
2021-09-19 19:29:58 +00:00
|
|
|
}
|
|
|
|
|
2021-10-02 13:10:28 +00:00
|
|
|
pub fn get_env_var(&self, name: &str) -> Option<String> {
|
2021-10-25 20:04:23 +00:00
|
|
|
// for frame in self.0.iter().rev() {
|
|
|
|
if let Some(v) = self.env_vars.get(name) {
|
|
|
|
return Some(v.to_string());
|
2021-10-25 04:01:02 +00:00
|
|
|
}
|
2021-10-25 20:04:23 +00:00
|
|
|
// }
|
2021-10-25 04:01:02 +00:00
|
|
|
None
|
2021-10-02 13:10:28 +00:00
|
|
|
}
|
|
|
|
|
2021-08-15 22:33:34 +00:00
|
|
|
pub fn print_stack(&self) {
|
2021-10-25 20:04:23 +00:00
|
|
|
// for frame in self.0.iter().rev() {
|
|
|
|
// println!("===frame===");
|
|
|
|
println!("vars:");
|
|
|
|
for (var, val) in &self.vars {
|
|
|
|
println!(" {}: {:?}", var, val);
|
|
|
|
}
|
|
|
|
println!("env vars:");
|
|
|
|
for (var, val) in &self.env_vars {
|
|
|
|
println!(" {}: {:?}", var, val);
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
2021-10-25 20:04:23 +00:00
|
|
|
// }
|
2021-08-15 22:33:34 +00:00
|
|
|
}
|
|
|
|
}
|