1
0

Continue revising built-in functions

This commit is contained in:
Jeff 2024-04-21 18:06:26 -04:00
parent fb78798a1d
commit dbbb912b82
5 changed files with 77 additions and 40 deletions

View File

@ -1,17 +1,14 @@
use std::{ use std::{io::stdin, thread, time::Duration};
fmt::{self, Display, Formatter},
io::stdin,
thread,
time::Duration,
};
use crate::{ use crate::{
abstract_tree::{Action, Type}, abstract_tree::{Action, Type},
context::Context, context::Context,
error::RuntimeError, error::{RuntimeError, ValidationError},
value::ValueInner,
Value,
}; };
use super::{AbstractNode, Expression, WithPosition}; use super::{AbstractNode, Expression};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum BuiltInFunctionCall { pub enum BuiltInFunctionCall {
@ -21,15 +18,46 @@ pub enum BuiltInFunctionCall {
} }
impl AbstractNode for BuiltInFunctionCall { impl AbstractNode for BuiltInFunctionCall {
fn expected_type(&self, context: &Context) -> Result<Type, crate::error::ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
todo!() match self {
BuiltInFunctionCall::ReadLine => Ok(Type::String),
BuiltInFunctionCall::Sleep(_) => Ok(Type::None),
BuiltInFunctionCall::WriteLine(_) => Ok(Type::None),
}
} }
fn validate(&self, context: &Context) -> Result<(), crate::error::ValidationError> { fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
todo!() Ok(())
} }
fn run(self, context: &Context) -> Result<Action, RuntimeError> { fn run(self, context: &Context) -> Result<Action, RuntimeError> {
todo!() match self {
BuiltInFunctionCall::ReadLine => {
let mut buffer = String::new();
stdin().read_line(&mut buffer)?;
Ok(Action::Return(Value::string(buffer)))
}
BuiltInFunctionCall::Sleep(expression) => {
let expression_run = expression.clone().run(context)?;
let expression_value = if let Action::Return(value) = expression_run {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position()),
));
};
if let ValueInner::Integer(milliseconds) = expression_value.inner().as_ref() {
thread::sleep(Duration::from_millis(*milliseconds as u64));
Ok(Action::None)
} else {
panic!("Expected an integer.");
}
}
BuiltInFunctionCall::WriteLine(_) => todo!(),
}
} }
} }

View File

@ -55,7 +55,9 @@ impl AbstractNode for Expression {
Expression::Logic(logic) => logic.node.expected_type(_context), Expression::Logic(logic) => logic.node.expected_type(_context),
Expression::Math(math) => math.node.expected_type(_context), Expression::Math(math) => math.node.expected_type(_context),
Expression::Value(value_node) => value_node.node.expected_type(_context), Expression::Value(value_node) => value_node.node.expected_type(_context),
Expression::BuiltInFunctionCall(_) => todo!(), Expression::BuiltInFunctionCall(built_in_function_call) => {
built_in_function_call.node.expected_type(_context)
}
} }
} }
@ -77,7 +79,9 @@ impl AbstractNode for Expression {
Expression::Logic(logic) => logic.node.validate(context), Expression::Logic(logic) => logic.node.validate(context),
Expression::Math(math) => math.node.validate(context), Expression::Math(math) => math.node.validate(context),
Expression::Value(value_node) => value_node.node.validate(context), Expression::Value(value_node) => value_node.node.validate(context),
Expression::BuiltInFunctionCall(_) => todo!(), Expression::BuiltInFunctionCall(built_in_function_call) => {
built_in_function_call.node.validate(context)
}
} }
} }
@ -101,7 +105,9 @@ impl AbstractNode for Expression {
Expression::Logic(logic) => logic.node.run(_context), Expression::Logic(logic) => logic.node.run(_context),
Expression::Math(math) => math.node.run(_context), Expression::Math(math) => math.node.run(_context),
Expression::Value(value_node) => value_node.node.run(_context), Expression::Value(value_node) => value_node.node.run(_context),
Expression::BuiltInFunctionCall(_) => todo!(), Expression::BuiltInFunctionCall(built_in_function_call) => {
built_in_function_call.node.run(_context)
}
} }
} }
} }

