Skip to content

Commit 1f26203

Browse files
committed
refactor rust_core module to separate files
1 parent aedb5be commit 1f26203

File tree

13 files changed

+1466
-276
lines changed

13 files changed

+1466
-276
lines changed

Cargo.lock

Lines changed: 1101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/environment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl Environment {
9898
let defmacro_macro = Value::DefmacroMacro {};
9999
let environment = Rc::new(Environment::new_main_environment());
100100

101-
let eval_fn = rust_core::EvalFn::new(Rc::clone(&environment));
101+
let eval_fn = rust_core::eval::EvalFn::new(Rc::clone(&environment));
102102

103103
environment.insert(Symbol::intern("+"), add_fn.to_rc_value());
104104
environment.insert(Symbol::intern("-"), subtract_fn.to_rc_value());

src/rust_core.rs

Lines changed: 17 additions & 271 deletions
Original file line numberDiff line numberDiff line change
@@ -32,281 +32,27 @@ pub use self::_multiply_::*;
3232
//
3333
// This module will hold core function and macro primitives that aren't special cases
3434
// (like the quote macro, or let), and can't be implemented in clojure itself
35-
//
36-
#[derive(Debug, Clone)]
37-
pub struct StrFn {}
38-
impl ToValue for StrFn {
39-
fn to_value(&self) -> Value {
40-
Value::IFn(Rc::new(self.clone()))
41-
}
42-
}
43-
impl IFn for StrFn {
44-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
45-
Value::String(
46-
args.into_iter()
47-
.map(|arg| arg.to_string())
48-
.collect::<Vec<String>>()
49-
.join(""),
50-
)
51-
}
52-
}
53-
54-
#[derive(Debug, Clone)]
55-
pub struct StringPrintFn {}
56-
impl ToValue for StringPrintFn {
57-
fn to_value(&self) -> Value {
58-
Value::IFn(Rc::new(self.clone()))
59-
}
60-
}
61-
impl IFn for StringPrintFn {
62-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
63-
Value::String(
64-
args.into_iter()
65-
.map(|arg| arg.to_string())
66-
.collect::<Vec<String>>()
67-
.join(""),
68-
)
69-
}
70-
}
71-
72-
#[derive(Debug, Clone)]
73-
pub struct AddFn {}
74-
impl ToValue for AddFn {
75-
fn to_value(&self) -> Value {
76-
Value::IFn(Rc::new(self.clone()))
77-
}
78-
}
79-
impl IFn for AddFn {
80-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
81-
args.into_iter().fold(0_i32.to_value(), |a, b| match a {
82-
Value::I32(a_) => match *b {
83-
Value::I32(b_) => Value::I32(a_ + b_),
84-
Value::F64(b_) => Value::F64(a_ as f64 + b_),
85-
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
86-
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
87-
b.type_tag()
88-
)),
89-
},
90-
Value::F64(a_) => match *b {
91-
Value::I32(b_) => Value::F64(a_ + b_ as f64),
92-
Value::F64(b_) => Value::F64(a_ + b_),
93-
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
94-
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
95-
b.type_tag()
96-
)),
97-
},
98-
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
99-
"Type mismatch: Expecting: (i32 | i64 | f32 | f64), Found: {}",
100-
a.type_tag()
101-
)),
102-
})
103-
}
104-
}
10535

106-
#[derive(Debug, Clone)]
107-
pub struct EvalFn {
108-
enclosing_environment: Rc<Environment>,
109-
}
110-
impl EvalFn {
111-
pub fn new(enclosing_environment: Rc<Environment>) -> EvalFn {
112-
EvalFn {
113-
enclosing_environment,
114-
}
115-
}
116-
}
117-
impl ToValue for EvalFn {
118-
fn to_value(&self) -> Value {
119-
Value::IFn(Rc::new(self.clone()))
120-
}
121-
}
122-
impl IFn for EvalFn {
123-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
124-
// @TODO generalize arity exceptions, and other exceptions
125-
if args.len() != 1 {
126-
return error_message::wrong_arg_count(1, args.len())
127-
}
128-
let arg = args.get(0).unwrap();
129-
arg.eval(Rc::clone(&self.enclosing_environment))
130-
}
131-
}
36+
// language core functions
37+
pub(crate) mod eval;
13238

