|
1 | | -use crate::value::{Value,ToValue}; |
2 | | -use crate::namespace::{Namespace,Namespaces}; |
3 | | -use crate::Symbol; |
| 1 | +use crate::namespace::{Namespace, Namespaces}; |
4 | 2 | use crate::rust_core; |
5 | | -use crate::rust_core::{AddFn,StrFn}; |
| 3 | +use crate::value::{ToValue, Value}; |
| 4 | +use crate::Symbol; |
| 5 | +use crate::repl; |
6 | 6 |
|
| 7 | +use std::cell::RefCell; |
7 | 8 | use std::collections::HashMap; |
8 | 9 | use std::rc::Rc; |
9 | | -use std::cell::RefCell; |
10 | | - |
11 | 10 |
|
12 | 11 | // @TODO lookup naming convention |
13 | 12 | /// Inner value of our environment |
14 | | -/// See Environment for overall purpose |
15 | | -#[derive(Debug,Clone)] |
| 13 | +/// See Environment for overall purpose |
| 14 | +#[derive(Debug, Clone)] |
16 | 15 | pub struct EnvironmentVal { |
17 | | - curr_ns : Namespace, |
18 | | - namespaces : Namespaces |
| 16 | + curr_ns: Namespace, |
| 17 | + namespaces: Namespaces, |
19 | 18 | } |
20 | 19 | impl EnvironmentVal { |
21 | | - /// Default main environment |
| 20 | + /// Default main environment |
22 | 21 | fn new_main_val() -> EnvironmentVal { |
23 | | - EnvironmentVal { |
24 | | - curr_ns: Namespace::new(Symbol::intern("user"), |
25 | | - RefCell::new(HashMap::new())), |
26 | | - namespaces: Namespaces(RefCell::new(HashMap::new())) |
27 | | - } |
| 22 | + EnvironmentVal { |
| 23 | + curr_ns: Namespace::new(Symbol::intern("user"), RefCell::new(HashMap::new())), |
| 24 | + namespaces: Namespaces(RefCell::new(HashMap::new())), |
| 25 | + } |
28 | 26 | } |
29 | 27 | } |
30 | 28 | /// Our environment keeps track of the meaning of things 'right here', relative to where |
31 | 29 | /// something is at (meaning, a form inside of a let might have a different meaning for |
32 | 30 | /// the symbol x than a form outside of it, with a let introducing an additional local environment |
33 | 31 | /// |
34 | 32 | /// Stores our namespaces and our current namespace, which themselves personally store our symbols |
35 | | -/// mapped to values |
36 | | -#[derive(Debug,Clone)] |
| 33 | +/// mapped to values |
| 34 | +#[derive(Debug, Clone)] |
37 | 35 | pub enum Environment { |
38 | 36 | MainEnvironment(EnvironmentVal), |
39 | 37 | /// Points to parent environment |
40 | | - /// Introduced by Closures, and by let |
41 | | - LocalEnvironment(Rc<Environment>,RefCell<HashMap<Symbol,Rc<Value>>>) |
| 38 | + /// Introduced by Closures, and by let |
| 39 | + LocalEnvironment(Rc<Environment>, RefCell<HashMap<Symbol, Rc<Value>>>), |
42 | 40 | } |
43 | 41 | use Environment::*; |
44 | 42 | impl Environment { |
45 | 43 | pub fn new_main_environment() -> Environment { |
46 | | - MainEnvironment(EnvironmentVal::new_main_val()) |
| 44 | + MainEnvironment(EnvironmentVal::new_main_val()) |
47 | 45 | } |
48 | 46 | pub fn new_local_environment(outer_environment: Rc<Environment>) -> Environment { |
49 | | - LocalEnvironment(outer_environment,RefCell::new(HashMap::new())) |
| 47 | + LocalEnvironment(outer_environment, RefCell::new(HashMap::new())) |
50 | 48 | } |
51 | | - pub fn insert(&self,sym: Symbol,val: Rc<Value>) |
52 | | - { |
53 | | - match self { |
54 | | - MainEnvironment(EnvironmentVal {curr_ns,..}) => { |
55 | | - curr_ns.insert(sym,val); |
56 | | - }, |
57 | | - LocalEnvironment(_,mappings) => { |
58 | | - mappings.borrow_mut().insert(sym,val); |
59 | | - } |
60 | | - } |
| 49 | + pub fn insert(&self, sym: Symbol, val: Rc<Value>) { |
| 50 | + match self { |
| 51 | + MainEnvironment(EnvironmentVal { curr_ns, .. }) => { |
| 52 | + curr_ns.insert(sym, val); |
| 53 | + } |
| 54 | + LocalEnvironment(_, mappings) => { |
| 55 | + mappings.borrow_mut().insert(sym, val); |
| 56 | + } |
| 57 | + } |
61 | 58 | } |
62 | | - pub fn get(&self, sym: &Symbol) -> Rc<Value> |
63 | | - { |
64 | | - match self { |
65 | | - MainEnvironment(EnvironmentVal {curr_ns,..}) => curr_ns.get(sym), |
66 | | - |
67 | | - LocalEnvironment(parent_env,mappings) => { |
68 | | - match mappings.borrow().get(sym) { |
69 | | - Some(val) => Rc::clone(val), |
70 | | - None => parent_env.get(sym) |
71 | | - } |
72 | | - } |
73 | | - } |
| 59 | + pub fn get(&self, sym: &Symbol) -> Rc<Value> { |
| 60 | + match self { |
| 61 | + MainEnvironment(EnvironmentVal { curr_ns, .. }) => curr_ns.get(sym), |
| 62 | + |
| 63 | + LocalEnvironment(parent_env, mappings) => match mappings.borrow().get(sym) { |
| 64 | + Some(val) => Rc::clone(val), |
| 65 | + None => parent_env.get(sym), |
| 66 | + }, |
| 67 | + } |
74 | 68 | } |
75 | 69 | pub fn clojure_core_environment() -> Rc<Environment> { |
76 | | - // Register our macros / functions ahead of time |
77 | | - let add_fn = rust_core::AddFn{}; |
78 | | - let str_fn = rust_core::StrFn{}; |
| 70 | + // Register our macros / functions ahead of time |
| 71 | + let add_fn = rust_core::AddFn {}; |
| 72 | + let str_fn = rust_core::StrFn {}; |
| 73 | + let do_fn = rust_core::DoFn {}; |
| 74 | + let nth_fn = rust_core::NthFn {}; |
| 75 | + let do_macro = rust_core::DoMacro {}; |
| 76 | + let concat_fn = rust_core::ConcatFn {}; |
| 77 | + let print_string_fn = rust_core::PrintStringFn {}; |
| 78 | + // Hardcoded fns |
| 79 | + let lexical_eval_fn = Value::LexicalEvalFn {}; |
79 | 80 | // Hardcoded macros |
80 | | - let let_macro = Value::LetMacro{}; |
81 | | - let quote_macro = Value::QuoteMacro{}; |
82 | | - let def_macro = Value::DefMacro{}; |
83 | | - let fn_macro = Value::FnMacro{}; |
84 | | - let defmacro_macro = Value::DefmacroMacro{}; |
85 | | - |
86 | | - let mut environment = Rc::new(Environment::new_main_environment()); |
87 | | - |
88 | | - let eval_fn = rust_core::EvalFn::new(Rc::clone(&environment)); |
| 81 | + let let_macro = Value::LetMacro {}; |
| 82 | + let quote_macro = Value::QuoteMacro {}; |
| 83 | + let def_macro = Value::DefMacro {}; |
| 84 | + let fn_macro = Value::FnMacro {}; |
| 85 | + let defmacro_macro = Value::DefmacroMacro {}; |
| 86 | + let environment = Rc::new(Environment::new_main_environment()); |
| 87 | + |
| 88 | + let eval_fn = rust_core::EvalFn::new(Rc::clone(&environment)); |
89 | 89 |
|
90 | | - environment.insert(Symbol::intern("+"),add_fn.to_rc_value()); |
91 | | - environment.insert(Symbol::intern("let"),let_macro.to_rc_value()); |
92 | | - environment.insert(Symbol::intern("str"),str_fn.to_rc_value()); |
93 | | - environment.insert(Symbol::intern("quote"),quote_macro.to_rc_value()); |
94 | | - environment.insert(Symbol::intern("def"),def_macro.to_rc_value()); |
95 | | - environment.insert(Symbol::intern("fn"),fn_macro.to_rc_value()); |
96 | | - environment.insert(Symbol::intern("defmacro"),defmacro_macro.to_rc_value()); |
97 | | - environment.insert(Symbol::intern("eval"),eval_fn.to_rc_value()); |
| 90 | + environment.insert(Symbol::intern("+"), add_fn.to_rc_value()); |
| 91 | + environment.insert(Symbol::intern("let"), let_macro.to_rc_value()); |
| 92 | + environment.insert(Symbol::intern("str"), str_fn.to_rc_value()); |
| 93 | + environment.insert(Symbol::intern("quote"), quote_macro.to_rc_value()); |
| 94 | + environment.insert(Symbol::intern("def"), def_macro.to_rc_value()); |
| 95 | + environment.insert(Symbol::intern("fn"), fn_macro.to_rc_value()); |
| 96 | + environment.insert(Symbol::intern("defmacro"), defmacro_macro.to_rc_value()); |
| 97 | + environment.insert(Symbol::intern("eval"), eval_fn.to_rc_value()); |
98 | 98 |
|
99 | | - environment |
| 99 | + environment.insert(Symbol::intern("+"), add_fn.to_rc_value()); |
| 100 | + environment.insert(Symbol::intern("let"), let_macro.to_rc_value()); |
| 101 | + environment.insert(Symbol::intern("str"), str_fn.to_rc_value()); |
| 102 | + environment.insert(Symbol::intern("quote"), quote_macro.to_rc_value()); |
| 103 | + environment.insert(Symbol::intern("do-fn*"), do_fn.to_rc_value()); |
| 104 | + environment.insert(Symbol::intern("do"), do_macro.to_rc_value()); |
| 105 | + environment.insert(Symbol::intern("def"), def_macro.to_rc_value()); |
| 106 | + environment.insert(Symbol::intern("fn"), fn_macro.to_rc_value()); |
| 107 | + environment.insert(Symbol::intern("defmacro"), defmacro_macro.to_rc_value()); |
| 108 | + environment.insert(Symbol::intern("eval"), eval_fn.to_rc_value()); |
| 109 | + environment.insert( |
| 110 | + Symbol::intern("lexical-eval"), |
| 111 | + lexical_eval_fn.to_rc_value(), |
| 112 | + ); |
| 113 | + |
| 114 | + environment.insert(Symbol::intern("nth"), nth_fn.to_rc_value()); |
| 115 | + environment.insert(Symbol::intern("concat"), concat_fn.to_rc_value()); |
| 116 | + environment.insert( |
| 117 | + Symbol::intern("print-string"), |
| 118 | + print_string_fn.to_rc_value(), |
| 119 | + ); |
| 120 | + |
| 121 | + // |
| 122 | + // Read in clojure.core |
| 123 | + // |
| 124 | + let _ = repl::try_eval_file(&environment, "./src/clojure/core.clj"); |
| 125 | + |
| 126 | + environment |
100 | 127 | } |
101 | 128 | } |
0 commit comments