regulus/
lib.rs

1#![warn(
2    clippy::nursery,
3    clippy::pedantic,
4    clippy::print_stdout,
5    clippy::print_stderr,
6    clippy::dbg_macro
7)]
8#![allow(
9    clippy::missing_errors_doc,
10    clippy::option_if_let_else,
11    clippy::must_use_candidate,
12    clippy::redundant_pub_crate,
13    clippy::needless_pass_by_value
14)]
15
16mod argument;
17mod atom;
18mod exception;
19mod function;
20mod macros;
21mod optimizations;
22mod parsing;
23mod state;
24
25mod builtins;
26
27#[rustfmt::skip]
28mod interned_stdlib;
29
30// TODO: reconsider and redesign the prelude, differentiate between internal and external usage
31pub mod prelude {
32    pub use crate::{
33        FILE_EXTENSION,
34        argument::Argument,
35        atom::{Atom, Object},
36        exception::{Exception, Result},
37        function::{Function, FunctionBody, FunctionCall},
38        functions,
39        parsing::{Position, Span},
40        raise, run, run_file,
41        state::{State, WriteHandle},
42    };
43}
44
45pub(crate) fn no_path() -> Rc<PathBuf> {
46    Rc::new(PathBuf::new())
47}
48
49use crate::{atom::Atom, exception::Result, state::State};
50use std::path::{Path, PathBuf};
51use std::rc::Rc;
52
53pub const FILE_EXTENSION: &str = "re";
54
55/// A convenient helper for directly running one file program.
56///
57/// Returns only the result of running the program, not the final state.
58///
59/// For more options, use [`State`] instead.
60///
61/// # Panics
62/// Panics if the path is invalid or cannot be read from.
63pub fn run_file(path: impl AsRef<Path>) -> Result<Atom> {
64    State::new().with_source_file(path).unwrap().run()
65}
66
67/// A convenient helper for directly running a program string.
68///
69/// Returns only the result of running the program, not the final state.
70///
71/// For more options, use [`State`] instead.
72pub fn run(code: impl AsRef<str>) -> Result<Atom> {
73    State::new().with_code(code).run()
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn bare_value_program_return() {
82        assert_eq!(
83            State::new().with_code("_(4)").run().unwrap().int().unwrap(),
84            4
85        );
86        assert_eq!(State::new().with_code("4").run().unwrap().int().unwrap(), 4);
87        assert_eq!(
88            State::new()
89                .with_code("=(x, 4), x")
90                .run()
91                .unwrap()
92                .int()
93                .unwrap(),
94            4
95        );
96    }
97}