mod and;
mod apply;
mod bimath;
mod block;
mod do_;
mod eq;
mod fun;
mod get;
mod get_type;
mod greater;
mod has;
mod head;
mod if_;
mod index;
mod is;
mod length;
mod less;
mod let_;
mod load;
mod math;
mod module;
mod multi;
mod not;
mod or;
mod pend;
mod plugin;
mod print;
mod range;
mod read;
mod set;
mod string_case;
mod substring;
mod tail;
mod to_string;
mod use_;
mod while_;
mod write;
use crate::{Environment, value::Value};
const FILE_EXT: &'static str = "ksl";
pub const TRUE_SYMBOL: &'static str = "t";
pub const FALSE_SYMBOL: &'static str = "f";
pub(crate) const KSL_PATH_ENV: &'static str = "KSL_PATH";
pub(crate) const DEFAULT_KSL_PATH: &'static str = "~/.local/share/ksl";
pub(crate) const MODULE_PATH_ENV: &'static str = "MODULE_PATH";
pub(crate) const MODULE_NAME_ENV: &'static str = "MODULE_NAME";
pub(crate) const BULTIN_FUNCTIONS: [&'static str; 64] = [
"Abs",
"Add",
"And",
"Append",
"Apply",
"Block",
"Concat",
"Cos",
"Cosh",
"Div",
"Do",
"Eq",
"Exp",
"Fun",
"Get",
"GetType",
"Greater",
"Has",
"Head",
"If",
"Index",
"IsAtom",
"IsBuiltin",
"IsInteger",
"IsLambda",
"IsList",
"IsNumber",
"IsObject",
"IsPlugin",
"IsString",
"IsUnit",
"Length",
"Less",
"Let",
"Ln",
"Load",
"Lowercase",
"Module",
"Mul",
"Neg",
"Not",
"Object",
"Or",
"Plugin",
"Power",
"Prepend",
"Print",
"Range",
"Read",
"Set",
"Sin",
"Sinh",
"Sub",
"SubString",
"Tail",
"Tan",
"Tanh",
"ToString",
"Trunc",
"Unit",
"Uppercase",
"Use",
"While",
"Write",
];
#[derive(Debug)]
enum MathFunctionType {
Abs,
Cos,
Cosh,
Exp,
Ln,
Neg,
Sin,
Sinh,
Tan,
Tanh,
Trunc,
}
#[derive(Debug)]
enum MultiFunctionType {
Add,
Concat,
Mul,
}
#[derive(Debug)]
enum BiMathFunctionType {
Div,
Power,
Sub,
}
#[derive(Debug)]
enum ValueType {
Atom,
Builtin,
Integer,
Lambda,
List,
Number,
Object,
Plugin,
String,
Unit,
}
pub(crate) fn eval_builtin(
symbol: &str,
args: &[Value],
env: &Environment,
) -> Option<(Value, Environment)> {
match symbol {
"Abs" => math::builtin(args, MathFunctionType::Abs, env),
"Add" => multi::builtin(args, MultiFunctionType::Add, env),
"And" => and::builtin(args, env),
"Append" => pend::builtin(args, false, env),
"Apply" => apply::builtin(args, env),
"Block" => block::builtin(args, env),
"Concat" => multi::builtin(args, MultiFunctionType::Concat, env),
"Cos" => math::builtin(args, MathFunctionType::Cos, env),
"Cosh" => math::builtin(args, MathFunctionType::Cosh, env),
"Div" => bimath::builtin(args, BiMathFunctionType::Div, env),
"Do" => do_::builtin(args, env),
"Eq" => eq::builtin(args, env),
"Exp" => math::builtin(args, MathFunctionType::Exp, env),
"Fun" => fun::builtin(args, env),
"Get" => get::builtin(args, env),
"GetType" => get_type::builtin(args, env),
"Greater" => greater::builtin(args, env),
"Has" => has::builtin(args, env),
"Head" => head::builtin(args, env),
"If" => if_::builtin(args, env),
"Index" => index::builtin(args, env),
"IsAtom" => is::builtin(args, ValueType::Atom, env),
"IsBuiltin" => is::builtin(args, ValueType::Builtin, env),
"IsInteger" => is::builtin(args, ValueType::Integer, env),
"IsLambda" => is::builtin(args, ValueType::Lambda, env),
"IsList" => is::builtin(args, ValueType::List, env),
"IsNumber" => is::builtin(args, ValueType::Number, env),
"IsObject" => is::builtin(args, ValueType::Object, env),
"IsPlugin" => is::builtin(args, ValueType::Plugin, env),
"IsString" => is::builtin(args, ValueType::String, env),
"IsUnit" => is::builtin(args, ValueType::Unit, env),
"Length" => length::builtin(args, env),
"Less" => less::builtin(args, env),
"Let" => let_::builtin(args, env),
"Ln" => math::builtin(args, MathFunctionType::Ln, env),
"Load" => load::builtin(args, env),
"Lowercase" => string_case::builtin(args, false, env),
"Module" => module::builtin(args, env),
"Mul" => multi::builtin(args, MultiFunctionType::Mul, env),
"Neg" => math::builtin(args, MathFunctionType::Neg, env),
"Not" => not::builtin(args, env),
"Object" => {
if let [Value::Identity(type_name)] = &args[..] {
Some((
Value::Object(type_name.clone(), Environment::new()),
Environment::new(),
))
} else {
eprintln!(
concat!(
"Error[ksl::builtin::Object]: ",
"`Object` only accepts a symbol as argument, ",
"but {:?} were passed."
),
args
);
None
}
}
"Or" => or::builtin(args, env),
"Plugin" => plugin::builtin(args, env),
"Power" => bimath::builtin(args, BiMathFunctionType::Power, env),
"Prepend" => pend::builtin(args, true, env),
"Print" => print::builtin(args, env),
"Range" => range::builtin(args, env),
"Read" => read::builtin(args, env),
"Set" => set::builtin(args, env),
"Sin" => math::builtin(args, MathFunctionType::Sin, env),
"Sinh" => math::builtin(args, MathFunctionType::Sinh, env),
"Sub" => bimath::builtin(args, BiMathFunctionType::Sub, env),
"SubString" => substring::builtin(args, env),
"Tail" => tail::builtin(args, env),
"Tan" => math::builtin(args, MathFunctionType::Tan, env),
"Tanh" => math::builtin(args, MathFunctionType::Tanh, env),
"ToString" => to_string::builtin(args, env),
"Trunc" => math::builtin(args, MathFunctionType::Trunc, env),
"Unit" => {
if args.is_empty() {
Some((Value::Unit, Environment::new()))
} else {
eprintln!(
concat!(
"Error[ksl::builtin::Unit]: ",
"`Unit` only accepts 0 arguments, ",
"but {} were passed."
),
args.len()
);
None
}
}
"Uppercase" => string_case::builtin(args, true, env),
"Use" => use_::builtin(args, env),
"While" => while_::builtin(args, env),
"Write" => write::builtin(args, env),
builtin_name => {
eprintln!(
concat!(
"Error[ksl::builtin::eval_builtin]: ",
"Built-in function `{}` is not implemented yet."
),
builtin_name
);
None
}
}
}