Begin implementing while loops
This commit is contained in:
parent
12418a3bba
commit
e82dd6736e
@ -1,3 +1,11 @@
|
|||||||
|
//! Abstract, executable representations of corresponding items found in Dust
|
||||||
|
//! source code. The types that implement [AbstractTree] are inteded to be
|
||||||
|
//! created by an [Evaluator].
|
||||||
|
//!
|
||||||
|
//! When adding new lanugage features, first extend the grammar to recognize new
|
||||||
|
//! syntax nodes. Then add a new AbstractTree type using the existing types as
|
||||||
|
//! examples.
|
||||||
|
|
||||||
pub mod assignment;
|
pub mod assignment;
|
||||||
pub mod expression;
|
pub mod expression;
|
||||||
pub mod function_call;
|
pub mod function_call;
|
||||||
@ -9,6 +17,7 @@ pub mod r#match;
|
|||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod statement;
|
pub mod statement;
|
||||||
pub mod tool;
|
pub mod tool;
|
||||||
|
pub mod r#while;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
assignment::*, expression::*, function_call::*, identifier::*, if_else::*, item::*, logic::*,
|
assignment::*, expression::*, function_call::*, identifier::*, if_else::*, item::*, logic::*,
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tool::Tool, AbstractTree, Assignment, Error, Expression, IfElse, Match, Result, Value,
|
r#while::While, tool::Tool, AbstractTree, Assignment, Error, Expression, IfElse, Match, Result,
|
||||||
VariableMap,
|
Value, VariableMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Abstract representation of a statement.
|
/// Abstract representation of a statement.
|
||||||
@ -17,6 +17,7 @@ pub enum Statement {
|
|||||||
IfElse(Box<IfElse>),
|
IfElse(Box<IfElse>),
|
||||||
Match(Match),
|
Match(Match),
|
||||||
Tool(Tool),
|
Tool(Tool),
|
||||||
|
While(Box<While>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Statement {
|
impl AbstractTree for Statement {
|
||||||
@ -38,6 +39,9 @@ impl AbstractTree for Statement {
|
|||||||
"tool" => Ok(Statement::IfElse(Box::new(IfElse::from_syntax_node(
|
"tool" => Ok(Statement::IfElse(Box::new(IfElse::from_syntax_node(
|
||||||
child, source,
|
child, source,
|
||||||
)?))),
|
)?))),
|
||||||
|
"while" => Ok(Statement::While(Box::new(While::from_syntax_node(
|
||||||
|
child, source,
|
||||||
|
)?))),
|
||||||
_ => Err(Error::UnexpectedSyntax {
|
_ => Err(Error::UnexpectedSyntax {
|
||||||
expected: "assignment, expression, if...else or tool",
|
expected: "assignment, expression, if...else or tool",
|
||||||
actual: child.kind(),
|
actual: child.kind(),
|
||||||
@ -54,6 +58,7 @@ impl AbstractTree for Statement {
|
|||||||
Statement::IfElse(if_else) => if_else.run(context),
|
Statement::IfElse(if_else) => if_else.run(context),
|
||||||
Statement::Match(r#match) => r#match.run(context),
|
Statement::Match(r#match) => r#match.run(context),
|
||||||
Statement::Tool(tool) => tool.run(context),
|
Statement::Tool(tool) => tool.run(context),
|
||||||
|
Statement::While(r#while) => r#while.run(context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
src/abstract_tree/while.rs
Normal file
47
src/abstract_tree/while.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{AbstractTree, Expression, Statement};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub struct While {
|
||||||
|
expression: Expression,
|
||||||
|
statement: Statement,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractTree for While {
|
||||||
|
fn from_syntax_node(node: tree_sitter::Node, source: &str) -> crate::Result<Self> {
|
||||||
|
debug_assert_eq!("while", node.kind());
|
||||||
|
|
||||||
|
let expression_node = node.child(1).unwrap();
|
||||||
|
let expression = Expression::from_syntax_node(expression_node, source)?;
|
||||||
|
|
||||||
|
let statement_node = node.child(3).unwrap();
|
||||||
|
let statement = Statement::from_syntax_node(statement_node, source)?;
|
||||||
|
|
||||||
|
Ok(While {
|
||||||
|
expression,
|
||||||
|
statement,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, context: &mut crate::VariableMap) -> crate::Result<crate::Value> {
|
||||||
|
while self.expression.run(context)?.as_boolean()? {
|
||||||
|
self.statement.run(context)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(crate::Value::Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::evaluate;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn evalualate_while_loop() {
|
||||||
|
assert_eq!(
|
||||||
|
evaluate("while false { 'foo' }"),
|
||||||
|
vec![Ok(crate::Value::Empty)]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit a3dbb19ecc40bc49487730c7679358389307559d
|
Subproject commit b55420d51b8431ab9d60f46bf5be753bcf55d953
|
Loading…
Reference in New Issue
Block a user