Add parsing for while loops
This commit is contained in:
parent
565fd450a9
commit
346d9ba878
@ -11,6 +11,7 @@ pub mod math;
|
||||
pub mod statement;
|
||||
pub mod r#type;
|
||||
pub mod value_node;
|
||||
pub mod r#while;
|
||||
|
||||
pub use self::{
|
||||
assignment::{Assignment, AssignmentOperator},
|
||||
@ -24,6 +25,7 @@ pub use self::{
|
||||
math::Math,
|
||||
r#loop::Loop,
|
||||
r#type::Type,
|
||||
r#while::While,
|
||||
statement::Statement,
|
||||
value_node::ValueNode,
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
error::{RuntimeError, ValidationError},
|
||||
};
|
||||
|
||||
use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, Type};
|
||||
use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, Type, While};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub enum Statement {
|
||||
@ -13,6 +13,7 @@ pub enum Statement {
|
||||
Expression(Expression),
|
||||
IfElse(IfElse),
|
||||
Loop(Loop),
|
||||
While(While),
|
||||
}
|
||||
|
||||
impl AbstractTree for Statement {
|
||||
@ -24,6 +25,7 @@ impl AbstractTree for Statement {
|
||||
Statement::Expression(expression) => expression.expected_type(_context),
|
||||
Statement::IfElse(if_else) => if_else.expected_type(_context),
|
||||
Statement::Loop(r#loop) => r#loop.expected_type(_context),
|
||||
Statement::While(r#while) => r#while.expected_type(_context),
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +37,7 @@ impl AbstractTree for Statement {
|
||||
Statement::Expression(expression) => expression.validate(_context),
|
||||
Statement::IfElse(if_else) => if_else.validate(_context),
|
||||
Statement::Loop(r#loop) => r#loop.validate(_context),
|
||||
Statement::While(r#while) => r#while.validate(_context),
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +49,7 @@ impl AbstractTree for Statement {
|
||||
Statement::Expression(expression) => expression.run(_context),
|
||||
Statement::IfElse(if_else) => if_else.run(_context),
|
||||
Statement::Loop(r#loop) => r#loop.run(_context),
|
||||
Statement::While(r#while) => r#while.run(_context),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
src/abstract_tree/while.rs
Normal file
32
src/abstract_tree/while.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use crate::{
|
||||
context::Context,
|
||||
error::{RuntimeError, ValidationError},
|
||||
};
|
||||
|
||||
use super::{AbstractTree, Action, Block, Expression, Type};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct While {
|
||||
expression: Expression,
|
||||
block: Block,
|
||||
}
|
||||
|
||||
impl While {
|
||||
pub fn new(expression: Expression, block: Block) -> Self {
|
||||
Self { expression, block }
|
||||
}
|
||||
}
|
||||
|
||||
impl AbstractTree for While {
|
||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -92,8 +92,8 @@ impl Display for Control {
|
||||
Control::DoubleColon => write!(f, "::"),
|
||||
Control::Colon => write!(f, ":"),
|
||||
Control::Dot => write!(f, "."),
|
||||
Control::DoubleDot => write!(f, ".."),
|
||||
Control::Semicolon => write!(f, ";"),
|
||||
Control::DoubleDot => write!(f, ".."),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,6 +226,7 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
just("range").padded(),
|
||||
just("str").padded(),
|
||||
just("loop").padded(),
|
||||
just("while").padded(),
|
||||
))
|
||||
.map(Token::Keyword);
|
||||
|
||||
|
@ -334,6 +334,11 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
.map(|statements| Statement::Loop(Loop::new(statements)))
|
||||
.boxed();
|
||||
|
||||
let r#while = just(Token::Keyword("while"))
|
||||
.ignore_then(expression.clone())
|
||||
.then(block.clone())
|
||||
.map(|(expression, block)| Statement::While(While::new(expression, block)));
|
||||
|
||||
let if_else = just(Token::Keyword("if"))
|
||||
.ignore_then(expression.clone())
|
||||
.then(block.clone())
|
||||
@ -354,6 +359,7 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
r#break,
|
||||
block_statement,
|
||||
r#loop,
|
||||
r#while,
|
||||
))
|
||||
.then_ignore(just(Token::Control(Control::Semicolon)).or_not())
|
||||
.boxed()
|
||||
@ -372,6 +378,22 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn r#while() {
|
||||
assert_eq!(
|
||||
parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0].0,
|
||||
Statement::While(While::new(
|
||||
Expression::Value(ValueNode::Boolean(true)),
|
||||
Block::new(vec![Statement::Expression(Expression::FunctionCall(
|
||||
FunctionCall::new(
|
||||
Expression::Identifier(Identifier::new("output")),
|
||||
vec![Expression::Value(ValueNode::String("hi".to_string()))]
|
||||
)
|
||||
))])
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn types() {
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user