Refactored stdlib to its own crate

This commit is contained in:
TriMill 2022-09-23 15:09:22 -04:00
parent 7173c5dda1
commit 08c0cd9173
14 changed files with 83 additions and 43 deletions

18
Cargo.lock generated
View file

@ -74,7 +74,6 @@ dependencies = [
"num-complex", "num-complex",
"num-rational", "num-rational",
"num-traits", "num-traits",
"paste",
"strum", "strum",
] ]
@ -84,10 +83,21 @@ version = "0.1.0"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"complexpr", "complexpr",
"complexpr-stdlib",
"rustyline", "rustyline",
"rustyline-derive", "rustyline-derive",
] ]
[[package]]
name = "complexpr-stdlib"
version = "0.1.0"
dependencies = [
"complexpr",
"lazy_static",
"num-traits",
"paste",
]
[[package]] [[package]]
name = "dirs-next" name = "dirs-next"
version = "2.0.0" version = "2.0.0"
@ -186,6 +196,12 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06" checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.132" version = "0.2.132"

View file

@ -1,2 +1,2 @@
[workspace] [workspace]
members = [ "complexpr-bin", "complexpr" ] members = [ "complexpr-bin", "complexpr", "complexpr-stdlib" ]

View file

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
complexpr = { path = "../complexpr" } complexpr = { path = "../complexpr" }
complexpr-stdlib = { path = "../complexpr-stdlib" }
backtrace = "0.3.66" backtrace = "0.3.66"
rustyline = { version = "10.0.0", optional = true } rustyline = { version = "10.0.0", optional = true }
rustyline-derive = { version = "0.7.0", optional = true } rustyline-derive = { version = "0.7.0", optional = true }

View file

