regulus/
lib.rs

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