Skip to content

Commit 9cbfadf

Browse files
committed
can add individual referred symbols and overall use limited version of refer
function
1 parent fd0812f commit 9cbfadf

File tree

7 files changed

+481
-122
lines changed

7 files changed

+481
-122
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ nom = "5.1"
1212
rand = "0.7"
1313
itertools= "0.9"
1414
url = "2.1.1"
15+
if_chain = "1.0"
1516
reqwest = { version = "0.10.4", features = ["blocking"] }

src/environment.rs

Lines changed: 72 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::clojure_std;
22
use crate::clojure_string;
3-
use crate::namespace::{Namespaces};
3+
use crate::namespace::Namespaces;
44
use crate::repl::Repl;
55
use crate::rust_core;
66
use crate::symbol::Symbol;
@@ -23,24 +23,28 @@ pub struct EnvironmentVal {
2323
namespaces: Namespaces,
2424
}
2525
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?
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::*;
9094
impl 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
//

src/keyword.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ pub struct Keyword {
88
pub sym: Symbol,
99
}
1010
impl Keyword {
11+
pub fn name(&self) -> &str {
12+
self.sym.name()
13+
}
1114
pub fn intern(name: &str) -> Keyword {
1215
Keyword {
1316
sym: Symbol::intern(name),

0 commit comments

Comments
 (0)