cl-interpret, cl-repl:
Move IO builtins into the CLI, so get_line can use repline keybinds.
This commit is contained in:
parent
0e3ba342c4
commit
af9c293907
@ -14,11 +14,11 @@ use std::{
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Builtin {
|
pub struct Builtin {
|
||||||
/// An identifier to be used during registration
|
/// An identifier to be used during registration
|
||||||
name: &'static str,
|
pub name: &'static str,
|
||||||
/// The signature, displayed when the builtin is printed
|
/// The signature, displayed when the builtin is printed
|
||||||
desc: &'static str,
|
pub desc: &'static str,
|
||||||
/// The function to be run when called
|
/// 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 {
|
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
|
/// Returns a shark
|
||||||
fn shark() {
|
fn shark() {
|
||||||
Ok('\u{1f988}')
|
Ok('\u{1f988}')
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the screen
|
|
||||||
fn clear() {
|
|
||||||
println!("\x1b[G");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const Math: &[Builtin] = &builtins![
|
pub const Math: &[Builtin] = &builtins![
|
||||||
|
@ -52,16 +52,14 @@ impl Display for Environment {
|
|||||||
impl Default for Environment {
|
impl Default for Environment {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
builtin: to_hashmap2(Builtins.iter().chain(Math.iter())),
|
builtin: to_hashmap(Builtins.iter().chain(Math.iter())),
|
||||||
global: vec![(HashMap::new(), "globals")],
|
global: vec![(HashMap::new(), "globals")],
|
||||||
frames: vec![],
|
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_hashmap(from: impl IntoIterator<Item = &'static Builtin>) -> HashMap<Sym, Option<ConValue>> {
|
||||||
// }
|
|
||||||
fn to_hashmap2(from: impl IntoIterator<Item = &'static Builtin>) -> HashMap<Sym, Option<ConValue>> {
|
|
||||||
from.into_iter()
|
from.into_iter()
|
||||||
.map(|v| (v.name(), Some(v.into())))
|
.map(|v| (v.name(), Some(v.into())))
|
||||||
.collect()
|
.collect()
|
||||||
@ -84,8 +82,15 @@ impl Environment {
|
|||||||
&self.builtin
|
&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.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) {
|
pub fn push_frame(&mut self, name: &'static str, frame: StackFrame) {
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
tools::print_token,
|
tools::print_token,
|
||||||
};
|
};
|
||||||
use cl_ast::File;
|
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_lexer::Lexer;
|
||||||
use cl_parser::Parser;
|
use cl_parser::Parser;
|
||||||
use std::{error::Error, path::Path};
|
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 Args { file, include, mode, repl } = args;
|
||||||
|
|
||||||
let mut env = Environment::new();
|
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 {
|
for path in include {
|
||||||
load_file(&mut env, path)?;
|
load_file(&mut env, path)?;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use cl_interpret::{
|
use cl_interpret::{convalue::ConValue, env::Environment, error::IResult, interpret::Interpret};
|
||||||
env::Environment, error::IResult, interpret::Interpret, convalue::ConValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
|
@ -5,7 +5,7 @@ use cl_lexer::Lexer;
|
|||||||
use cl_parser::Parser;
|
use cl_parser::Parser;
|
||||||
use repline::{error::ReplResult, prebaked::*};
|
use repline::{error::ReplResult, prebaked::*};
|
||||||
|
|
||||||
fn clear() {
|
pub fn clear() {
|
||||||
println!("{}", ansi::CLEAR_ALL);
|
println!("{}", ansi::CLEAR_ALL);
|
||||||
banner()
|
banner()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user