#![warn(
clippy::nursery,
clippy::pedantic,
clippy::print_stdout,
clippy::print_stderr,
clippy::dbg_macro
)]
#![allow(
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::option_if_let_else,
clippy::must_use_candidate,
clippy::redundant_pub_crate,
clippy::needless_pass_by_value,
clippy::missing_const_for_fn,
clippy::type_complexity
)]
mod argument;
mod atom;
mod exception;
mod function;
mod list;
mod macros;
mod optimizations;
mod parsing;
mod state;
mod builtins;
#[rustfmt::skip]
mod interned_stdlib;
pub mod prelude {
pub use crate::{
FILE_EXTENSION,
argument::Argument,
atom::{Atom, Object},
exception::{Exception, Result},
function::{Function, FunctionBody, FunctionCall},
functions,
list::List,
parsing::{Position, Span},
raise, run, run_file,
state::{State, Storage, WriteHandle},
};
}
use crate::{atom::Atom, exception::Result, state::State};
use std::path::{Path, PathBuf};
use std::rc::Rc;
pub(crate) fn no_path() -> Rc<PathBuf> {
Rc::new(PathBuf::new())
}
pub const FILE_EXTENSION: &str = "re";
pub fn run_file(path: impl AsRef<Path>) -> Result<Atom> {
State::new().with_source_file(path).unwrap().run()
}
pub fn run(code: impl AsRef<str>) -> Result<Atom> {
State::new().with_code(code).run()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bare_value_program_return() {
assert_eq!(run("_(4)").unwrap().int().unwrap(), 4);
assert_eq!(run("4").unwrap().int().unwrap(), 4);
assert_eq!(run("=(x, 4), x").unwrap().int().unwrap(), 4);
}
#[test]
fn state_reuse_exit() {
let mut state = State::new().with_code("exit(2)");
assert_eq!(state.run().unwrap(), Atom::Int(2));
state = state.with_code("exit(1)");
assert_eq!(state.run().unwrap(), Atom::Int(1));
state = state.with_code("3");
assert_eq!(state.run().unwrap(), Atom::Int(3));
}
#[expect(
clippy::neg_cmp_op_on_partial_ord,
reason = "that's what the test is about"
)]
#[test]
fn atom_not_ord() {
assert!(!(Atom::Null < Atom::Int(2)));
assert!(!(Atom::Null == Atom::Int(2)));
assert!(!(Atom::Null > Atom::Int(2)));
}
}