1
0

Implement for loops

This commit is contained in:
Jeff 2023-10-17 14:06:02 -04:00
parent deb03ed1b6
commit 173e7a2ee8
6 changed files with 67 additions and 7 deletions

3
examples/for_loop.ds Normal file
View File

@ -0,0 +1,3 @@
for i in [1 2 3] {
(output i)
}

6
examples/while_loop.ds Normal file
View File

@ -0,0 +1,6 @@
i = 0
while i < 10 {
(output i)
i += 1
}

45
src/abstract_tree/for.rs Normal file
View File

@ -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<Self> {
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<crate::Value> {
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)
}
}

View File

@ -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;

View File

@ -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<IfElse>),
Match(Match),
While(Box<While>),
Run(Box<Async>),
Async(Box<Async>),
For(Box<For>),
}
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),
}
}
}

@ -1 +1 @@
Subproject commit 9ec43a98418f395a668c59a79b0832e563d9f0e4
Subproject commit 9fb89fcd8b29386735de0bad42232ef3d72e7e91