Begin implementing while loops

This commit is contained in:
Jeff 2023-10-06 22:45:36 -04:00
parent 12418a3bba
commit e82dd6736e
4 changed files with 64 additions and 3 deletions

View File

@ -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::*,

View File

@ -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),
}
}
}

View 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