Skip to content
Snippets Groups Projects
Commit c1fb7def authored by David Söderberg's avatar David Söderberg
Browse files

Upload New File

parent 4f6f7217
No related branches found
No related tags found
No related merge requests found
use std::fmt;
use crate::ast::*;
use std::collections::{HashMap, VecDeque};
pub type FnEnv<'a> = HashMap<&'a str, &'a Func>;
impl Func {
pub fn get_id(&self) -> &str {
&self.name
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Val {
Num(i32),
Bool(bool),
Unit,
Uninitialized,
RefMut(String),
Ref(String),
}
#[derive(Debug)]
pub enum Bc {
Free,
Shared,
Mut,
Ref(Box<Bc>),
}
pub fn progam_to_env(prog: &Program) -> FnEnv {
let program_funcs = &prog.funcs;
program_funcs.into_iter().map(|f| (f.get_id(), f)).collect()
}
#[derive(Debug)]
pub struct VarMem(VecDeque<HashMap<String, Type>>);
impl VarMem {
pub fn new() -> Self {
VarMem(VecDeque::<HashMap<String, Type>>::new())
}
pub fn get_type(&self, id: String) -> Option<&Type> {
self.0.iter().find_map(|hm| {
hm.get(id.as_str())
.map(|t| (t))
})
}
pub fn get_mut_type(&mut self, id: String) -> Option<&mut Type> {
self.0.iter_mut().find_map(|hm| hm.get_mut(id.as_str()))
}
pub fn new_id(&mut self, id: String, ty: Type) {
let hm = self.0.front_mut().unwrap();
println!("[VarMem] Inserted id {:?} into scope {:?}", &id, hm);
hm.insert(id, ty);
}
pub fn update(&mut self, id: String, ty: Type) {
println!("[VarMem] Updating environment variable {:?}", id);
match self.get_mut_type(id.clone()) {
Some(ot) => match ot {
Type::Unknown => {
(*ot) = ty;
}
t => match (*t).eq(&ty) {
true => println!("[VarMem] Updated environment variable {:?} to type {:?}", id, ty),
false => panic!("[VarMem] Update types are different {:?} <> {:?}", t, ty),
},
},
None => panic!("[VarMem] Error variable {:?} is not found", id),
}
}
pub fn push_empty_scope(&mut self) {
self.0.push_front(HashMap::new());
}
pub fn push_param_scope(&mut self, args: HashMap<String, Type>) {
self.0.push_front(args)
}
pub fn pop_scope(&mut self) {
self.0.pop_front();
}
}
#[derive(Debug)]
pub struct BcMem(VecDeque<HashMap<String, Bc>>);
impl BcMem {
pub fn new() -> Self {
BcMem(VecDeque::<HashMap<String, Bc>>::new())
}
pub fn get(&self, id: String) -> Option<&Bc> {
self.0.iter().find_map(|hm| {
hm.get(id.as_str())
.map(|bc| (bc))
})
}
pub fn get_mut(&mut self, id: String) -> Option<&mut Bc> {
self.0.iter_mut().find_map(|hm| hm.get_mut(id.as_str()))
}
pub fn new_id(&mut self, id: String, bc: Bc) {
let hm = self.0.front_mut().unwrap();
println!("[BcMem] Inserted id {:?} into scope {:?}", &id, hm);
hm.insert(id, bc);
}
pub fn update(&mut self, id: String, bc: Bc) {
println!("[BcMem] Updating environment variable {:?}", id);
match self.get_mut(id.clone()) {
Some(b) => match b {
Bc::Free => {
*b = bc;
}
Bc::Shared => match bc {
Bc::Shared => println!("[BcMem] Updated environment variable {:?} to bc {:?}", id, bc),
Bc::Mut => panic!("[BcMem] Error tried update editable variable {:?}", id),
_ => panic!("[BcMem] Error unimplemented borrow state in Bc::Shared"),
},
_ => panic!("[BcMem] Error unimplemented borrow state"),
},
None => panic!("[BcMem] Error variable {:?} is not found", id),
}
}
pub fn push_empty_scope(&mut self) {
self.0.push_front(HashMap::new());
}
pub fn push_param_scope(&mut self, args: HashMap<String, Bc>) {
self.0.push_front(args)
}
pub fn pop_scope(&mut self) {
self.0.pop_front();
}
}
#[derive(Debug)]
pub struct Mem(VecDeque<HashMap<String, (bool, Val)>>);
impl Mem {
pub fn new() -> Self {
Mem(VecDeque::<HashMap<String, (bool, Val)>>::new())
}
pub fn get(&self, id: String) -> Option<&Val> {
self.0.iter().find_map(|hm| match hm.get(id.as_str()) {
Some((_, v)) => Some(v),
_ => None,
})
}
pub fn get_mut(&mut self, id: String) -> Option<&mut Val> {
self.0
.iter_mut()
.find_map(|hm| match hm.get_mut(id.as_str()) {
Some((true, v)) => Some(v),
Some((_, v)) => {
match v {
Val::Uninitialized => Some(v),
Val::RefMut(_) => {
println!("[Mem] Gotten &mut {:?}", v);
Some(v)
}
_ => panic!("[Mem] Error cannot access {:?} as a mutable", id),
}
}
_ => None,
})
}
pub fn new_id(&mut self, id: String, is_mut: bool) {
let hm = self.0.front_mut().unwrap();
println!("[Mem] Inserted id {:?}, in scope {:?}", id, hm);
hm.insert(id, (is_mut, Val::Uninitialized));
}
pub fn update(&mut self, id: String, val: Val) {
match self.get_mut(id.clone()) {
Some(v_ref) => {
println!("[Mem] Variable {:?} was found", id);
*v_ref = val;
}
None => {
panic!("[Mem] Error variable {:?} was not found", id);
}
};
}
pub fn push_empty_scope(&mut self) {
self.0.push_front(HashMap::new());
}
pub fn push_param_scope(&mut self, args: HashMap<String, (bool, Val)>) {
self.0.push_front(args)
}
pub fn pop_scope(&mut self) {
self.0.pop_front();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment