ksl 0.1.7

KSL core library and interpreter
Documentation
//! # KSL core library
//!
//! [![github]](https://github.com/kands-code/rswk)
//! [![crates-io]](https://crates.io/crates/ksl)
//! [![docs-rs]](https://docs.rs/ksl)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! # Description
//!
//! This library provides a comprehensive set of functions
//! for tokenizing and executing KSL code.

mod builtin;
pub mod eval;
mod token;
pub mod value;

/// List of built-in functions.
pub use builtin::BULTIN_FUNCTIONS;
/// Literal value corresponding to the boolean false in Atom.
pub use builtin::FALSE_SYMBOL;
/// Module name in environment as key's literal value.
pub use builtin::MODULE_NAME_ENV;
/// Imported module path list in environment as key's literal value.
pub use builtin::MODULE_PATH_ENV;
/// Literal value corresponding to the boolean true in Atom.
pub use builtin::TRUE_SYMBOL;

use crate::value::Value;

/// Environment type in KSL
///
/// Currently an alias for HashMap, but its definition may change in the future,
/// so it's recommended to use `Environment` instead of directly using `HashMap`.
pub type Environment = std::collections::HashMap<String, Value>;

/// Initial Environment in KSL
///
/// Includes built-in functions and various constants in KSL.
///
/// # Example
///
/// ```rust
/// fn main() { let _ = ksl::init_environment(); }
/// ```
pub fn init_environment() -> Environment {
    let mut env = Environment::new();
    for &func in BULTIN_FUNCTIONS.iter() {
        let _ = env.insert(String::from(func), Value::Builtin(func));
    }
    let _ = env.insert(String::from(MODULE_PATH_ENV), Value::List(Vec::new()));
    env
}

/// Check if two numbers are equal.
fn is_number_eq(n1: f64, n2: f64) -> bool { (n1 - n2).abs() <= 1.9073486328125e-6 }

/// Expand the tilde at the start of a path.
fn expand_tilde(path: String) -> Option<String> {
    if path.starts_with('~') {
        Some(
            (match std::env::var(if cfg!(target_os = "windows") {
                "USERPROFILE"
            } else {
                "HOME"
            }) {
                Ok(p) => p,
                Err(_) => {
                    eprintln!(concat!(
                        "Error[ksl::eval::eval_apply]: ",
                        "Unable to retrieve user home directory path."
                    ));
                    return None;
                }
            }) + &path[1..],
        )
    } else {
        Some(path)
    }
}