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 expression;
|
||||
pub mod function_call;
|
||||
@ -9,6 +17,7 @@ pub mod r#match;
|
||||
pub mod math;
|
||||
pub mod statement;
|
||||
pub mod tool;
|
||||
pub mod r#while;
|
||||
|
||||
pub use {
|
||||
assignment::*, expression::*, function_call::*, identifier::*, if_else::*, item::*, logic::*,
|
||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
tool::Tool, AbstractTree, Assignment, Error, Expression, IfElse, Match, Result, Value,
|
||||
VariableMap,
|
||||
r#while::While, tool::Tool, AbstractTree, Assignment, Error, Expression, IfElse, Match, Result,
|
||||
Value, VariableMap,
|
||||
};
|
||||
|
||||
/// Abstract representation of a statement.
|
||||
@ -17,6 +17,7 @@ pub enum Statement {
|
||||
IfElse(Box<IfElse>),
|
||||
Match(Match),
|
||||
Tool(Tool),
|
||||
While(Box<While>),
|
||||
}
|
||||
|
||||
impl AbstractTree for Statement {
|
||||
@ -38,6 +39,9 @@ impl AbstractTree for Statement {
|
||||
"tool" => Ok(Statement::IfElse(Box::new(IfElse::from_syntax_node(
|
||||
child, source,
|
||||
)?))),
|
||||
"while" => Ok(Statement::While(Box::new(While::from_syntax_node(
|
||||
child, source,
|
||||
)?))),
|
||||
_ => Err(Error::UnexpectedSyntax {
|
||||
expected: "assignment, expression, if...else or tool",
|
||||
actual: child.kind(),
|
||||
@ -54,6 +58,7 @@ impl AbstractTree for Statement {
|
||||
Statement::IfElse(if_else) => if_else.run(context),
|
||||
Statement::Match(r#match) => r#match.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