From fd9a4c04cbd4afa3d2509a8db5bd33ab6b3a20fb Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 7 Oct 2023 12:37:35 -0400 Subject: [PATCH] Implement function calls --- src/abstract_tree/function_call.rs | 4 ++-- src/abstract_tree/item.rs | 5 ++++- src/abstract_tree/while.rs | 15 ++++++--------- src/evaluator.rs | 4 ++-- src/value/function.rs | 20 ++++++++++---------- src/value/mod.rs | 14 ++++++++------ tree-sitter-dust | 2 +- 7 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index 27bd125..ab5eae1 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -55,8 +55,8 @@ impl AbstractTree for FunctionCall { let mut results = Vec::with_capacity(self.expressions.len()); - for statement in definition.statements() { - let result = statement.run(context)?; + for item in definition.items() { + let result = item.run(context)?; results.push(result); } diff --git a/src/abstract_tree/item.rs b/src/abstract_tree/item.rs index c80b2c0..70426a3 100644 --- a/src/abstract_tree/item.rs +++ b/src/abstract_tree/item.rs @@ -1,5 +1,6 @@ //! Top-level unit of Dust code. +use serde::{Deserialize, Serialize}; use tree_sitter::Node; use crate::{AbstractTree, Error, Result, Statement, Value, VariableMap}; @@ -9,7 +10,7 @@ use crate::{AbstractTree, Error, Result, Statement, Value, VariableMap}; /// Items are either comments, which do nothing, or statements, which can be run /// to produce a single value or interact with a context by creating or /// referencing variables. -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub enum Item { Comment(String), Statement(Statement), @@ -17,6 +18,8 @@ pub enum Item { impl AbstractTree for Item { fn from_syntax_node(node: Node, source: &str) -> Result { + debug_assert_eq!("item", node.kind()); + let child = node.child(0).unwrap(); if child.kind() == "comment" { diff --git a/src/abstract_tree/while.rs b/src/abstract_tree/while.rs index 8025ea8..96f5d7e 100644 --- a/src/abstract_tree/while.rs +++ b/src/abstract_tree/while.rs @@ -1,11 +1,11 @@ use serde::{Deserialize, Serialize}; -use crate::{AbstractTree, Expression, Statement}; +use crate::{AbstractTree, Expression, Item}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct While { expression: Expression, - statement: Statement, + item: Item, } impl AbstractTree for While { @@ -15,18 +15,15 @@ impl AbstractTree for While { 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)?; + let item_node = node.child(3).unwrap(); + let item = Item::from_syntax_node(item_node, source)?; - Ok(While { - expression, - statement, - }) + Ok(While { expression, item }) } fn run(&self, context: &mut crate::VariableMap) -> crate::Result { while self.expression.run(context)?.as_boolean()? { - self.statement.run(context)?; + self.item.run(context)?; } Ok(crate::Value::Empty) diff --git a/src/evaluator.rs b/src/evaluator.rs index fb79cf8..5fe27ab 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -272,8 +272,8 @@ mod tests { fn evaluate_function() { let function = Function::new( vec![Identifier::new("message".to_string())], - vec![Statement::Expression(Expression::Identifier( - Identifier::new("message".to_string()), + vec![Item::Statement(Statement::Expression( + Expression::Identifier(Identifier::new("message".to_string())), ))], ); diff --git a/src/value/function.rs b/src/value/function.rs index f1d7e56..7dbb297 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -2,28 +2,28 @@ use std::fmt::{self, Display, Formatter}; use serde::{Deserialize, Serialize}; -use crate::{Identifier, Statement}; +use crate::{Identifier, Item}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Function { - identifiers: Vec, - statements: Vec, + parameters: Vec, + body: Vec, } impl Function { - pub fn new(identifiers: Vec, statements: Vec) -> Self { + pub fn new(identifiers: Vec, items: Vec) -> Self { Function { - identifiers, - statements, + parameters: identifiers, + body: items, } } pub fn identifiers(&self) -> &Vec { - &self.identifiers + &self.parameters } - pub fn statements(&self) -> &Vec { - &self.statements + pub fn items(&self) -> &Vec { + &self.body } } @@ -32,7 +32,7 @@ impl Display for Function { write!( f, "function < {:?} > {{ {:?} }}", // TODO: Correct this output - self.identifiers, self.statements + self.parameters, self.body ) } } diff --git a/src/value/mod.rs b/src/value/mod.rs index ba56b36..422b320 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -1,7 +1,7 @@ //! Types that represent runtime values. use crate::{ error::{Error, Result}, - AbstractTree, Function, Identifier, Statement, Table, ValueType, VariableMap, + AbstractTree, Function, Identifier, Item, Table, ValueType, VariableMap, }; use json::JsonValue; @@ -157,25 +157,27 @@ impl Value { "function" => { let child_count = child.child_count(); let mut identifiers = Vec::new(); - let mut statements = Vec::new(); + let mut items = Vec::new(); for index in 0..child_count { let child = child.child(index).unwrap(); + println!("{child:?}"); + if child.kind() == "identifier" { let identifier = Identifier::from_syntax_node(child, source)?; identifiers.push(identifier) } - if child.kind() == "statement" { - let statement = Statement::from_syntax_node(child, source)?; + if child.kind() == "item" { + let item = Item::from_syntax_node(child, source)?; - statements.push(statement) + items.push(item) } } - Ok(Value::Function(Function::new(identifiers, statements))) + Ok(Value::Function(Function::new(identifiers, items))) } _ => Err(Error::UnexpectedSyntax { expected: "string, integer, float, boolean, list, table, map, function or empty", diff --git a/tree-sitter-dust b/tree-sitter-dust index b55420d..d7ff4e5 160000 --- a/tree-sitter-dust +++ b/tree-sitter-dust @@ -1 +1 @@ -Subproject commit b55420d51b8431ab9d60f46bf5be753bcf55d953 +Subproject commit d7ff4e57c58d9ff0708dc2902262384b99c4bc2c