Skip to content

Commit

Permalink
Merge pull request clojure-rs#45 from zackteo/feature/run-clj-file-as…
Browse files Browse the repository at this point in the history
…-script

Run clj file as script & evaluate expression
  • Loading branch information
Tko1 authored May 16, 2020
2 parents c272638 + ee27d1a commit 6fc04e0
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 6 deletions.
4 changes: 4 additions & 0 deletions examples/hello_world.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(defn hello-world[]
(println "Hello, world"))

(hello-world)
23 changes: 19 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,26 @@ mod symbol;
mod type_tag;
mod util;
mod value;
mod user_action;

fn main() {
//
// Start repl
//
let cli_args: user_action::Action = user_action::parse_args( std::env::args().collect() );

// instantiate the core environment
let repl = repl::Repl::default();
repl.run();

match cli_args {
// eval the file/script
user_action::Action::RunScript(script) => {
println!("{}", repl::Repl::eval_file(&repl, script.as_str()));
},

// eval the expression
user_action::Action::Evaluate(expression) => {
println!("{}", repl::Repl::eval(&repl, &repl::Repl::read_string(&expression)));
},

// Start repl
user_action::Action::Nothing => { repl.run(); }
}
}
6 changes: 4 additions & 2 deletions src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use std::io::Write;

use crate::environment::Environment;
use crate::reader;
use crate::value::Evaluable;
use crate::value::Value;
use crate::value::{Value,Evaluable,ToValue};
use std::rc::Rc;

pub struct Repl {
Expand Down Expand Up @@ -84,6 +83,9 @@ impl Repl {
last_val = Repl::read(&mut reader);
}
}
pub fn eval_file(&self, filepath: &str) -> Value {
self.try_eval_file(filepath).to_value()
}
}

impl Default for Repl {
Expand Down
83 changes: 83 additions & 0 deletions src/user_action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::fmt;

#[derive(PartialEq,Eq)]
pub enum Action{
RunScript(String),
Evaluate(String),
Nothing,
}

impl fmt::Debug for Action {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &*self {
Action::RunScript(filepath) => write!(f, "RunScript: {}", filepath),
Action::Evaluate(expression) => write!(f, "Evaluate: {}", expression),
Action::Nothing => write!(f, "Nothing"),
}
}
}

pub fn parse_args(arguments: Vec<String>) -> Action{

if arguments.len() >= 2 {
if arguments[1] == "-i" || arguments[1] == "--init" {
return Action::RunScript(arguments[2].clone());
}else if arguments[1] == "-e" || arguments[1] == "--eval" {
return Action::Evaluate(arguments[2].clone());
}else { Action::RunScript(arguments[1].clone()) } // for path as argument
}else {
return Action::Nothing;
}
}

#[cfg(test)]
mod tests {
mod parse_args_test {
use crate::user_action;

#[test]
fn parses_args_given_path() {
let arguments = vec!["target/debug/rust_clojure".to_string(), "examples/hello_world.clj".to_string()];
assert_eq!(user_action::Action::RunScript("examples/hello_world.clj".to_string()),
user_action::parse_args(arguments));
}

#[test]
fn parses_args_given_i() {
let arguments = vec!["target/debug/rust_clojure".to_string(), "-i".to_string(), "test.clj".to_string()];

assert_eq!(user_action::Action::RunScript("test.clj".to_string()),
user_action::parse_args(arguments));
}

#[test]
fn parses_args_given_init() {
let arguments = vec!["target/debug/rust_clojure".to_string(), "--init".to_string(), "testing.clj".to_string()];

assert_eq!(user_action::Action::RunScript("testing.clj".to_string()),
user_action::parse_args(arguments));
}

#[test]
fn parses_args_given_e() {
let arguments = vec!["target/debug/rust_clojure".to_string(), "-e".to_string(), "(+ 1 2 3)".to_string()];

assert_eq!(user_action::Action::Evaluate("(+ 1 2 3)".to_string()),
user_action::parse_args(arguments));
}

#[test]
fn parses_args_given_eval() {
let arguments = vec!["target/debug/rust_clojure".to_string(), "--eval".to_string(), "(println \"eh\")".to_string()];

assert_eq!(user_action::Action::Evaluate("(println \"eh\")".to_string()),
user_action::parse_args(arguments));
}

#[test]
fn parses_args_given_nil() {
assert_eq!(user_action::Action::Nothing, user_action::parse_args(vec!["target/debug/rust_clojure".to_string()]));
}
}
}

9 changes: 9 additions & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::fmt::Display;
use crate::environment::Environment;
use crate::ifn::IFn;
use crate::keyword::Keyword;
Expand Down Expand Up @@ -611,6 +612,14 @@ impl ToValue for PersistentListMap {
Value::PersistentListMap(self.clone())
}
}
impl<T: Display> ToValue for Result<Value,T> {
fn to_value(&self) -> Value {
match self {
Ok(val) => val.clone(),
Err(err) => Value::Condition(err.to_string())
}
}
}

/// Allows a type to be evaluated, abstracts evaluation
///
Expand Down

0 comments on commit 6fc04e0

Please sign in to comment.