|
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