@@ -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;
0 commit comments