dust/dust-lang/src/abstract_tree/built_in_function_call.rs

176 lines
6.5 KiB
Rust
Raw Normal View History

use std::{
2024-05-25 15:48:43 +00:00
fs::read_to_string,
io::{stdin, stdout, Write},
thread,
time::Duration,
};
2024-04-21 21:00:08 +00:00
2024-06-04 18:47:15 +00:00
use serde::{Deserialize, Serialize};
2024-04-21 21:00:08 +00:00
use crate::{
context::Context,
2024-04-21 22:06:26 +00:00
error::{RuntimeError, ValidationError},
value::ValueInner,
Value,
2024-04-21 21:00:08 +00:00
};
2024-06-22 00:59:38 +00:00
use super::{AbstractNode, Evaluation, Expression, Type, TypeConstructor};
2024-04-21 21:00:08 +00:00
2024-06-04 18:47:15 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
2024-04-21 21:00:08 +00:00
pub enum BuiltInFunctionCall {
2024-06-17 14:10:06 +00:00
JsonParse(TypeConstructor, Expression),
Length(Expression),
ReadFile(Expression),
2024-04-21 21:00:08 +00:00
ReadLine,
2024-06-17 14:10:06 +00:00
Sleep(Expression),
WriteLine(Expression),
2024-04-21 21:00:08 +00:00
}
2024-06-22 00:59:38 +00:00
impl AbstractNode for BuiltInFunctionCall {
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
Ok(())
}
2024-04-21 21:00:08 +00:00
2024-06-22 00:59:38 +00:00
fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> {
match self {
2024-06-04 18:47:15 +00:00
BuiltInFunctionCall::JsonParse(_, expression) => {
expression.validate(_context, _manage_memory)
}
BuiltInFunctionCall::Length(expression) => {
expression.validate(_context, _manage_memory)
}
2024-05-25 15:48:43 +00:00
BuiltInFunctionCall::ReadFile(expression) => {
expression.validate(_context, _manage_memory)
}
BuiltInFunctionCall::ReadLine => Ok(()),
2024-04-22 11:56:03 +00:00
BuiltInFunctionCall::Sleep(expression) => expression.validate(_context, _manage_memory),
BuiltInFunctionCall::WriteLine(expression) => {
expression.validate(_context, _manage_memory)
}
}
2024-04-21 21:00:08 +00:00
}
2024-06-17 14:10:06 +00:00
fn evaluate(
self,
2024-06-22 00:59:38 +00:00
context: &Context,
2024-06-17 14:10:06 +00:00
_manage_memory: bool,
2024-06-22 00:59:38 +00:00
) -> Result<Option<Evaluation>, RuntimeError> {
2024-04-21 22:06:26 +00:00
match self {
2024-06-16 07:12:04 +00:00
BuiltInFunctionCall::JsonParse(_type, expression) => {
2024-06-17 14:10:06 +00:00
let action = expression.clone().evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
2024-06-04 18:47:15 +00:00
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::String(string) = value.inner().as_ref() {
let deserialized = serde_json::from_str(string)?;
2024-06-22 00:59:38 +00:00
Ok(Some(Evaluation::Return(deserialized)))
2024-06-04 18:47:15 +00:00
} else {
Err(RuntimeError::ValidationFailure(
ValidationError::ExpectedString {
actual: value.r#type(context)?,
position: expression.position(),
},
))
}
}
BuiltInFunctionCall::Length(expression) => {
2024-06-17 14:10:06 +00:00
let action = expression.clone().evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
2024-05-25 15:48:43 +00:00
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
2024-06-04 18:47:15 +00:00
let length = if let ValueInner::List(list) = value.inner().as_ref() {
list.len() as i64
} else {
0
};
2024-05-25 15:48:43 +00:00
2024-06-22 00:59:38 +00:00
Ok(Some(Evaluation::Return(Value::integer(length))))
2024-06-04 18:47:15 +00:00
}
BuiltInFunctionCall::ReadFile(expression) => {
2024-06-17 14:10:06 +00:00
let action = expression.clone().evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
2024-06-04 18:47:15 +00:00
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
2024-05-25 15:48:43 +00:00
let file_contents = if let ValueInner::String(path) = value.inner().as_ref() {
read_to_string(path)?
} else {
String::with_capacity(0)
};
2024-06-22 00:59:38 +00:00
Ok(Some(Evaluation::Return(Value::string(file_contents))))
2024-05-25 15:48:43 +00:00
}
2024-04-21 22:06:26 +00:00
BuiltInFunctionCall::ReadLine => {
let mut buffer = String::new();
stdin().read_line(&mut buffer)?;
2024-06-22 00:59:38 +00:00
Ok(Some(Evaluation::Return(Value::string(
buffer.strip_suffix('\n').unwrap_or(&buffer),
2024-06-22 00:59:38 +00:00
))))
2024-04-21 22:06:26 +00:00
}
BuiltInFunctionCall::Sleep(expression) => {
2024-06-17 14:10:06 +00:00
let action = expression.clone().evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
2024-04-21 22:06:26 +00:00
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
2024-04-21 22:22:59 +00:00
if let ValueInner::Integer(milliseconds) = value.inner().as_ref() {
2024-04-21 22:06:26 +00:00
thread::sleep(Duration::from_millis(*milliseconds as u64));
2024-04-21 22:22:59 +00:00
}
2024-04-21 22:06:26 +00:00
2024-06-21 22:28:12 +00:00
Ok(Evaluation::Void)
2024-04-21 22:22:59 +00:00
}
BuiltInFunctionCall::WriteLine(expression) => {
2024-06-17 14:10:06 +00:00
let action = expression.clone().evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action {
2024-04-21 22:22:59 +00:00
value
2024-04-21 22:06:26 +00:00
} else {
2024-04-21 22:22:59 +00:00
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::String(output) = value.inner().as_ref() {
let mut stdout = stdout();
stdout.write_all(output.as_bytes())?;
stdout.write(b"\n")?;
stdout.flush()?;
2024-04-21 22:06:26 +00:00
}
2024-04-21 22:22:59 +00:00
2024-06-21 22:28:12 +00:00
Ok(Evaluation::Void)
2024-04-21 22:06:26 +00:00
}
}
2024-04-21 21:00:08 +00:00
}
2024-06-16 07:12:04 +00:00
2024-06-22 00:59:38 +00:00
fn expected_type(&self, context: &Context) -> Result<Option<Type>, ValidationError> {
2024-06-16 07:12:04 +00:00
match self {
2024-06-22 00:59:38 +00:00
BuiltInFunctionCall::JsonParse(r#type, _) => {
Ok(Some(r#type.clone().construct(&context)?))
}
BuiltInFunctionCall::Length(_) => Ok(Some(Type::Integer)),
BuiltInFunctionCall::ReadFile(_) => Ok(Some(Type::String)),
BuiltInFunctionCall::ReadLine => Ok(Some(Type::String)),
BuiltInFunctionCall::Sleep(_) => Ok(None),
BuiltInFunctionCall::WriteLine(_) => Ok(None),
2024-06-16 07:12:04 +00:00
}
}
}