This commit is contained in:
JT
2021-10-26 09:04:23 +13:00
parent f84582ca2b
commit d29208dd9e
14 changed files with 265 additions and 81 deletions

View File

@ -1,6 +1,6 @@
use std::ops::{Index, IndexMut};
use crate::{DeclId, Signature};
use crate::{DeclId, Signature, VarId};
use super::Statement;
@ -9,6 +9,7 @@ pub struct Block {
pub signature: Box<Signature>,
pub stmts: Vec<Statement>,
pub exports: Vec<(Vec<u8>, DeclId)>, // Assuming just defs for now
pub captures: Vec<VarId>,
}
impl Block {
@ -47,6 +48,7 @@ impl Block {
signature: Box::new(Signature::new("")),
stmts: vec![],
exports: vec![],
captures: vec![],
}
}
@ -55,6 +57,7 @@ impl Block {
signature: self.signature,
stmts: self.stmts,
exports,
captures: self.captures,
}
}
}
@ -68,6 +71,7 @@ where
signature: Box::new(Signature::new("")),
stmts: stmts.collect(),
exports: vec![],
captures: vec![],
}
}
}

View File

@ -13,6 +13,7 @@ pub enum Expr {
RangeOperator,
),
Var(VarId),
VarDecl(VarId),
Call(Box<Call>),
ExternalCall(String, Span, Vec<Expression>),
Operator(Operator),

View File

@ -77,6 +77,7 @@ impl Expression {
pub fn as_var(&self) -> Option<VarId> {
match self.expr {
Expr::Var(var_id) => Some(var_id),
Expr::VarDecl(var_id) => Some(var_id),
_ => None,
}
}

View File

@ -3,14 +3,11 @@ use std::collections::HashMap;
use crate::{ShellError, Value, VarId};
#[derive(Debug, Clone)]
pub struct StackFrame {
pub struct Stack {
pub vars: HashMap<VarId, Value>,
pub env_vars: HashMap<String, String>,
}
#[derive(Clone, Debug)]
pub struct Stack(Vec<StackFrame>);
impl Default for Stack {
fn default() -> Self {
Self::new()
@ -19,77 +16,82 @@ impl Default for Stack {
impl Stack {
pub fn new() -> Stack {
Stack(vec![StackFrame {
Stack {
vars: HashMap::new(),
env_vars: HashMap::new(),
}])
}
}
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
for frame in self.0.iter().rev() {
if let Some(v) = frame.vars.get(&var_id) {
return Ok(v.clone());
}
if let Some(v) = self.vars.get(&var_id) {
return Ok(v.clone());
}
Err(ShellError::InternalError("variable not found".into()))
}
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);
self.vars.insert(var_id, value);
}
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);
self.env_vars.insert(var, value);
}
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(),
});
pub fn collect_captures(&self, captures: &[VarId]) -> Stack {
let mut output = Stack::new();
output
}
pub fn get_env_vars(&self) -> HashMap<String, String> {
let mut output = HashMap::new();
for frame in &self.0 {
output.extend(frame.env_vars.clone().into_iter());
for capture in captures {
output.vars.insert(
*capture,
self.get_var(*capture)
.expect("internal error: capture of missing variable"),
);
}
output
}
// 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
// }
pub fn get_env_vars(&self) -> HashMap<String, String> {
// let mut output = HashMap::new();
// for frame in &self.0 {
// output.extend(frame.env_vars.clone().into_iter());
// }
// output
self.env_vars.clone()
}
pub fn get_env_var(&self, name: &str) -> Option<String> {
for frame in self.0.iter().rev() {
if let Some(v) = frame.env_vars.get(name) {
return Some(v.to_string());
}
// for frame in self.0.iter().rev() {
if let Some(v) = self.env_vars.get(name) {
return Some(v.to_string());
}
// }
None
}
pub fn print_stack(&self) {
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);
}
// 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);
}
// }
}
}