133-
#[derive(Debug, Clone)]
134-
pub struct DoFn {}
135-
impl ToValue for DoFn {
136-
fn to_value(&self) -> Value {
137-
Value::IFn(Rc::new(self.clone()))
138-
}
139-
}
140-
impl IFn for DoFn {
141-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
142-
// @TODO generalize arity exceptions, and other exceptions
143-
if args.is_empty() {
144-
return Value::Nil;
145-
}
146-
(**args.last().unwrap()).clone()
147-
}
148-
}
149-
150-
//
151-
// Since our macros currently expand and evaluate at the same time, our `do` macro will be implemented
152-
// by expanding to a do-fn, which will just naturally evaluate all arguments, being a fn, and
153-
// return the last item
154-
// This will change when macros change
155-
//
156-
#[derive(Debug, Clone)]
157-
pub struct DoMacro {}
158-
impl ToValue for DoMacro {
159-
fn to_value(&self) -> Value {
160-
Value::Macro(Rc::new(self.clone()))
161-
}
162-
}
163-
impl IFn for DoMacro {
164-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
165-
// @TODO generalize arity exceptions, and other exceptions
166-
if args.is_empty() {
167-
return vec![Symbol::intern("do").to_rc_value(), Rc::new(Value::Nil)]
168-
.into_list()
169-
.to_value();
170-
}
171-
// (do a b c) becomes (do-fn* a b c), so we need to copy a,b, and c for our new expression
172-
let args_for_ret_expr = args
173-
.iter()
174-
.map(|arg| arg.to_rc_value())
175-
.collect::<Vec<Rc<Value>>>();
39+
// macros
40+
pub(crate) mod do_macro;
17641

177-
let mut do_body = vec![Symbol::intern("do-fn*").to_rc_value()];
178-
do_body.extend_from_slice(args_for_ret_expr.get(0..).unwrap());
42+
// arithmetics
43+
pub(crate) mod _plus_;
17944

180-
do_body.into_list().to_value()
181-
}
182-
}
45+
// string
46+
pub(crate) mod str;
18347

184-
#[derive(Debug, Clone)]
185-
pub struct NthFn {}
186-
impl ToValue for NthFn {
187-
fn to_value(&self) -> Value {
188-
Value::IFn(Rc::new(self.clone()))
189-
}
190-
}
191-
impl IFn for NthFn {
192-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
193-
// @TODO generalize arity exceptions, and other exceptions
194-
if args.len() != 2 {
195-
return error_message::wrong_varg_count(&[2,3], args.len())
196-
}
197-
// @TODO change iteration to work with Value references, or even change invoke to work on Rc<..>
198-
// as we do everything else; surely we don't want to clone just to read from a collection
199-
if let Value::I32(ind) = **args.get(1).unwrap() {
200-
if ind < 0 {
201-
return error_message::index_cannot_be_negative(ind as usize)
202-
}
203-
let ind = ind as usize;
48+
// operations on collections
49+
pub(crate) mod nth;
50+
pub(crate) mod concat;
51+
pub(crate) mod assoc;
20452

205-
match &**args.get(0).unwrap() {
206-
Value::PersistentList(Cons(head, tail, count)) => {
207-
let count = *count as usize;
208-
if ind >= count {
209-
error_message::index_out_of_bounds(ind, count)
210-
} else if ind == 0 {
211-
head.to_value()
212-
} else {
213-
tail.iter().nth(ind - 1).unwrap().to_value()
214-
}
215-
}
216-
Value::PersistentList(Empty) => error_message::index_out_of_bounds(ind, 0),
217-
Value::PersistentVector(PersistentVector { vals }) => {
218-
if ind >= vals.len() {
219-
error_message::index_out_of_bounds(ind, vals.len())
220-
} else {
221-
vals.get(ind).unwrap().to_value()
222-
}
223-
}
224-
_ => error_message::type_mismatch(TypeTag::ISeq, &**args.get(0).unwrap()),
225-
}
226-
} else {
227-
error_message::type_mismatch(TypeTag::Integer, &**args.get(1).unwrap())
228-
}
229-
}
230-
}
53+
// input and output
54+
pub(crate) mod print_string;
55+
pub(crate) mod string_pring;
23156

