diff --git a/src/built_in_functions/mod.rs b/src/built_in_functions/mod.rs index 7f67740..5a11d9e 100644 --- a/src/built_in_functions/mod.rs +++ b/src/built_in_functions/mod.rs @@ -11,13 +11,14 @@ mod option; mod output; mod packages; mod random; +mod std; mod r#type; /// All built-in functions recognized by the interpreter. /// /// This is the public interface to access built-in functions by iterating over /// the references it holds. -pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 21] = [ +pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 22] = [ &assert::Assert, &assert::AssertEqual, &collections::Length, @@ -38,6 +39,7 @@ pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 21] = [ &random::RandomBoolean, &random::RandomFloat, &random::RandomInteger, + &std::Std, &r#type::TypeFunction, ]; diff --git a/src/built_in_functions/std.rs b/src/built_in_functions/std.rs new file mode 100644 index 0000000..8b2666e --- /dev/null +++ b/src/built_in_functions/std.rs @@ -0,0 +1,35 @@ +use std::sync::OnceLock; + +use crate::{interpret_with_context, BuiltInFunction, Error, Map, Result, Type, Value}; + +static STD: OnceLock = OnceLock::new(); + +pub struct Std; + +impl BuiltInFunction for Std { + fn name(&self) -> &'static str { + "std" + } + + fn run(&self, arguments: &[Value], _context: &Map) -> Result { + Error::expect_argument_amount(self, 0, arguments.len())?; + + let std_context = STD.get_or_init(|| { + let std_source = "say_hi = () { output(hi) }"; + let std_context = Map::new(); + + interpret_with_context(std_source, std_context.clone()).unwrap(); + + std_context + }); + + Ok(Value::Map(std_context.clone())) + } + + fn r#type(&self) -> Type { + Type::Function { + parameter_types: vec![], + return_type: Box::new(Type::Map), + } + } +}