cl-interpret, cl-repl:
Move IO builtins into the CLI, so get_line can use repline keybinds.
This commit is contained in:
		| @@ -14,11 +14,11 @@ use std::{ | ||||
| #[derive(Clone, Copy)] | ||||
| pub struct Builtin { | ||||
|     /// An identifier to be used during registration | ||||
|     name: &'static str, | ||||
|     pub name: &'static str, | ||||
|     /// The signature, displayed when the builtin is printed | ||||
|     desc: &'static str, | ||||
|     pub desc: &'static str, | ||||
|     /// The function to be run when called | ||||
|     func: &'static dyn Fn(&mut Environment, &[ConValue]) -> IResult<ConValue>, | ||||
|     pub func: &'static dyn Fn(&mut Environment, &[ConValue]) -> IResult<ConValue>, | ||||
| } | ||||
|  | ||||
| impl Builtin { | ||||
| @@ -173,23 +173,10 @@ pub const Builtins: &[Builtin] = &builtins![ | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Gets a line of input from stdin | ||||
|     fn get_line() { | ||||
|         let mut line = String::new(); | ||||
|         let _ = std::io::stdin().read_line(&mut line); | ||||
|         Ok(line) | ||||
|     } | ||||
|  | ||||
|     /// Returns a shark | ||||
|     fn shark() { | ||||
|         Ok('\u{1f988}') | ||||
|     } | ||||
|  | ||||
|     /// Clears the screen | ||||
|     fn clear() { | ||||
|         println!("\x1b[G"); | ||||
|         Ok(()) | ||||
|     } | ||||
| ]; | ||||
|  | ||||
| pub const Math: &[Builtin] = &builtins![ | ||||
|   | ||||
| @@ -52,16 +52,14 @@ impl Display for Environment { | ||||
| impl Default for Environment { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             builtin: to_hashmap2(Builtins.iter().chain(Math.iter())), | ||||
|             builtin: to_hashmap(Builtins.iter().chain(Math.iter())), | ||||
|             global: vec![(HashMap::new(), "globals")], | ||||
|             frames: vec![], | ||||
|         } | ||||
|     } | ||||
| } | ||||
| // fn to_hashmap(from: &[&'static dyn BuiltIn]) -> HashMap<Sym, Option<ConValue>> { | ||||
| //     from.iter().map(|&v| (v.name(), Some(v.into()))).collect() | ||||
| // } | ||||
| fn to_hashmap2(from: impl IntoIterator<Item = &'static Builtin>) -> HashMap<Sym, Option<ConValue>> { | ||||
|  | ||||
| fn to_hashmap(from: impl IntoIterator<Item = &'static Builtin>) -> HashMap<Sym, Option<ConValue>> { | ||||
|     from.into_iter() | ||||
|         .map(|v| (v.name(), Some(v.into()))) | ||||
|         .collect() | ||||
| @@ -84,8 +82,15 @@ impl Environment { | ||||
|         &self.builtin | ||||
|     } | ||||
|  | ||||
|     pub fn add_builtin(&mut self, builtin: &'static Builtin) { | ||||
|     pub fn add_builtin(&mut self, builtin: &'static Builtin) -> &mut Self { | ||||
|         self.builtin.insert(builtin.name(), Some(builtin.into())); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     pub fn add_builtins(&mut self, builtins: &'static [Builtin]) { | ||||
|         for builtin in builtins { | ||||
|             self.add_builtin(builtin); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn push_frame(&mut self, name: &'static str, frame: StackFrame) { | ||||
|   | ||||
| @@ -6,7 +6,7 @@ use crate::{ | ||||
|     tools::print_token, | ||||
| }; | ||||
| use cl_ast::File; | ||||
| use cl_interpret::{convalue::ConValue, env::Environment, interpret::Interpret}; | ||||
| use cl_interpret::{builtin::builtins, convalue::ConValue, env::Environment, interpret::Interpret}; | ||||
| use cl_lexer::Lexer; | ||||
| use cl_parser::Parser; | ||||
| use std::{error::Error, path::Path}; | ||||
| @@ -16,6 +16,31 @@ pub fn run(args: Args) -> Result<(), Box<dyn Error>> { | ||||
|     let Args { file, include, mode, repl } = args; | ||||
|  | ||||
|     let mut env = Environment::new(); | ||||
|  | ||||
|     env.add_builtins(&builtins! { | ||||
|         /// Clears the screen | ||||
|         fn clear() { | ||||
|             menu::clear(); | ||||
|             Ok(ConValue::Empty) | ||||
|         } | ||||
|         /// Evaluates a quoted expression | ||||
|         fn eval(ConValue::Quote(quote)) @env { | ||||
|             env.eval(quote.as_ref()) | ||||
|         } | ||||
|         /// Executes a file | ||||
|         fn import(ConValue::String(path)) @env { | ||||
|             load_file(env, &**path).or(Ok(ConValue::Empty)) | ||||
|         } | ||||
|  | ||||
|         /// Gets a line of input from stdin | ||||
|         fn get_line() { | ||||
|             match repline::Repline::new("", "", "").read() { | ||||
|                 Ok(line) => Ok(ConValue::String(line.into())), | ||||
|                 Err(e) => Ok(ConValue::String(e.to_string().into())), | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     for path in include { | ||||
|         load_file(&mut env, path)?; | ||||
|     } | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| use cl_interpret::{ | ||||
|     env::Environment, error::IResult, interpret::Interpret, convalue::ConValue, | ||||
| }; | ||||
| use cl_interpret::{convalue::ConValue, env::Environment, error::IResult, interpret::Interpret}; | ||||
|  | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct Context { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ use cl_lexer::Lexer; | ||||
| use cl_parser::Parser; | ||||
| use repline::{error::ReplResult, prebaked::*}; | ||||
|  | ||||
| fn clear() { | ||||
| pub fn clear() { | ||||
|     println!("{}", ansi::CLEAR_ALL); | ||||
|     banner() | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user