diff --git a/examples/repl.rs b/examples/repl.rs new file mode 100644 index 00000000..bc2ee802 --- /dev/null +++ b/examples/repl.rs @@ -0,0 +1,40 @@ +extern crate rhai; + +use std::fmt::Display; +use std::process::exit; +use std::io::{stdin, stdout, Write}; +use rhai::{Engine, Scope, FnRegister}; + +fn showit(x: &mut T) -> () { + println!("{}", x) +} + +fn quit() { exit(0); } + +pub fn main() { + let mut engine = Engine::new(); + let mut scope = Scope::new(); + + engine.register_fn("print", showit as fn(x: &mut i32)->()); + engine.register_fn("print", showit as fn(x: &mut i64)->()); + engine.register_fn("print", showit as fn(x: &mut u32)->()); + engine.register_fn("print", showit as fn(x: &mut u64)->()); + engine.register_fn("print", showit as fn(x: &mut f32)->()); + engine.register_fn("print", showit as fn(x: &mut f64)->()); + engine.register_fn("print", showit as fn(x: &mut bool)->()); + engine.register_fn("print", showit as fn(x: &mut String)->()); + engine.register_fn("exit", quit); + + loop { + print!("> "); + let mut input = String::new(); + stdout().flush().expect("couldn't flush stdout"); + if let Err(e) = stdin().read_line(&mut input) { + println!("input error: {}", e); + } + + if let Err(e) = engine.consume_with_scope(&mut scope, &input) { + println!("error: {}", e); + } + } +} diff --git a/src/engine.rs b/src/engine.rs index c4c68b87..0d163813 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1241,6 +1241,63 @@ impl Engine { } } + pub fn consume_file(&mut self, fname: &str) -> Result<(), EvalAltResult> { + use std::fs::File; + use std::io::prelude::*; + + if let Ok(mut f) = File::open(fname) { + let mut contents = String::new(); + + if f.read_to_string(&mut contents).is_ok() { + if let e @ Err(_) = self.consume(&contents) { + return e; + } else { return Ok(()); } + } else { + Err(EvalAltResult::ErrorCantOpenScriptFile) + } + } else { + Err(EvalAltResult::ErrorCantOpenScriptFile) + } + } + + pub fn consume(&mut self, input: &str) -> Result<(), EvalAltResult> { + let mut scope: Scope = Scope::new(); + + let res = self.consume_with_scope(&mut scope, input); + + res + } + + pub fn consume_with_scope(&mut self, scope: &mut Scope, input: &str) -> Result<(), EvalAltResult> { + let tokens = lex(input); + + let mut peekables = tokens.peekable(); + let tree = parse(&mut peekables); + + match tree { + Ok((ref os, ref fns)) => { + for f in fns { + if f.params.len() > 6 { + return Ok(()); + } + let name = f.name.clone(); + let local_f = f.clone(); + let ent = self.fns.entry(name).or_insert_with(Vec::new); + (*ent).push(FnType::InternalFn(local_f)); + } + + for o in os { + if let Err(e) = self.eval_stmt(scope, o) { + return Err(e); + } + } + + Ok(()) + }, + Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch), + } + } + pub fn register_default_lib(engine: &mut Engine) { engine.register_type::(); engine.register_type::(); @@ -1303,7 +1360,6 @@ impl Engine { // FIXME? Registering array lookups are a special case because we want to return boxes // directly let ent = engine.fns.entry("[]".to_string()).or_insert_with(Vec::new); // (*ent).push(FnType::ExternalFn2(Box::new(idx))); - } pub fn new() -> Engine {