232-
#[derive(Debug, Clone)]
233-
pub struct ConcatFn {}
234-
impl ToValue for ConcatFn {
235-
fn to_value(&self) -> Value {
236-
Value::IFn(Rc::new(self.clone()))
237-
}
238-
}
239-
impl IFn for ConcatFn {
240-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
241-
let concatted_vec = args.iter().fold(Vec::new(), |mut sum, coll| {
242-
let coll_vec = match &**coll {
243-
Value::PersistentList(plist) => {
244-
Rc::new(plist.clone()).iter().collect::<Vec<Rc<Value>>>()
245-
}
246-
Value::PersistentVector(pvector) => {
247-
Rc::new(pvector.clone()).iter().collect::<Vec<Rc<Value>>>()
248-
}
249-
_ => vec![],
250-
};
251-
252-
sum.extend(coll_vec);
253-
sum
254-
});
255-
Value::PersistentList(concatted_vec.into_iter().collect::<PersistentList>())
256-
}
257-
}
258-
259-
/// Primitive printing function;
260-
/// (defn print-string [string] .. prints single string .. )
261-
#[derive(Debug, Clone)]
262-
pub struct PrintStringFn {}
263-
impl ToValue for PrintStringFn {
264-
fn to_value(&self) -> Value {
265-
Value::IFn(Rc::new(self.clone()))
266-
}
267-
}
268-
impl IFn for PrintStringFn {
269-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
270-
if args.len() != 1 {
271-
return error_message::wrong_arg_count(1, args.len())
272-
}
273-
println!("{}", args.get(0).unwrap().to_string());
274-
Value::Nil
275-
}
276-
}
277-
// General assoc fn; however, currently just implemented
278-
// for our one map type, PersistentListMap
279-
#[derive(Debug, Clone)]
280-
pub struct AssocFn {}
281-
impl ToValue for AssocFn {
282-
fn to_value(&self) -> Value {
283-
Value::IFn(Rc::new(self.clone()))
284-
}
285-
}
286-
impl IFn for AssocFn {
287-
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
288-
// We don't want even args, because assoc works like
289-
// (assoc {} :a 1) ;; 3 args
290-
// (assoc {} :a 1 :b 2) ;; 5 args
291-
// (assoc {} :a 1 :b 2 :c 3) ;; 7 args ...
292-
if args.len() < 3 || args.len().is_even() {
293-
return Value::Condition(format!(
294-
"Wrong number of arguments given to function (Given: {}, Expected: 3 | 5 | 7 | ..)",
295-
args.len()
296-
));
297-
}
298-
299-
if let Value::PersistentListMap(pmap) = &*(args.get(0).unwrap().clone()) {
300-
let mut retval = pmap.clone();
301-
for (key_value, val_value) in args.into_iter().skip(1).tuples() {
302-
let key = key_value.to_rc_value();
303-
let val = val_value.to_rc_value();
304-
println!("key: {:?}, val: {:?}", key, val);
305-
retval = pmap.assoc(key, val);
306-
}
307-
return Value::PersistentListMap(retval);
308-
}
309-
310-
Value::Nil
311-
}
312-
}
57+
// other
58+
pub(crate) mod slurp;

src/rust_core/_plus_.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{Value, ToValue};
3+
use std::rc::Rc;
4+
5+
/// (+ x y & xys)
6+
///
7+
#[derive(Debug, Clone)]
8+
pub struct AddFn {}
9+
impl ToValue for AddFn {
10+
fn to_value(&self) -> Value {
11+
Value::IFn(Rc::new(self.clone()))
12+
}
13+
}
14+
impl IFn for AddFn {
15+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
16+
args.into_iter().fold(0_i32.to_value(), |a, b| match a {
17+
Value::I32(a_) => match *b {
18+
Value::I32(b_) => Value::I32(a_ + b_),
19+
Value::F64(b_) => Value::F64(a_ as f64 + b_),
20+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
21+
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
22+
b.type_tag()
23+
)),
24+
},
25+
Value::F64(a_) => match *b {
26+
Value::I32(b_) => Value::F64(a_ + b_ as f64),
27+
Value::F64(b_) => Value::F64(a_ + b_),
28+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
29+
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
30+
b.type_tag()
31+
)),
32+
},
33+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
34+
"Type mismatch: Expecting: (i32 | i64 | f32 | f64), Found: {}",
35+
a.type_tag()
36+
)),
37+
})
38+
}
39+
}

src/rust_core/assoc.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use crate::ifn::IFn;
2+
use crate::value::{Value, ToValue};
3+
use std::rc::Rc;
4+
use crate::util::IsEven;
5+
use itertools::Itertools;
6+
use crate::persistent_list_map::IPersistentListMap;
7+
8+
/// (assoc map key val & kvs)
9+
///
10+
// General assoc fn; however, currently just implemented
11+
// for our one map type, PersistentListMap
12+
#[derive(Debug, Clone)]
13+
pub struct AssocFn {}
14+
impl ToValue for AssocFn {
15+
fn to_value(&self) -> Value {
16+
Value::IFn(Rc::new(self.clone()))
17+
}
18+
}
19+
impl IFn for AssocFn {
20+
fn invoke(&self, args: Vec<Rc<Value>>) -> Value {
21+
// We don't want even args, because assoc works like
22+
// (assoc {} :a 1) ;; 3 args
23+
// (assoc {} :a 1 :b 2) ;; 5 args
24+
// (assoc {} :a 1 :b 2 :c 3) ;; 7 args ...
25+
if args.len() < 3 || args.len().is_even() {
26+
return Value::Condition(format!(
27+
"Wrong number of arguments given to function (Given: {}, Expected: 3 | 5 | 7 | ..)",
28+
args.len()
29+
));
30+
}
31+
32+
if let Value::PersistentListMap(pmap) = &*(args.get(0).unwrap().clone()) {
33+
let mut retval = pmap.clone();
34+
for (key_value, val_value) in args.into_iter().skip(1).tuples() {
35+
let key = key_value.to_rc_value();
36+
let val = val_value.to_rc_value();
37+
println!("key: {:?}, val: {:?}", key, val);
38+
retval = pmap.assoc(key, val);
39+
}
40+
return Value::PersistentListMap(retval);
41+
}
42+
43+
Value::Nil
44+
}
45+
}

0 commit comments

Comments
 (0)