Continue revising built-in functions
This commit is contained in:
parent
fb78798a1d
commit
dbbb912b82
@ -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!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,17 +255,20 @@ 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)))
|
||||||
|
.to(BuiltInFunctionCall::ReadLine),
|
||||||
just(Token::Keyword(Keyword::Sleep))
|
just(Token::Keyword(Keyword::Sleep))
|
||||||
|
.ignore_then(just(Token::Control(Control::ParenOpen)))
|
||||||
.ignore_then(expression.clone())
|
.ignore_then(expression.clone())
|
||||||
.map(|expression| BuiltInFunctionCall::Sleep(expression)),
|
.map(|expression| BuiltInFunctionCall::Sleep(expression)),
|
||||||
just(Token::Keyword(Keyword::WriteLine))
|
just(Token::Keyword(Keyword::WriteLine))
|
||||||
|
.ignore_then(just(Token::Control(Control::ParenOpen)))
|
||||||
.ignore_then(expression.clone())
|
.ignore_then(expression.clone())
|
||||||
.map(|expression| BuiltInFunctionCall::WriteLine(expression)),
|
.map(|expression| BuiltInFunctionCall::WriteLine(expression)),
|
||||||
)))
|
))
|
||||||
.then_ignore(just(Token::Control(Control::DoubleUnderscore)))
|
.then_ignore(just(Token::Control(Control::ParenClose)))
|
||||||
.map_with(|built_in_function_call, state| {
|
.map_with(|built_in_function_call, state| {
|
||||||
Expression::BuiltInFunctionCall(
|
Expression::BuiltInFunctionCall(
|
||||||
Box::new(built_in_function_call).with_position(state.span()),
|
Box::new(built_in_function_call).with_position(state.span()),
|
||||||
@ -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))
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
thread = {
|
thread = {
|
||||||
sleep = (milliseconds: int) none {
|
sleep = (milliseconds: int) none {
|
||||||
__SLEEP__(milliseconds)
|
SLEEP(milliseconds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user