1
1
use crate :: clojure_std;
2
2
use crate :: clojure_string;
3
- use crate :: namespace:: { Namespaces } ;
3
+ use crate :: namespace:: Namespaces ;
4
4
use crate :: repl:: Repl ;
5
5
use crate :: rust_core;
6
6
use crate :: symbol:: Symbol ;
@@ -23,24 +23,28 @@ pub struct EnvironmentVal {
23
23
namespaces : Namespaces ,
24
24
}
25
25
impl 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?
27
27
/// 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
29
29
fn change_namespace ( & self , name : Symbol ) {
30
30
self . curr_ns_sym . replace ( name) ;
31
31
}
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) {
35
34
self . change_namespace ( symbol. unqualified ( ) ) ;
36
- }
37
- else {
35
+ } else {
38
36
self . create_namespace ( symbol) ;
39
37
self . change_namespace ( symbol. unqualified ( ) ) ;
40
38
}
41
39
}
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) ;
44
48
}
45
49
fn insert_into_current_namespace ( & self , sym : Symbol , val : Rc < Value > ) {
46
50
self . namespaces
@@ -56,7 +60,7 @@ impl EnvironmentVal {
56
60
self . curr_ns_sym . borrow ( ) . clone ( )
57
61
}
58
62
59
- fn create_namespace ( & self , symbol : & Symbol ) {
63
+ fn create_namespace ( & self , symbol : & Symbol ) {
60
64
self . namespaces . create_namespace ( symbol) ;
61
65
}
62
66
// @TODO as mentioned, we've been working with a memory model where values exist
@@ -90,8 +94,41 @@ use Environment::*;
90
94
impl Environment {
91
95
pub fn has_namespace ( & self , symbol : & Symbol ) -> bool {
92
96
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) ;
95
132
}
96
133
LocalEnvironment ( ..) => panic ! (
97
134
"get_main_environment() returns LocalEnvironment,\
@@ -100,7 +137,7 @@ impl Environment {
100
137
}
101
138
}
102
139
/// Changes the current namespace, or creates one first if
103
- /// namespace doesn't already exist
140
+ /// namespace doesn't already exist
104
141
pub fn change_or_create_namespace ( & self , symbol : & Symbol ) {
105
142
match self . get_main_environment ( ) {
106
143
MainEnvironment ( env_val) => {
@@ -190,10 +227,7 @@ impl Environment {
190
227
// Use that namespace
191
228
env_val. get_from_namespace ( & Symbol :: intern ( & sym. ns ) , sym)
192
229
} 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)
197
231
}
198
232
}
199
233
LocalEnvironment ( parent_env, mappings) => {
@@ -265,6 +299,7 @@ impl Environment {
265
299
let eval_fn = rust_core:: EvalFn :: new ( Rc :: clone ( & environment) ) ;
266
300
let ns_macro = rust_core:: NsMacro :: new ( Rc :: clone ( & environment) ) ;
267
301
let load_file_fn = rust_core:: LoadFileFn :: new ( Rc :: clone ( & environment) ) ;
302
+ let refer_fn = rust_core:: ReferFn :: new ( Rc :: clone ( & environment) ) ;
268
303
// @TODO after we merge this with all the other commits we have,
269
304
// just change all the `insert`s here to use insert_in_namespace
270
305
// I prefer explicity and the non-dependence-on-environmental-factors
@@ -285,23 +320,23 @@ impl Environment {
285
320
environment. insert ( Symbol :: intern ( "eval" ) , eval_fn. to_rc_value ( ) ) ;
286
321
287
322
// 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
+ ) ;
305
340
306
341
// core.clj wraps calls to the rust implementations
307
342
// @TODO add this to clojure.rs.core namespace as clojure.rs.core/slurp
@@ -419,6 +454,8 @@ impl Environment {
419
454
) ;
420
455
environment. insert ( Symbol :: intern ( "read-line" ) , read_line_fn. to_rc_value ( ) ) ;
421
456
457
+ environment. insert ( Symbol :: intern ( "refer" ) , refer_fn. to_rc_value ( ) ) ;
458
+
422
459
//
423
460
// Read in clojure.core
424
461
//
0 commit comments