1
0

Add io:stdin to built-ins

This commit is contained in:
Jeff 2024-02-19 23:35:09 -05:00
parent cc76ca89cc
commit 6b88fbf8b9
4 changed files with 90 additions and 4 deletions

View File

@ -7,7 +7,7 @@ use crate::{error::RuntimeError, Context, Type, Value};
use super::Callable;
pub fn fs_functions() -> impl Iterator<Item = Fs> {
pub fn all_fs_functions() -> impl Iterator<Item = Fs> {
all()
}

View File

@ -0,0 +1,56 @@
use enum_iterator::{all, Sequence};
use serde::{Deserialize, Serialize};
use crate::{error::RuntimeError, Context, Type, Value};
use super::Callable;
pub fn all_io_functions() -> impl Iterator<Item = Io> {
all()
}
#[derive(Sequence, Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum Io {
Stdin,
}
impl Callable for Io {
fn name(&self) -> &'static str {
match self {
Io::Stdin => "stdin",
}
}
fn description(&self) -> &'static str {
match self {
Io::Stdin => "Read input from stdin.",
}
}
fn r#type(&self) -> crate::Type {
match self {
Io::Stdin => Type::Function {
parameter_types: vec![],
return_type: Box::new(Type::String),
},
}
}
fn call(
&self,
_arguments: &[Value],
_source: &str,
_context: &Context,
) -> Result<Value, RuntimeError> {
match self {
Io::Stdin => {
let mut input = String::new();
let stdin = std::io::stdin();
stdin.read_line(&mut input)?;
Ok(Value::string(input))
}
}
}
}

View File

@ -1,4 +1,5 @@
pub mod fs;
pub mod io;
pub mod json;
pub mod str;
@ -12,7 +13,7 @@ use crate::{
Context, EnumInstance, Format, Identifier, Type, Value,
};
use self::{fs::Fs, json::Json, str::StrFunction};
use self::{fs::Fs, io::Io, json::Json, str::StrFunction};
pub trait Callable {
fn name(&self) -> &'static str;
@ -30,6 +31,7 @@ pub trait Callable {
pub enum BuiltInFunction {
AssertEqual,
Fs(Fs),
Io(Io),
Json(Json),
Length,
Output,
@ -45,6 +47,7 @@ impl Callable for BuiltInFunction {
match self {
BuiltInFunction::AssertEqual => "assert_equal",
BuiltInFunction::Fs(fs_function) => fs_function.name(),
BuiltInFunction::Io(io_function) => io_function.name(),
BuiltInFunction::Json(json_function) => json_function.name(),
BuiltInFunction::Length => "length",
BuiltInFunction::Output => "output",
@ -60,6 +63,7 @@ impl Callable for BuiltInFunction {
match self {
BuiltInFunction::AssertEqual => "assert_equal",
BuiltInFunction::Fs(fs_function) => fs_function.description(),
BuiltInFunction::Io(io_function) => io_function.description(),
BuiltInFunction::Json(json_function) => json_function.description(),
BuiltInFunction::Length => "length",
BuiltInFunction::Output => "output",
@ -75,6 +79,7 @@ impl Callable for BuiltInFunction {
match self {
BuiltInFunction::AssertEqual => Type::function(vec![Type::Any, Type::Any], Type::None),
BuiltInFunction::Fs(fs_function) => fs_function.r#type(),
BuiltInFunction::Io(io_function) => io_function.r#type(),
BuiltInFunction::Json(json_function) => json_function.r#type(),
BuiltInFunction::Length => Type::function(vec![Type::Collection], Type::Integer),
BuiltInFunction::Output => Type::function(vec![Type::Any], Type::None),
@ -113,6 +118,7 @@ impl Callable for BuiltInFunction {
}
}
BuiltInFunction::Fs(fs_function) => fs_function.call(arguments, _source, context),
BuiltInFunction::Io(io_function) => io_function.call(arguments, _source, context),
BuiltInFunction::Json(json_function) => json_function.call(arguments, _source, context),
BuiltInFunction::Length => {
RuntimeError::expect_argument_amount(self.name(), 1, arguments.len())?;

View File

@ -4,12 +4,16 @@ use enum_iterator::{all, Sequence};
use serde::{Deserialize, Serialize};
use crate::{
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
built_in_functions::{
fs::all_fs_functions, io::all_io_functions, json::json_functions, str::string_functions,
Callable,
},
BuiltInFunction, EnumInstance, Function, Identifier, List, Map, Value,
};
static ARGS: OnceLock<Value> = OnceLock::new();
static FS: OnceLock<Value> = OnceLock::new();
static IO: OnceLock<Value> = OnceLock::new();
static JSON: OnceLock<Value> = OnceLock::new();
static NONE: OnceLock<Value> = OnceLock::new();
static RANDOM: OnceLock<Value> = OnceLock::new();
@ -32,6 +36,9 @@ pub enum BuiltInValue {
/// File system tools.
Fs,
/// Input and output tools.
Io,
/// JSON format tools.
Json,
@ -58,6 +65,7 @@ impl BuiltInValue {
BuiltInValue::Args => "args",
BuiltInValue::AssertEqual => "assert_equal",
BuiltInValue::Fs => "fs",
BuiltInValue::Io => "io",
BuiltInValue::Json => "json",
BuiltInValue::Length => BuiltInFunction::Length.name(),
BuiltInValue::None => "None",
@ -75,6 +83,7 @@ impl BuiltInValue {
BuiltInValue::Args => "The command line arguments sent to this program.",
BuiltInValue::AssertEqual => "Error if the two values are not equal.",
BuiltInValue::Fs => "File and directory tools.",
BuiltInValue::Io => "Input/output tools.",
BuiltInValue::Json => "JSON formatting tools.",
BuiltInValue::Length => BuiltInFunction::Length.description(),
BuiltInValue::None => "The absence of a value.",
@ -98,11 +107,26 @@ impl BuiltInValue {
BuiltInValue::AssertEqual => {
Value::Function(Function::BuiltIn(BuiltInFunction::AssertEqual))
}
BuiltInValue::Io => IO
.get_or_init(|| {
let mut io_map = Map::new();
for io_function in all_io_functions() {
let key = io_function.name();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Io(io_function)));
io_map.set(Identifier::new(key), value);
}
Value::Map(io_map)
})
.clone(),
BuiltInValue::Fs => FS
.get_or_init(|| {
let mut fs_map = Map::new();
for fs_function in fs_functions() {
for fs_function in all_fs_functions() {
let key = fs_function.name();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Fs(fs_function)));