diff --git a/Cargo.lock b/Cargo.lock index 958c4be..263a810 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,6 @@ dependencies = [ "num-complex", "num-rational", "num-traits", - "paste", "strum", ] @@ -84,10 +83,21 @@ version = "0.1.0" dependencies = [ "backtrace", "complexpr", + "complexpr-stdlib", "rustyline", "rustyline-derive", ] +[[package]] +name = "complexpr-stdlib" +version = "0.1.0" +dependencies = [ + "complexpr", + "lazy_static", + "num-traits", + "paste", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -186,6 +196,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.132" diff --git a/Cargo.toml b/Cargo.toml index 8d1b996..d619803 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = [ "complexpr-bin", "complexpr" ] +members = [ "complexpr-bin", "complexpr", "complexpr-stdlib" ] diff --git a/complexpr-bin/Cargo.toml b/complexpr-bin/Cargo.toml index b1d9734..861ec71 100644 --- a/complexpr-bin/Cargo.toml +++ b/complexpr-bin/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] complexpr = { path = "../complexpr" } +complexpr-stdlib = { path = "../complexpr-stdlib" } backtrace = "0.3.66" rustyline = { version = "10.0.0", optional = true } rustyline-derive = { version = "0.7.0", optional = true } diff --git a/complexpr-bin/src/main.rs b/complexpr-bin/src/main.rs index 34b3f55..496d111 100644 --- a/complexpr-bin/src/main.rs +++ b/complexpr-bin/src/main.rs @@ -1,7 +1,7 @@ use std::{fs, panic::{self, PanicInfo}, process::ExitCode}; use backtrace::Backtrace; -use complexpr::{interpreter::interpret}; +use complexpr::{interpreter::interpret, env::Environment}; mod helper; mod repl; @@ -22,10 +22,21 @@ fn panic_hook(info: &PanicInfo) { } } +fn create_env() -> Environment { + let mut env = Environment::new(); + + complexpr_stdlib::prelude::load(&mut env); + complexpr_stdlib::io::load(&mut env); + complexpr_stdlib::iter::load(&mut env); + complexpr_stdlib::math::load(&mut env); + + env +} + fn main() -> ExitCode { panic::set_hook(Box::new(panic_hook)); let args: Vec = std::env::args().collect(); - if args.len() == 2 { + if args.len() >= 2 { let fname = &args[1]; let src = match fs::read_to_string(fname) { Ok(src) => src, @@ -34,7 +45,10 @@ fn main() -> ExitCode { return ExitCode::from(2); } }; - let res = interpret(&src, Some(fname.into()), None, false); + + let env = create_env().wrap(); + + let res = interpret(&src, Some(fname.into()), Some(env), false); if let Err(e) = res { eprintln!("Error: {}", e); return ExitCode::from(1); diff --git a/complexpr-bin/src/repl.rs b/complexpr-bin/src/repl.rs index feee4d9..8c791db 100644 --- a/complexpr-bin/src/repl.rs +++ b/complexpr-bin/src/repl.rs @@ -1,9 +1,10 @@ #![cfg(feature = "repl")] use rustyline::{self, error::ReadlineError, Config, CompletionType, EditMode, hint::HistoryHinter, validate::MatchingBracketValidator, Editor}; -use complexpr::{env::Environment, interpreter::interpret, value::Value, stdlib}; +use complexpr::{interpreter::interpret, value::Value}; -use crate::helper::CxprHelper; + +use crate::{helper::CxprHelper, create_env}; const C_RESET: &str = "\x1b[0m"; const C_BLUE: &str = "\x1b[94m"; @@ -17,7 +18,7 @@ pub fn repl() -> Result<(), Box> { .edit_mode(EditMode::Emacs) .build(); - let env = Environment::new().wrap(); + let env = create_env().wrap(); let h = CxprHelper { hinter: HistoryHinter {}, @@ -36,11 +37,6 @@ pub fn repl() -> Result<(), Box> { println!("Press {}Ctrl+D{} to exit.", C_BLUE, C_RESET); - stdlib::load(&mut env.borrow_mut()); - stdlib::io::load(&mut env.borrow_mut()); - stdlib::iter::load(&mut env.borrow_mut()); - stdlib::math::load(&mut env.borrow_mut()); - loop { let readline = rl.readline(">> "); match readline { diff --git a/complexpr-stdlib/Cargo.toml b/complexpr-stdlib/Cargo.toml new file mode 100644 index 0000000..04981cf --- /dev/null +++ b/complexpr-stdlib/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "complexpr-stdlib" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +complexpr = { path = "../complexpr"} +num-traits = "0.2.15" +paste = "1.0.9" +lazy_static = "1.4.0" diff --git a/complexpr/src/stdlib/io.rs b/complexpr-stdlib/src/io.rs similarity index 90% rename from complexpr/src/stdlib/io.rs rename to complexpr-stdlib/src/io.rs index 679a179..94e7662 100644 --- a/complexpr/src/stdlib/io.rs +++ b/complexpr-stdlib/src/io.rs @@ -1,6 +1,8 @@ use std::{io::{Write, Read}, fs::{OpenOptions, File}, rc::Rc, cell::RefCell, fmt}; -use crate::{env::Environment, declare_fn, value::{Value, Native, TypeData}, RuntimeError}; +use complexpr::{env::Environment, value::{Value, Native, TypeData}, RuntimeError}; + +use crate::declare_fn; pub fn load(env: &mut Environment) { declare_fn!(env, print, 1); @@ -37,7 +39,7 @@ struct FileBox { } lazy_static::lazy_static! { - static ref FILE_TYPE_ID: usize = crate::value::generate_type_id(); + static ref FILE_TYPE_ID: usize = complexpr::value::generate_type_id(); } thread_local!(static FILE_TYPE_NAME: Rc = Rc::from("File")); @@ -50,8 +52,8 @@ impl Native for FileBox { self } - fn get_type(&self) -> crate::value::Type { - crate::value::Type { name: FILE_TYPE_NAME.with(Rc::clone), id: *FILE_TYPE_ID, typedata: TypeData::None } + fn get_type(&self) -> complexpr::value::Type { + complexpr::value::Type { name: FILE_TYPE_NAME.with(Rc::clone), id: *FILE_TYPE_ID, typedata: TypeData::None } } } diff --git a/complexpr/src/stdlib/iter.rs b/complexpr-stdlib/src/iter.rs similarity index 96% rename from complexpr/src/stdlib/iter.rs rename to complexpr-stdlib/src/iter.rs index 0888506..b6469c0 100644 --- a/complexpr/src/stdlib/iter.rs +++ b/complexpr-stdlib/src/iter.rs @@ -1,6 +1,8 @@ use std::{rc::Rc, cell::RefCell}; -use crate::{value::{Value, func::Func}, RuntimeError, env::Environment, declare_fn}; +use complexpr::{value::{Value, func::Func}, RuntimeError, env::Environment}; + +use crate::declare_fn; pub fn load(env: &mut Environment) { declare_fn!(env, take, 2); diff --git a/complexpr-stdlib/src/lib.rs b/complexpr-stdlib/src/lib.rs new file mode 100644 index 0000000..6ab207a --- /dev/null +++ b/complexpr-stdlib/src/lib.rs @@ -0,0 +1,16 @@ +pub mod prelude; +pub mod io; +pub mod iter; +pub mod math; + +#[macro_export] +macro_rules! declare_fn { + ($env:ident, $name:ident, $arg_count:literal) => {::paste::paste!{{ + let s: ::std::rc::Rc = ::std::rc::Rc::from(stringify!($name)); + $env.declare(s.clone(), ::complexpr::value::Value::Func(::complexpr::value::func::Func::Builtin { func: [], arg_count: $arg_count, name: s })); + }}}; + ($env:ident, $name:literal, $rust_name:ident, $arg_count:literal) => {{ + let s: ::std::rc::Rc = ::std::rc::Rc::from($name); + $env.declare(s.clone(), ::complexpr::value::Value::Func(::complexpr::value::func::Func::Builtin { func: $rust_name, arg_count: $arg_count, name: s })); + }}; +} diff --git a/complexpr/src/stdlib/math.rs b/complexpr-stdlib/src/math.rs similarity index 98% rename from complexpr/src/stdlib/math.rs rename to complexpr-stdlib/src/math.rs index 01c09d6..a10a658 100644 --- a/complexpr/src/stdlib/math.rs +++ b/complexpr-stdlib/src/math.rs @@ -2,7 +2,9 @@ use std::cmp::Ordering; use num_traits::{ToPrimitive, Pow, Signed}; -use crate::{value::{Value, Complex, Rational}, RuntimeError, env::Environment, declare_fn}; +use complexpr::{value::{Value, Complex, Rational}, RuntimeError, env::Environment}; + +use crate::declare_fn; enum Floaty { Real(f64), Complex(Complex) diff --git a/complexpr/src/stdlib/mod.rs b/complexpr-stdlib/src/prelude.rs similarity index 88% rename from complexpr/src/stdlib/mod.rs rename to complexpr-stdlib/src/prelude.rs index be8eb8f..ce6a5a4 100644 --- a/complexpr/src/stdlib/mod.rs +++ b/complexpr-stdlib/src/prelude.rs @@ -1,22 +1,8 @@ -pub mod io; -pub mod iter; -pub mod math; - use std::{time::{SystemTime, UNIX_EPOCH}, rc::Rc, cell::RefCell}; -use crate::{value::{Value, func::Func}, RuntimeError, env::Environment}; +use complexpr::{value::{Value, func::Func}, RuntimeError, env::Environment}; -#[macro_export] -macro_rules! declare_fn { - ($env:ident, $name:ident, $arg_count:literal) => {::paste::paste!{{ - let s: ::std::rc::Rc = ::std::rc::Rc::from(stringify!($name)); - $env.declare(s.clone(), $crate::value::Value::Func($crate::value::func::Func::Builtin { func: [], arg_count: $arg_count, name: s })); - }}}; - ($env:ident, $name:literal, $rust_name:ident, $arg_count:literal) => {{ - let s: ::std::rc::Rc = ::std::rc::Rc::from($name); - $env.declare(s.clone(), $crate::value::Value::Func($crate::value::func::Func::Builtin { func: $rust_name, arg_count: $arg_count, name: s })); - }}; -} +use crate::declare_fn; pub fn load(env: &mut Environment) { declare_fn!(env, "type", fn_type, 1); diff --git a/complexpr/Cargo.toml b/complexpr/Cargo.toml index 1d1825c..9a6a629 100644 --- a/complexpr/Cargo.toml +++ b/complexpr/Cargo.toml @@ -8,5 +8,3 @@ num-complex = "0.4.2" num-rational = "0.4.1" num-traits = "0.2.15" strum = { version = "0.24.1", features = ["derive"] } -paste = "1.0.9" -lazy_static = "1.4.0" diff --git a/complexpr/src/interpreter.rs b/complexpr/src/interpreter.rs index d92ce8f..52530d7 100644 --- a/complexpr/src/interpreter.rs +++ b/complexpr/src/interpreter.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, rc::Rc}; -use crate::{value::Value, lexer::Lexer, parser::Parser, eval::{eval_stmt, eval_expr}, expr::Stmt, stdlib, env::{EnvRef, Environment}}; +use crate::{value::Value, lexer::Lexer, parser::Parser, eval::{eval_stmt, eval_expr}, expr::Stmt, env::{EnvRef, Environment}}; pub fn interpret(src: &str, fname: Option, env: Option, repl: bool) -> Result> { let ctx_name = if repl { "" } else { fname.as_ref().map(|s| s.as_ref()).unwrap_or("") }; @@ -13,10 +13,6 @@ pub fn interpret(src: &str, fname: Option, env: Option, repl: bo environ = env; } else { environ = Rc::new(RefCell::new(Environment::new())); - stdlib::load(&mut environ.borrow_mut()); - stdlib::io::load(&mut environ.borrow_mut()); - stdlib::iter::load(&mut environ.borrow_mut()); - stdlib::math::load(&mut environ.borrow_mut()); } let mut result = Value::Nil; diff --git a/complexpr/src/lib.rs b/complexpr/src/lib.rs index ea3db59..160c104 100644 --- a/complexpr/src/lib.rs +++ b/complexpr/src/lib.rs @@ -8,7 +8,6 @@ pub mod value; pub mod eval; pub mod interpreter; pub mod env; -pub mod stdlib; #[derive(Clone, Debug)] pub struct Position {