@@ -4,12 +4,13 @@ use crate::ir::ast::Name;
44use std:: collections:: HashMap ;
55use std:: collections:: LinkedList ;
66
7+ #[ derive( Clone ) ]
78pub struct Scope < A > {
89 pub variables : HashMap < Name , A > ,
910 pub functions : HashMap < Name , Function > ,
1011}
1112
12- impl < A > Scope < A > {
13+ impl < A : Clone > Scope < A > {
1314 fn new ( ) -> Scope < A > {
1415 Scope {
1516 variables : HashMap :: new ( ) ,
@@ -22,17 +23,23 @@ impl<A> Scope<A> {
2223 return ( ) ;
2324 }
2425
25- fn lookup ( & mut self , var : Name ) -> Option < & A > {
26- self . variables . get ( & var)
26+ fn map_function ( & mut self , function : Function ) -> ( ) {
27+ self . functions . insert ( function. name . clone ( ) , function) ;
28+ return ( ) ;
29+ }
30+
31+ fn lookup ( & self , var : & Name ) -> Option < & A > {
32+ self . variables . get ( var)
2733 }
2834}
2935
36+ #[ derive( Clone ) ]
3037pub struct Environment < A > {
3138 pub globals : Scope < A > ,
3239 pub stack : LinkedList < Scope < A > > ,
3340}
3441
35- impl < A > Environment < A > {
42+ impl < A : Clone > Environment < A > {
3643 pub fn new ( ) -> Environment < A > {
3744 Environment {
3845 globals : Scope :: new ( ) ,
@@ -48,13 +55,22 @@ impl<A> Environment<A> {
4855 return ( ) ;
4956 }
5057
51- pub fn lookup ( & mut self , var : Name ) -> Option < & A > {
52- match self . stack . front_mut ( ) {
58+ pub fn map_function ( & mut self , function : Function ) -> ( ) {
59+ self . globals . map_function ( function) ;
60+ return ( ) ;
61+ }
62+
63+ pub fn lookup ( & self , var : & Name ) -> Option < & A > {
64+ match self . stack . front ( ) {
5365 None => self . globals . lookup ( var) ,
5466 Some ( top) => top. lookup ( var) ,
5567 }
5668 }
5769
70+ pub fn scoped_function ( & self ) -> bool {
71+ !self . stack . is_empty ( )
72+ }
73+
5874 pub fn push ( & mut self ) -> ( ) {
5975 self . stack . push_front ( Scope :: new ( ) ) ;
6076 }
@@ -75,8 +91,8 @@ mod tests {
7591 s. map_variable ( "x" . to_string ( ) , 32 ) ;
7692 s. map_variable ( "y" . to_string ( ) , 23 ) ;
7793
78- assert_eq ! ( Some ( 32 ) , s. lookup( "x" . to_string( ) ) . copied( ) ) ;
79- assert_eq ! ( Some ( 23 ) , s. lookup( "y" . to_string( ) ) . copied( ) ) ;
94+ assert_eq ! ( Some ( 32 ) , s. lookup( & "x" . to_string( ) ) . copied( ) ) ;
95+ assert_eq ! ( Some ( 23 ) , s. lookup( & "y" . to_string( ) ) . copied( ) ) ;
8096 }
8197
8298 #[ test]
@@ -90,13 +106,13 @@ mod tests {
90106 env. map_variable ( "x" . to_string ( ) , 55 ) ;
91107 env. map_variable ( "y" . to_string ( ) , 23 ) ;
92108
93- assert_eq ! ( Some ( 55 ) , env. lookup( "x" . to_string( ) ) . copied( ) ) ;
94- assert_eq ! ( Some ( 23 ) , env. lookup( "y" . to_string( ) ) . copied( ) ) ;
95- assert_eq ! ( None , env. lookup( "a" . to_string( ) ) . copied( ) ) ;
109+ assert_eq ! ( Some ( 55 ) , env. lookup( & "x" . to_string( ) ) . copied( ) ) ;
110+ assert_eq ! ( Some ( 23 ) , env. lookup( & "y" . to_string( ) ) . copied( ) ) ;
111+ assert_eq ! ( None , env. lookup( & "a" . to_string( ) ) . copied( ) ) ;
96112
97113 env. pop ( ) ;
98114
99- assert_eq ! ( Some ( 32 ) , env. lookup( "x" . to_string( ) ) . copied( ) ) ;
100- assert_eq ! ( None , env. lookup( "y" . to_string( ) ) . copied( ) ) ;
115+ assert_eq ! ( Some ( 32 ) , env. lookup( & "x" . to_string( ) ) . copied( ) ) ;
116+ assert_eq ! ( None , env. lookup( & "y" . to_string( ) ) . copied( ) ) ;
101117 }
102118}
0 commit comments