@ -1,7 +1,7 @@
use std::{fs, panic::{self, PanicInfo}, process::ExitCode}; use std::{fs, panic::{self, PanicInfo}, process::ExitCode};
use backtrace::Backtrace; use backtrace::Backtrace;
use complexpr::{interpreter::interpret}; use complexpr::{interpreter::interpret, env::Environment};
mod helper; mod helper;
mod repl; 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 { fn main() -> ExitCode {
panic::set_hook(Box::new(panic_hook)); panic::set_hook(Box::new(panic_hook));
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.len() == 2 { if args.len() >= 2 {
let fname = &args[1]; let fname = &args[1];
let src = match fs::read_to_string(fname) { let src = match fs::read_to_string(fname) {
Ok(src) => src, Ok(src) => src,
@ -34,7 +45,10 @@ fn main() -> ExitCode {
return ExitCode::from(2); 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 { if let Err(e) = res {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);
return ExitCode::from(1); return ExitCode::from(1);

View file

@ -1,9 +1,10 @@
#![cfg(feature = "repl")] #![cfg(feature = "repl")]
use rustyline::{self, error::ReadlineError, Config, CompletionType, EditMode, hint::HistoryHinter, validate::MatchingBracketValidator, Editor}; 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_RESET: &str = "\x1b[0m";
const C_BLUE: &str = "\x1b[94m"; const C_BLUE: &str = "\x1b[94m";
@ -17,7 +18,7 @@ pub fn repl() -> Result<(), Box<dyn std::error::Error>> {
.edit_mode(EditMode::Emacs) .edit_mode(EditMode::Emacs)
.build(); .build();
let env = Environment::new().wrap(); let env = create_env().wrap();
let h = CxprHelper { let h = CxprHelper {
hinter: HistoryHinter {}, hinter: HistoryHinter {},
@ -36,11 +37,6 @@ pub fn repl() -> Result<(), Box<dyn std::error::Error>> {
println!("Press {}Ctrl+D{} to exit.", C_BLUE, C_RESET); 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 { loop {
let readline = rl.readline(">> "); let readline = rl.readline(">> ");
match readline { match readline {

View file

@ -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"

View file

@ -1,6 +1,8 @@
use std::{io::{Write, Read}, fs::{OpenOptions, File}, rc::Rc, cell::RefCell, fmt}; 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) { pub fn load(env: &mut Environment) {
declare_fn!(env, print, 1); declare_fn!(env, print, 1);
@ -37,7 +39,7 @@ struct FileBox {
} }
lazy_static::lazy_static! { 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<str> = Rc::from("File")); thread_local!(static FILE_TYPE_NAME: Rc<str> = Rc::from("File"));
@ -50,8 +52,8 @@ impl Native for FileBox {
self self
} }
fn get_type(&self) -> crate::value::Type { fn get_type(&self) -> complexpr::value::Type {
crate::value::Type { name: FILE_TYPE_NAME.with(Rc::clone), id: *FILE_TYPE_ID, typedata: TypeData::None } complexpr::value::Type { name: FILE_TYPE_NAME.with(Rc::clone), id: *FILE_TYPE_ID, typedata: TypeData::None }
} }
} }

View file

@ -1,6 +1,8 @@
use std::{rc::Rc, cell::RefCell}; 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) { pub fn load(env: &mut Environment) {
declare_fn!(env, take, 2); declare_fn!(env, take, 2);

View file

@ -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<str> = ::std::rc::Rc::from(stringify!($name));
$env.declare(s.clone(), ::complexpr::value::Value::Func(::complexpr::value::func::Func::Builtin { func: [<fn_ $name>], arg_count: $arg_count, name: s }));
}}};
($env:ident, $name:literal, $rust_name:ident, $arg_count:literal) => {{
let s: ::std::rc::Rc<str> = ::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 }));
}};
}

View file

@ -2,7 +2,9 @@ use std::cmp::Ordering;
use num_traits::{ToPrimitive, Pow, Signed}; 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 { enum Floaty {
Real(f64), Complex(Complex) Real(f64), Complex(Complex)

View file

@ -1,22 +1,8 @@
pub mod io;
pub mod iter;
pub mod math;
use std::{time::{SystemTime, UNIX_EPOCH}, rc::Rc, cell::RefCell}; 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] use crate::declare_fn;
macro_rules! declare_fn {
($env:ident, $name:ident, $arg_count:literal) => {::paste::paste!{{
let s: ::std::rc::Rc<str> = ::std::rc::Rc::from(stringify!($name));
$env.declare(s.clone(), $crate::value::Value::Func($crate::value::func::Func::Builtin { func: [<fn_ $name>], arg_count: $arg_count, name: s }));
}}};
($env:ident, $name:literal, $rust_name:ident, $arg_count:literal) => {{
let s: ::std::rc::Rc<str> = ::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 }));
}};
}
pub fn load(env: &mut Environment) { pub fn load(env: &mut Environment) {
declare_fn!(env, "type", fn_type, 1); declare_fn!(env, "type", fn_type, 1);

View file

@ -8,5 +8,3 @@ num-complex = "0.4.2"
num-rational = "0.4.1" num-rational = "0.4.1"
num-traits = "0.2.15" num-traits = "0.2.15"
strum = { version = "0.24.1", features = ["derive"] } strum = { version = "0.24.1", features = ["derive"] }
paste = "1.0.9"
lazy_static = "1.4.0"

View file

@ -1,6 +1,6 @@
use std::{cell::RefCell, rc::Rc}; 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<String>, env: Option<EnvRef>, repl: bool) -> Result<Value, Box<dyn std::error::Error>> { pub fn interpret(src: &str, fname: Option<String>, env: Option<EnvRef>, repl: bool) -> Result<Value, Box<dyn std::error::Error>> {
let ctx_name = if repl { "<interactive input>" } else { fname.as_ref().map(|s| s.as_ref()).unwrap_or("<unknown>") }; let ctx_name = if repl { "<interactive input>" } else { fname.as_ref().map(|s| s.as_ref()).unwrap_or("<unknown>") };
@ -13,10 +13,6 @@ pub fn interpret(src: &str, fname: Option<String>, env: Option<EnvRef>, repl: bo
environ = env; environ = env;
} else { } else {
environ = Rc::new(RefCell::new(Environment::new())); 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; let mut result = Value::Nil;

View file

@ -8,7 +8,6 @@ pub mod value;
pub mod eval; pub mod eval;
pub mod interpreter; pub mod interpreter;
pub mod env; pub mod env;
pub mod stdlib;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Position { pub struct Position {