File tree Expand file tree Collapse file tree 6 files changed +76
-5
lines changed Expand file tree Collapse file tree 6 files changed +76
-5
lines changed Original file line number Diff line number Diff line change 8
8
(defn apply [f args]
9
9
(lexical-eval (concat (list f) args)))
10
10
11
- (defn println [& more]
11
+ (defn print [& more]
12
12
(print-string (apply str more)))
13
13
14
+ (defn println [& more]
15
+ (println-string (apply str more)))
16
+
14
17
(defn inc [x]
15
18
(+ x 1 ))
16
19
Original file line number Diff line number Diff line change @@ -199,6 +199,8 @@ impl Environment {
199
199
let do_macro = rust_core:: DoMacro { } ;
200
200
let concat_fn = rust_core:: ConcatFn { } ;
201
201
let print_string_fn = rust_core:: PrintStringFn { } ;
202
+ let println_string_fn = rust_core:: PrintlnStringFn { } ;
203
+ let read_line_fn = rust_core:: ReadLineFn { } ;
202
204
let assoc_fn = rust_core:: AssocFn { } ;
203
205
204
206
// rust implementations of core functions
@@ -277,6 +279,11 @@ impl Environment {
277
279
Symbol :: intern ( "print-string" ) ,
278
280
print_string_fn. to_rc_value ( ) ,
279
281
) ;
282
+ environment. insert (
283
+ Symbol :: intern ( "println-string" ) ,
284
+ println_string_fn. to_rc_value ( ) ,
285
+ ) ;
286
+ environment. insert ( Symbol :: intern ( "read-line" ) , read_line_fn. to_rc_value ( ) ) ;
280
287
281
288
//
282
289
// Read in clojure.core
Original file line number Diff line number Diff line change @@ -36,9 +36,15 @@ impl Repl {
36
36
loop {
37
37
print ! ( "{}=> " , self . environment. get_current_namespace_name( ) ) ;
38
38
let _ = io:: stdout ( ) . flush ( ) ;
39
+ let mut next = Value :: Nil ;
40
+
41
+ // a scope for stdin to be released for providing input for function
42
+ {
43
+ let mut stdin_reader = stdin. lock ( ) ;
44
+ // Read
45
+ next = Repl :: read ( & mut stdin_reader) ;
46
+ }
39
47
40
- // Read
41
- let next = Repl :: read ( & mut stdin_reader) ;
42
48
// Eval
43
49
let evaled_next = self . eval ( & next) ;
44
50
// Print
Original file line number Diff line number Diff line change @@ -48,6 +48,8 @@ pub(crate) mod print_string;
48
48
pub use self :: print_string:: * ;
49
49
pub ( crate ) mod string_print;
50
50
pub use self :: string_print:: * ;
51
+ pub ( crate ) mod read_line;
52
+ pub use self :: read_line:: * ;
51
53
52
54
// other
53
55
pub ( crate ) mod slurp;
Original file line number Diff line number Diff line change @@ -5,7 +5,26 @@ use std::rc::Rc;
5
5
use crate :: error_message;
6
6
7
7
/// Primitive printing function;
8
- /// (defn print-string [string] .. prints single string .. )
8
+ /// (defn println-string [string] .. prints single string with linebreak.. )
9
+ #[ derive( Debug , Clone ) ]
10
+ pub struct PrintlnStringFn { }
11
+ impl ToValue for PrintlnStringFn {
12
+ fn to_value ( & self ) -> Value {
13
+ Value :: IFn ( Rc :: new ( self . clone ( ) ) )
14
+ }
15
+ }
16
+ impl IFn for PrintlnStringFn {
17
+ fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
18
+ if args. len ( ) != 1 {
19
+ return error_message:: wrong_arg_count ( 1 , args. len ( ) )
20
+ }
21
+ println ! ( "{}" , args. get( 0 ) . unwrap( ) . to_string( ) ) ;
22
+ Value :: Nil
23
+ }
24
+ }
25
+
26
+ /// Primitive printing function;
27
+ /// (defn print-string [string] .. prints single string without linebreak.. )
9
28
#[ derive( Debug , Clone ) ]
10
29
pub struct PrintStringFn { }
11
30
impl ToValue for PrintStringFn {
@@ -18,7 +37,7 @@ impl IFn for PrintStringFn {
18
37
if args. len ( ) != 1 {
19
38
return error_message:: wrong_arg_count ( 1 , args. len ( ) ) ;
20
39
}
21
- println ! ( "{}" , args. get( 0 ) . unwrap( ) . to_string( ) ) ;
40
+ print ! ( "{}" , args. get( 0 ) . unwrap( ) . to_string( ) ) ;
22
41
Value :: Nil
23
42
}
24
43
}
Original file line number Diff line number Diff line change
1
+ use crate :: ifn:: IFn ;
2
+ use crate :: value:: { Value , ToValue , Evaluable } ;
3
+ use std:: rc:: Rc ;
4
+
5
+ use std:: io;
6
+
7
+ use crate :: error_message;
8
+ use nom:: lib:: std:: convert:: TryFrom ;
9
+ use std:: io:: { Read , Write } ;
10
+
11
+ /// Read a line from stdin
12
+ /// (defn read-line [])
13
+ #[ derive( Debug , Clone ) ]
14
+ pub struct ReadLineFn { }
15
+ impl ToValue for ReadLineFn {
16
+ fn to_value ( & self ) -> Value {
17
+ Value :: IFn ( Rc :: new ( self . clone ( ) ) )
18
+ }
19
+ }
20
+ impl IFn for ReadLineFn {
21
+ fn invoke ( & self , args : Vec < Rc < Value > > ) -> Value {
22
+ if args. len ( ) != 0 {
23
+ return error_message:: wrong_arg_count ( 0 , args. len ( ) )
24
+ }
25
+
26
+ //io::stdout().flush();
27
+ let mut input = String :: new ( ) ;
28
+ io:: stdout ( ) . flush ( ) ;
29
+ match io:: stdin ( ) . read_line ( & mut input) {
30
+ Ok ( _) => Value :: String ( input) ,
31
+ Err ( error) => error_message:: generic_err ( Box :: try_from ( error) . unwrap ( ) )
32
+ }
33
+ }
34
+ }
You can’t perform that action at this time.
0 commit comments