View File

@ -255,22 +255,25 @@ pub fn parser<'src>(
}, },
); );
let built_in_function_call = just(Token::Control(Control::DoubleUnderscore)) let built_in_function_call = choice((
.ignore_then(choice(( just(Token::Keyword(Keyword::ReadLine))
just(Token::Keyword(Keyword::ReadLine)).to(BuiltInFunctionCall::ReadLine), .ignore_then(just(Token::Control(Control::ParenOpen)))
just(Token::Keyword(Keyword::Sleep)) .to(BuiltInFunctionCall::ReadLine),
.ignore_then(expression.clone()) just(Token::Keyword(Keyword::Sleep))
.map(|expression| BuiltInFunctionCall::Sleep(expression)), .ignore_then(just(Token::Control(Control::ParenOpen)))
just(Token::Keyword(Keyword::WriteLine)) .ignore_then(expression.clone())
.ignore_then(expression.clone()) .map(|expression| BuiltInFunctionCall::Sleep(expression)),
.map(|expression| BuiltInFunctionCall::WriteLine(expression)), just(Token::Keyword(Keyword::WriteLine))
))) .ignore_then(just(Token::Control(Control::ParenOpen)))
.then_ignore(just(Token::Control(Control::DoubleUnderscore))) .ignore_then(expression.clone())
.map_with(|built_in_function_call, state| { .map(|expression| BuiltInFunctionCall::WriteLine(expression)),
Expression::BuiltInFunctionCall( ))
Box::new(built_in_function_call).with_position(state.span()), .then_ignore(just(Token::Control(Control::ParenClose)))
) .map_with(|built_in_function_call, state| {
}); Expression::BuiltInFunctionCall(
Box::new(built_in_function_call).with_position(state.span()),
)
});
let structure_field = identifier let structure_field = identifier
.clone() .clone()
@ -600,19 +603,19 @@ mod tests {
#[test] #[test]
fn built_in_function() { fn built_in_function() {
assert_eq!( assert_eq!(
parse(&lex("__READ_LINE__").unwrap()).unwrap()[0], parse(&lex("READ_LINE()").unwrap()).unwrap()[0],
Statement::Expression(Expression::BuiltInFunctionCall( Statement::Expression(Expression::BuiltInFunctionCall(
Box::new(BuiltInFunctionCall::ReadLine).with_position((0, 13)) Box::new(BuiltInFunctionCall::ReadLine).with_position((0, 11))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("__WRITE_LINE 'hiya'__").unwrap()).unwrap()[0], parse(&lex("WRITE_LINE('hiya')").unwrap()).unwrap()[0],
Statement::Expression(Expression::BuiltInFunctionCall( Statement::Expression(Expression::BuiltInFunctionCall(
Box::new(BuiltInFunctionCall::WriteLine(Expression::Value( Box::new(BuiltInFunctionCall::WriteLine(Expression::Value(
ValueNode::String("hiya".to_string()).with_position((13, 19)) ValueNode::String("hiya".to_string()).with_position((11, 17))
))) )))
.with_position((0, 21)) .with_position((0, 18))
)) ))
); );
} }

View File

@ -1,9 +1,9 @@
io = { io = {
read_line = () str { read_line = () str {
__READ_LINE__() READ_LINE()
} }
write_line = (output: any) none { write_line = (output: any) none {
__WRITE_LINE__(output) WRITE_LINE(output)
} }
} }

View File

@ -1,5 +1,5 @@
thread = { thread = {
sleep = (milliseconds: int) none { sleep = (milliseconds: int) none {
__SLEEP__(milliseconds) SLEEP(milliseconds)
} }
} }