Skip to content

Commit fc0dd18

Browse files
committed
read-line function, and print function
1 parent 4eeaa34 commit fc0dd18

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed

src/clojure/core.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
(defn apply [f args]
99
(lexical-eval (concat (list f) args)))
1010

11-
(defn println [& more]
11+
(defn print [& more]
1212
(print-string (apply str more)))
1313

14+
(defn println [& more]
15+
(println-string (apply str more)))
16+
1417
(defn inc [x]
1518
(+ x 1))
1619

src/environment.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ impl Environment {
199199
let do_macro = rust_core::DoMacro {};
200200
let concat_fn = rust_core::ConcatFn {};
201201
let print_string_fn = rust_core::PrintStringFn {};
202+
let println_string_fn = rust_core::PrintlnStringFn {};
203+
let read_line_fn = rust_core::ReadLineFn {};
202204
let assoc_fn = rust_core::AssocFn {};
203205

204206
// rust implementations of core functions
@@ -277,6 +279,11 @@ impl Environment {
277279
Symbol::intern("print-string"),
278280
print_string_fn.to_rc_value(),
279281
);
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());
280287

281288
//
282289
// Read in clojure.core

src/repl.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,15 @@ impl Repl {
3636
loop {
3737
print!("{}=> ",self.environment.get_current_namespace_name());
3838
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+
}
3947

40-
// Read
41-
let next = Repl::read(&mut stdin_reader);
4248
// Eval
4349
let evaled_next = self.eval(&next);
4450
// Print

src/rust_core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pub(crate) mod print_string;
4848
pub use self::print_string::*;
4949
pub(crate) mod string_print;
5050
pub use self::string_print::*;
51+
pub(crate) mod read_line;
52+
pub use self::read_line::*;
5153

5254
// other
5355
pub(crate) mod slurp;

src/rust_core/print_string.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,26 @@ use std::rc::Rc;
55
use crate::error_message;
66

77
/// 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.. )
928
#[derive(Debug, Clone)]
1029
pub struct PrintStringFn {}
1130
impl ToValue for PrintStringFn {
@@ -18,7 +37,7 @@ impl IFn for PrintStringFn {
1837
if args.len() != 1 {
1938
return error_message::wrong_arg_count(1, args.len());
2039
}
21-
println!("{}", args.get(0).unwrap().to_string());
40+
print!("{}", args.get(0).unwrap().to_string());
2241
Value::Nil
2342
}
2443
}

src/rust_core/read_line.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
}

0 commit comments

Comments
 (0)