Implement function calls
This commit is contained in:
parent
e82dd6736e
commit
fd9a4c04cb
@ -55,8 +55,8 @@ impl AbstractTree for FunctionCall {
|
|||||||
|
|
||||||
let mut results = Vec::with_capacity(self.expressions.len());
|
let mut results = Vec::with_capacity(self.expressions.len());
|
||||||
|
|
||||||
for statement in definition.statements() {
|
for item in definition.items() {
|
||||||
let result = statement.run(context)?;
|
let result = item.run(context)?;
|
||||||
|
|
||||||
results.push(result);
|
results.push(result);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Top-level unit of Dust code.
|
//! Top-level unit of Dust code.
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Error, Result, Statement, Value, VariableMap};
|
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
|
/// 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
|
/// to produce a single value or interact with a context by creating or
|
||||||
/// referencing variables.
|
/// referencing variables.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Item {
|
pub enum Item {
|
||||||
Comment(String),
|
Comment(String),
|
||||||
Statement(Statement),
|
Statement(Statement),
|
||||||
@ -17,6 +18,8 @@ pub enum Item {
|
|||||||
|
|
||||||
impl AbstractTree for Item {
|
impl AbstractTree for Item {
|
||||||
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
|
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
|
||||||
|
debug_assert_eq!("item", node.kind());
|
||||||
|
|
||||||
let child = node.child(0).unwrap();
|
let child = node.child(0).unwrap();
|
||||||
|
|
||||||
if child.kind() == "comment" {
|
if child.kind() == "comment" {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{AbstractTree, Expression, Statement};
|
use crate::{AbstractTree, Expression, Item};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct While {
|
pub struct While {
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
statement: Statement,
|
item: Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for While {
|
impl AbstractTree for While {
|
||||||
@ -15,18 +15,15 @@ impl AbstractTree for While {
|
|||||||
let expression_node = node.child(1).unwrap();
|
let expression_node = node.child(1).unwrap();
|
||||||
let expression = Expression::from_syntax_node(expression_node, source)?;
|
let expression = Expression::from_syntax_node(expression_node, source)?;
|
||||||
|
|
||||||
let statement_node = node.child(3).unwrap();
|
let item_node = node.child(3).unwrap();
|
||||||
let statement = Statement::from_syntax_node(statement_node, source)?;
|
let item = Item::from_syntax_node(item_node, source)?;
|
||||||
|
|
||||||
Ok(While {
|
Ok(While { expression, item })
|
||||||
expression,
|
|
||||||
statement,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, context: &mut crate::VariableMap) -> crate::Result<crate::Value> {
|
fn run(&self, context: &mut crate::VariableMap) -> crate::Result<crate::Value> {
|
||||||
while self.expression.run(context)?.as_boolean()? {
|
while self.expression.run(context)?.as_boolean()? {
|
||||||
self.statement.run(context)?;
|
self.item.run(context)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(crate::Value::Empty)
|
Ok(crate::Value::Empty)
|
||||||
|
@ -272,8 +272,8 @@ mod tests {
|
|||||||
fn evaluate_function() {
|
fn evaluate_function() {
|
||||||
let function = Function::new(
|
let function = Function::new(
|
||||||
vec![Identifier::new("message".to_string())],
|
vec![Identifier::new("message".to_string())],
|
||||||
vec![Statement::Expression(Expression::Identifier(
|
vec![Item::Statement(Statement::Expression(
|
||||||
Identifier::new("message".to_string()),
|
Expression::Identifier(Identifier::new("message".to_string())),
|
||||||
))],
|
))],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,28 +2,28 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Identifier, Statement};
|
use crate::{Identifier, Item};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
identifiers: Vec<Identifier>,
|
parameters: Vec<Identifier>,
|
||||||
statements: Vec<Statement>,
|
body: Vec<Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn new(identifiers: Vec<Identifier>, statements: Vec<Statement>) -> Self {
|
pub fn new(identifiers: Vec<Identifier>, items: Vec<Item>) -> Self {
|
||||||
Function {
|
Function {
|
||||||
identifiers,
|
parameters: identifiers,
|
||||||
statements,
|
body: items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn identifiers(&self) -> &Vec<Identifier> {
|
pub fn identifiers(&self) -> &Vec<Identifier> {
|
||||||
&self.identifiers
|
&self.parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn statements(&self) -> &Vec<Statement> {
|
pub fn items(&self) -> &Vec<Item> {
|
||||||
&self.statements
|
&self.body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ impl Display for Function {
|
|||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"function < {:?} > {{ {:?} }}", // TODO: Correct this output
|
"function < {:?} > {{ {:?} }}", // TODO: Correct this output
|
||||||
self.identifiers, self.statements
|
self.parameters, self.body
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Types that represent runtime values.
|
//! Types that represent runtime values.
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
AbstractTree, Function, Identifier, Statement, Table, ValueType, VariableMap,
|
AbstractTree, Function, Identifier, Item, Table, ValueType, VariableMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
@ -157,25 +157,27 @@ impl Value {
|
|||||||
"function" => {
|
"function" => {
|
||||||
let child_count = child.child_count();
|
let child_count = child.child_count();
|
||||||
let mut identifiers = Vec::new();
|
let mut identifiers = Vec::new();
|
||||||
let mut statements = Vec::new();
|
let mut items = Vec::new();
|
||||||
|
|
||||||
for index in 0..child_count {
|
for index in 0..child_count {
|
||||||
let child = child.child(index).unwrap();
|
let child = child.child(index).unwrap();
|
||||||
|
|
||||||
|
println!("{child:?}");
|
||||||
|
|
||||||
if child.kind() == "identifier" {
|
if child.kind() == "identifier" {
|
||||||
let identifier = Identifier::from_syntax_node(child, source)?;
|
let identifier = Identifier::from_syntax_node(child, source)?;
|
||||||
|
|
||||||
identifiers.push(identifier)
|
identifiers.push(identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
if child.kind() == "statement" {
|
if child.kind() == "item" {
|
||||||
let statement = Statement::from_syntax_node(child, source)?;
|
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 {
|
_ => Err(Error::UnexpectedSyntax {
|
||||||
expected: "string, integer, float, boolean, list, table, map, function or empty",
|
expected: "string, integer, float, boolean, list, table, map, function or empty",
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit b55420d51b8431ab9d60f46bf5be753bcf55d953
|
Subproject commit d7ff4e57c58d9ff0708dc2902262384b99c4bc2c
|
Loading…
Reference in New Issue
Block a user