2024-04-27 09:45:39 +00:00
|
|
|
use std::{
|
2024-05-25 15:48:43 +00:00
|
|
|
fs::read_to_string,
|
2024-04-27 09:45:39 +00:00
|
|
|
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::{
|
|
|
|
abstract_tree::{Action, Type},
|
|
|
|
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-04 18:47:15 +00:00
|
|
|
use super::{AbstractNode, Expression, WithPosition};
|
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-04 18:47:15 +00:00
|
|
|
JsonParse(WithPosition<Type>, Expression),
|
|
|
|
Length(Expression),
|
2024-05-25 15:48:43 +00:00
|
|
|
ReadFile(Expression),
|
2024-04-21 21:00:08 +00:00
|
|
|
ReadLine,
|
|
|
|
Sleep(Expression),
|
|
|
|
WriteLine(Expression),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractNode for BuiltInFunctionCall {
|
2024-04-22 12:25:20 +00:00
|
|
|
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
|
2024-04-21 22:06:26 +00:00
|
|
|
match self {
|
2024-06-04 18:47:15 +00:00
|
|
|
BuiltInFunctionCall::JsonParse(r#type, _) => Ok(r#type.item.clone()),
|
|
|
|
BuiltInFunctionCall::Length(_) => Ok(Type::Integer),
|
2024-05-25 15:48:43 +00:00
|
|
|
BuiltInFunctionCall::ReadFile(_) => Ok(Type::String),
|
2024-04-21 22:06:26 +00:00
|
|
|
BuiltInFunctionCall::ReadLine => Ok(Type::String),
|
|
|
|
BuiltInFunctionCall::Sleep(_) => Ok(Type::None),
|
|
|
|
BuiltInFunctionCall::WriteLine(_) => Ok(Type::None),
|
|
|
|
}
|
2024-04-21 21:00:08 +00:00
|
|
|
}
|
|
|
|
|
2024-04-22 12:25:20 +00:00
|
|
|
fn validate(
|
|
|
|
&self,
|
|
|
|
_context: &mut Context,
|
|
|
|
_manage_memory: bool,
|
|
|
|
) -> Result<(), ValidationError> {
|
2024-04-22 05:51:34 +00:00
|
|
|
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)
|
|
|
|
}
|
2024-04-22 05:51:34 +00:00
|
|
|
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-22 05:51:34 +00:00
|
|
|
}
|
2024-04-21 21:00:08 +00:00
|
|
|
}
|
|
|
|
|
2024-04-22 11:56:03 +00:00
|
|
|
fn run(self, context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
|
2024-04-21 22:06:26 +00:00
|
|
|
match self {
|
2024-06-04 18:47:15 +00:00
|
|
|
BuiltInFunctionCall::JsonParse(r#type, expression) => {
|
|
|
|
let action = expression.clone().run(context, _manage_memory)?;
|
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
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)?;
|
|
|
|
|
|
|
|
Ok(Action::Return(deserialized))
|
|
|
|
} else {
|
|
|
|
Err(RuntimeError::ValidationFailure(
|
|
|
|
ValidationError::ExpectedString {
|
|
|
|
actual: value.r#type(context)?,
|
|
|
|
position: expression.position(),
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
BuiltInFunctionCall::Length(expression) => {
|
2024-05-25 15:48:43 +00:00
|
|
|
let action = expression.clone().run(context, _manage_memory)?;
|
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
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-04 18:47:15 +00:00
|
|
|
Ok(Action::Return(Value::integer(length)))
|
|
|
|
}
|
|
|
|
BuiltInFunctionCall::ReadFile(expression) => {
|
|
|
|
let action = expression.clone().run(context, _manage_memory)?;
|
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
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)
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Action::Return(Value::string(file_contents)))
|
|
|
|
}
|
2024-04-21 22:06:26 +00:00
|
|
|
BuiltInFunctionCall::ReadLine => {
|
|
|
|
let mut buffer = String::new();
|
|
|
|
|
|
|
|
stdin().read_line(&mut buffer)?;
|
|
|
|
|
2024-04-27 09:45:39 +00:00
|
|
|
Ok(Action::Return(Value::string(
|
|
|
|
buffer.strip_suffix('\n').unwrap_or(&buffer),
|
|
|
|
)))
|
2024-04-21 22:06:26 +00:00
|
|
|
}
|
|
|
|
BuiltInFunctionCall::Sleep(expression) => {
|
2024-04-22 11:56:03 +00:00
|
|
|
let action = expression.clone().run(context, _manage_memory)?;
|
2024-04-21 22:22:59 +00:00
|
|
|
let value = if let Action::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-04-21 22:22:59 +00:00
|
|
|
Ok(Action::None)
|
|
|
|
}
|
|
|
|
BuiltInFunctionCall::WriteLine(expression) => {
|
2024-04-22 11:56:03 +00:00
|
|
|
let action = expression.clone().run(context, _manage_memory)?;
|
2024-04-21 22:22:59 +00:00
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
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() {
|
2024-04-27 09:45:39 +00:00
|
|
|
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
|
|
|
|
|
|
|
Ok(Action::None)
|
2024-04-21 22:06:26 +00:00
|
|
|
}
|
|
|
|
}
|
2024-04-21 21:00:08 +00:00
|
|
|
}
|
|
|
|
}
|