diff --git a/src/abstract_tree/identifier.rs b/src/abstract_tree/identifier.rs index f09ddc0..6f3d5dd 100644 --- a/src/abstract_tree/identifier.rs +++ b/src/abstract_tree/identifier.rs @@ -47,9 +47,7 @@ impl AbstractTree for Identifier { } else { for built_in_function in BUILT_IN_FUNCTIONS { if self.0 == built_in_function.name() { - if let Type::Function { return_type, .. } = built_in_function.r#type() { - return Ok(*return_type); - } + return Ok(built_in_function.r#type()); } } diff --git a/src/built_in_functions/commands.rs b/src/built_in_functions/commands.rs new file mode 100644 index 0000000..03f7edc --- /dev/null +++ b/src/built_in_functions/commands.rs @@ -0,0 +1,33 @@ +use std::process::Command; + +use crate::{BuiltInFunction, Error, Map, Result, Type, Value}; + +pub struct Sh; + +impl BuiltInFunction for Sh { + fn name(&self) -> &'static str { + "sh" + } + + fn run(&self, arguments: &[Value], _context: &Map) -> Result { + Error::expect_argument_amount(self, 1, arguments.len())?; + + let command_text = arguments.first().unwrap().as_string()?; + let mut command = Command::new("sh"); + + for word in command_text.split(' ') { + command.arg(word); + } + + let output = command.spawn()?.wait_with_output()?.stdout; + + Ok(Value::String(String::from_utf8(output)?)) + } + + fn r#type(&self) -> crate::Type { + Type::Function { + parameter_types: vec![Type::String], + return_type: Box::new(Type::String), + } + } +} diff --git a/src/built_in_functions/mod.rs b/src/built_in_functions/mod.rs index 8aaabfc..f1fd830 100644 --- a/src/built_in_functions/mod.rs +++ b/src/built_in_functions/mod.rs @@ -3,6 +3,7 @@ use crate::{Map, Result, Type, Value}; mod assert; mod collections; +mod commands; mod data_formats; mod fs; mod network; @@ -14,10 +15,11 @@ mod r#type; /// /// This is the public interface to access built-in functions by iterating over /// the references it holds. -pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 15] = [ +pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 16] = [ &assert::Assert, &assert::AssertEqual, &collections::Length, + &commands::Sh, &data_formats::FromJson, &data_formats::ToJson, &fs::Read,