Skip to content

Commit c9d98f2

Browse files
committed
[refactor] Adding a new definition for environment.
1 parent 16f656e commit c9d98f2

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

src/environment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod environment;

src/environment/environment.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
use crate::ir::ast::Function;
3+
use crate::ir::ast::Name;
4+
5+
use std::collections::HashMap;
6+
use std::collections::LinkedList;
7+
8+
pub struct Scope<A> {
9+
pub variables: HashMap<Name, A>,
10+
pub functions: HashMap<Name, Function>
11+
}
12+
13+
impl<A> Scope<A> {
14+
fn new() -> Scope<A> {
15+
Scope { variables: HashMap::new(), functions: HashMap::new() }
16+
}
17+
18+
fn map_variable(&mut self, var: Name, value: A) -> () {
19+
self.variables.insert(var, value);
20+
return ()
21+
}
22+
23+
fn lookup(&mut self, var: Name) -> Option<&A> {
24+
self.variables.get(&var)
25+
}
26+
}
27+
28+
pub struct Environment<A> {
29+
pub globals: Scope<A>,
30+
pub stack: LinkedList<Scope<A>>
31+
}
32+
33+
impl<A> Environment<A> {
34+
35+
pub fn new() -> Environment<A> {
36+
Environment { globals: Scope::new(), stack: LinkedList::new() }
37+
}
38+
39+
pub fn map_variable(&mut self, var: Name, value: A) -> () {
40+
match self.stack.front_mut() {
41+
None => self.globals.map_variable(var, value),
42+
Some(top) => top.map_variable(var, value)
43+
44+
};
45+
return ()
46+
}
47+
48+
pub fn lookup(&mut self, var: Name) -> Option<&A> {
49+
match self.stack.front_mut() {
50+
None => self.globals.lookup(var),
51+
Some(top) => top.lookup(var)
52+
}
53+
}
54+
55+
pub fn push(&mut self) -> () {
56+
self.stack.push_front(Scope::new());
57+
}
58+
59+
pub fn pop(&mut self) -> () {
60+
self.stack.pop_front();
61+
}
62+
}
63+
64+
65+
#[cfg(test)]
66+
mod tests {
67+
use crate::environment::environment::{Scope, Environment};
68+
69+
#[test]
70+
fn eval_map_and_lookup_var() {
71+
let mut s: Scope<i32> = Scope::new();
72+
73+
s.map_variable("x".to_string(), 32);
74+
s.map_variable("y".to_string(), 23);
75+
76+
assert_eq!(Some(32), s.lookup("x".to_string()).copied());
77+
assert_eq!(Some(23), s.lookup("y".to_string()).copied());
78+
}
79+
80+
#[test]
81+
fn eval_environment() {
82+
let mut env: Environment<i32> = Environment::new();
83+
84+
env.map_variable("x".to_string(), 32);
85+
86+
env.push();
87+
88+
env.map_variable("x".to_string(), 55);
89+
env.map_variable("y".to_string(), 23);
90+
91+
assert_eq!(Some(55), env.lookup("x".to_string()).copied());
92+
assert_eq!(Some(23), env.lookup("y".to_string()).copied());
93+
assert_eq!(None, env.lookup("a".to_string()).copied());
94+
95+
env.pop();
96+
97+
assert_eq!(Some(32), env.lookup("x".to_string()).copied());
98+
assert_eq!(None, env.lookup("y".to_string()).copied());
99+
}
100+
101+
102+
}

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod interpreter;
1414
pub mod ir;
1515
pub mod parser;
1616
pub mod tc;
17+
pub mod environment;
1718

1819
fn main() {
1920
println!("Hello, world!");

0 commit comments

Comments
 (0)