11use crate :: clojure_std;
22use crate :: clojure_string;
3- use crate :: namespace:: { Namespaces } ;
3+ use crate :: namespace:: Namespaces ;
44use crate :: repl:: Repl ;
55use crate :: rust_core;
66use crate :: symbol:: Symbol ;
@@ -23,24 +23,28 @@ pub struct EnvironmentVal {
2323 namespaces : Namespaces ,
2424}
2525impl EnvironmentVal {
26- // @TODO is this wrapper really necessary, or is it just inviting an invariant break?
26+ // @TODO is this wrapper really necessary, or is it just inviting an invariant break?
2727 /// Note; do not use. Does not enforce the invariant that namespace exist
28- /// Use change_or_create_namespace instead
28+ /// Use change_or_create_namespace instead
2929 fn change_namespace ( & self , name : Symbol ) {
3030 self . curr_ns_sym . replace ( name) ;
3131 }
32- fn change_or_create_namespace ( & self , symbol : & Symbol )
33- {
34- if self . has_namespace ( symbol) {
32+ fn change_or_create_namespace ( & self , symbol : & Symbol ) {
33+ if self . has_namespace ( symbol) {
3534 self . change_namespace ( symbol. unqualified ( ) ) ;
36- }
37- else {
35+ } else {
3836 self . create_namespace ( symbol) ;
3937 self . change_namespace ( symbol. unqualified ( ) ) ;
4038 }
4139 }
42- fn insert_into_namespace ( & self , namespace : & Symbol , sym : Symbol , val : Rc < Value > ) {
43- self . namespaces . insert_into_namespace ( namespace, & sym, val) ;
40+ fn add_referred_syms ( & self , namespace_sym : & Symbol , syms : HashMap < Symbol , Vec < Symbol > > ) {
41+ self . namespaces . add_referred_syms ( namespace_sym, syms) ;
42+ }
43+ fn add_referred_namespace ( & self , namespace_sym : & Symbol , referred_namespace_sym : & Symbol ) {
44+ self . namespaces . add_referred_namespace ( namespace_sym, referred_namespace_sym) ;
45+ }
46+ fn insert_into_namespace ( & self , namespace_sym : & Symbol , sym : Symbol , val : Rc < Value > ) {
47+ self . namespaces . insert_into_namespace ( namespace_sym, & sym, val) ;
4448 }
4549 fn insert_into_current_namespace ( & self , sym : Symbol , val : Rc < Value > ) {
4650 self . namespaces
@@ -56,7 +60,7 @@ impl EnvironmentVal {
5660 self . curr_ns_sym . borrow ( ) . clone ( )
5761 }
5862
59- fn create_namespace ( & self , symbol : & Symbol ) {
63+ fn create_namespace ( & self , symbol : & Symbol ) {
6064 self . namespaces . create_namespace ( symbol) ;
6165 }
6266 // @TODO as mentioned, we've been working with a memory model where values exist
@@ -90,8 +94,41 @@ use Environment::*;
9094impl Environment {
9195 pub fn has_namespace ( & self , symbol : & Symbol ) -> bool {
9296 match self . get_main_environment ( ) {
93- MainEnvironment ( env_val) => {
94- env_val. has_namespace ( symbol)
97+ MainEnvironment ( env_val) => env_val. has_namespace ( symbol) ,
98+ LocalEnvironment ( ..) => panic ! (
99+ "get_main_environment() returns LocalEnvironment,\
100+ but by definition should only return MainEnvironment"
101+ ) ,
102+ }
103+ }
104+ pub fn add_referred_syms ( & self , namespace_sym : & Symbol , syms : HashMap < Symbol , Vec < Symbol > > ) {
105+ match self . get_main_environment ( ) {
106+ MainEnvironment ( env_val) => {
107+ env_val. add_referred_syms ( namespace_sym, syms) ;
108+ }
109+ LocalEnvironment ( ..) => panic ! (
110+ "get_main_environment() returns LocalEnvironment,\
111+ but by definition should only return MainEnvironment"
112+ ) ,
113+ }
114+ }
115+ pub fn add_referred_syms_to_curr_namespace ( & self , syms : HashMap < Symbol , Vec < Symbol > > ) {
116+ match self . get_main_environment ( ) {
117+ MainEnvironment ( env_val) => {
118+ let namespace_sym = self . get_current_namespace ( ) ;
119+ env_val. add_referred_syms ( & namespace_sym, syms) ;
120+ }
121+ LocalEnvironment ( ..) => panic ! (
122+ "get_main_environment() returns LocalEnvironment,\
123+ but by definition should only return MainEnvironment"
124+ ) ,
125+ }
126+ }
127+ pub fn add_referred_namespace_to_curr_namespace ( & self , referred_namespace_sym : & Symbol ) {
128+ match self . get_main_environment ( ) {
129+ MainEnvironment ( env_val) => {
130+ let namespace_sym = self . get_current_namespace ( ) ;
131+ env_val. add_referred_namespace ( & namespace_sym, referred_namespace_sym) ;
95132 }
96133 LocalEnvironment ( ..) => panic ! (
97134 "get_main_environment() returns LocalEnvironment,\
@@ -100,7 +137,7 @@ impl Environment {
100137 }
101138 }
102139 /// Changes the current namespace, or creates one first if
103- /// namespace doesn't already exist
140+ /// namespace doesn't already exist
104141 pub fn change_or_create_namespace ( & self , symbol : & Symbol ) {
105142 match self . get_main_environment ( ) {
106143 MainEnvironment ( env_val) => {
@@ -190,10 +227,7 @@ impl Environment {
190227 // Use that namespace
191228 env_val. get_from_namespace ( & Symbol :: intern ( & sym. ns ) , sym)
192229 } else {
193- env_val. get_from_namespace (
194- & env_val. get_current_namespace ( ) ,
195- & sym,
196- )
230+ env_val. get_from_namespace ( & env_val. get_current_namespace ( ) , & sym)
197231 }
198232 }
199233 LocalEnvironment ( parent_env, mappings) => {
@@ -265,6 +299,7 @@ impl Environment {
265299 let eval_fn = rust_core:: EvalFn :: new ( Rc :: clone ( & environment) ) ;
266300 let ns_macro = rust_core:: NsMacro :: new ( Rc :: clone ( & environment) ) ;
267301 let load_file_fn = rust_core:: LoadFileFn :: new ( Rc :: clone ( & environment) ) ;
302+ let refer_fn = rust_core:: ReferFn :: new ( Rc :: clone ( & environment) ) ;
268303 // @TODO after we merge this with all the other commits we have,
269304 // just change all the `insert`s here to use insert_in_namespace
270305 // I prefer explicity and the non-dependence-on-environmental-factors
@@ -285,23 +320,23 @@ impl Environment {
285320 environment. insert ( Symbol :: intern ( "eval" ) , eval_fn. to_rc_value ( ) ) ;
286321
287322 // Thread namespace
288- environment. insert_into_namespace (
289- & Symbol :: intern ( "Thread" ) ,
290- Symbol :: intern ( "sleep" ) ,
291- thread_sleep_fn. to_rc_value ( )
292- ) ;
293-
294- // System namespace
295- environment. insert_into_namespace (
296- & Symbol :: intern ( "System" ) ,
297- Symbol :: intern ( "nanoTime" ) ,
298- nanotime_fn. to_rc_value ( )
299- ) ;
300- environment. insert_into_namespace (
301- & Symbol :: intern ( "System" ) ,
302- Symbol :: intern ( "getenv" ) ,
303- get_env_fn. to_rc_value ( )
304- ) ;
323+ environment. insert_into_namespace (
324+ & Symbol :: intern ( "Thread" ) ,
325+ Symbol :: intern ( "sleep" ) ,
326+ thread_sleep_fn. to_rc_value ( ) ,
327+ ) ;
328+
329+ // System namespace
330+ environment. insert_into_namespace (
331+ & Symbol :: intern ( "System" ) ,
332+ Symbol :: intern ( "nanoTime" ) ,
333+ nanotime_fn. to_rc_value ( ) ,
334+ ) ;
335+ environment. insert_into_namespace (
336+ & Symbol :: intern ( "System" ) ,
337+ Symbol :: intern ( "getenv" ) ,
338+ get_env_fn. to_rc_value ( ) ,
339+ ) ;
305340
306341 // core.clj wraps calls to the rust implementations
307342 // @TODO add this to clojure.rs.core namespace as clojure.rs.core/slurp
@@ -419,6 +454,8 @@ impl Environment {
419454 ) ;
420455 environment. insert ( Symbol :: intern ( "read-line" ) , read_line_fn. to_rc_value ( ) ) ;
421456
457+ environment. insert ( Symbol :: intern ( "refer" ) , refer_fn. to_rc_value ( ) ) ;
458+
422459 //
423460 // Read in clojure.core
424461 //
0 commit comments