diff --git a/examples/for_loop.ds b/examples/for_loop.ds new file mode 100644 index 0000000..67d368e --- /dev/null +++ b/examples/for_loop.ds @@ -0,0 +1,3 @@ +for i in [1 2 3] { + (output i) +} diff --git a/examples/while_loop.ds b/examples/while_loop.ds new file mode 100644 index 0000000..c2b07bf --- /dev/null +++ b/examples/while_loop.ds @@ -0,0 +1,6 @@ +i = 0 + +while i < 10 { + (output i) + i += 1 +} diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs new file mode 100644 index 0000000..3d51798 --- /dev/null +++ b/src/abstract_tree/for.rs @@ -0,0 +1,45 @@ +use serde::{Deserialize, Serialize}; + +use crate::{AbstractTree, Expression, Identifier, Item, Value}; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub struct For { + identifier: Identifier, + expression: Expression, + item: Item, +} + +impl AbstractTree for For { + fn from_syntax_node(source: &str, node: tree_sitter::Node) -> crate::Result { + let identifier_node = node.child(1).unwrap(); + let identifier = Identifier::from_syntax_node(source, identifier_node)?; + + let expression_node = node.child(3).unwrap(); + let expression = Expression::from_syntax_node(source, expression_node)?; + + let item_node = node.child(5).unwrap(); + let item = Item::from_syntax_node(source, item_node)?; + + Ok(For { + identifier, + expression, + item, + }) + } + + fn run(&self, source: &str, context: &mut crate::VariableMap) -> crate::Result { + let value = self.expression.run(source, context)?; + let list = value.as_list()?; + let key = self.identifier.inner(); + + for value in list { + context.set_value(key.clone(), value.clone())?; + + self.item.run(source, context)?; + } + + context.set_value(key.clone(), Value::Empty)?; + + Ok(Value::Empty) + } +} diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index ae69e53..2c6a493 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -9,6 +9,7 @@ pub mod assignment; pub mod r#async; pub mod expression; +pub mod r#for; pub mod function_call; pub mod identifier; pub mod if_else; @@ -23,7 +24,7 @@ pub mod r#while; pub use { assignment::*, expression::*, function_call::*, identifier::*, if_else::*, item::*, logic::*, - math::*, r#match::*, statement::*, + math::*, r#async::*, r#for::*, r#match::*, r#while::*, statement::*, }; use tree_sitter::Node; diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 625bdc1..53068e6 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; use crate::{ - r#async::Async, r#while::While, AbstractTree, Assignment, Error, Expression, IfElse, Match, - Result, Value, VariableMap, + AbstractTree, Assignment, Async, Error, Expression, For, IfElse, Match, Result, Value, + VariableMap, While, }; /// Abstract representation of a statement. @@ -17,7 +17,8 @@ pub enum Statement { IfElse(Box), Match(Match), While(Box), - Run(Box), + Async(Box), + For(Box), } impl AbstractTree for Statement { @@ -42,7 +43,10 @@ impl AbstractTree for Statement { "while" => Ok(Statement::While(Box::new(While::from_syntax_node( source, child, )?))), - "async" => Ok(Statement::Run(Box::new(Async::from_syntax_node( + "async" => Ok(Statement::Async(Box::new(Async::from_syntax_node( + source, child, + )?))), + "for" => Ok(Statement::For(Box::new(For::from_syntax_node( source, child, )?))), _ => Err(Error::UnexpectedSyntaxNode { @@ -61,7 +65,8 @@ impl AbstractTree for Statement { Statement::IfElse(if_else) => if_else.run(source, context), Statement::Match(r#match) => r#match.run(source, context), Statement::While(r#while) => r#while.run(source, context), - Statement::Run(run) => run.run(source, context), + Statement::Async(run) => run.run(source, context), + Statement::For(r#for) => r#for.run(source, context), } } } diff --git a/tree-sitter-dust b/tree-sitter-dust index 9ec43a9..9fb89fc 160000 --- a/tree-sitter-dust +++ b/tree-sitter-dust @@ -1 +1 @@ -Subproject commit 9ec43a98418f395a668c59a79b0832e563d9f0e4 +Subproject commit 9fb89fcd8b29386735de0bad42232ef3d72e7e91