1
0

Implement function value

This commit is contained in:
Jeff 2023-09-30 17:52:37 -04:00
parent d2d2ea1c57
commit 327a2d044b
3 changed files with 52 additions and 28 deletions

View File

@ -1,5 +1,6 @@
//! The top level of Dust's API with functions to interpret Dust code. //! The top level of Dust's API with functions to interpret Dust code.
use serde::{Deserialize, Serialize};
use tree_sitter::{Node, Parser, Tree as TSTree, TreeCursor}; use tree_sitter::{Node, Parser, Tree as TSTree, TreeCursor};
use crate::{language, Error, Result, Value, VariableMap}; use crate::{language, Error, Result, Value, VariableMap};
@ -170,7 +171,7 @@ impl Item {
/// 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 Statement { pub enum Statement {
Open(Expression), Open(Expression),
} }
@ -205,7 +206,7 @@ impl Statement {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum Expression { pub enum Expression {
Identifier(String), Identifier(String),
Value(Value), Value(Value),
@ -267,7 +268,7 @@ impl Expression {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Operation { pub struct Operation {
left: Expression, left: Expression,
operator: String, operator: String,
@ -298,7 +299,8 @@ impl Operation {
) -> Result<Value> { ) -> Result<Value> {
let left = self.left.run(context, &mut cursor, source)?; let left = self.left.run(context, &mut cursor, source)?;
let right = self.right.run(context, &mut cursor, source)?; let right = self.right.run(context, &mut cursor, source)?;
let result = match self.operator.as_str() {
match self.operator.as_str() {
"+" => left + right, "+" => left + right,
"-" => left - right, "-" => left - right,
"=" => { "=" => {
@ -309,10 +311,8 @@ impl Operation {
Ok(Value::Empty) Ok(Value::Empty)
} }
"==" => Ok(Value::Boolean(left == right)), "==" => Ok(Value::Boolean(left == right)),
_ => return Err(Error::CustomMessage("Operator not supported.".to_string())), _ => Err(Error::CustomMessage("Operator not supported.".to_string())),
}; }
Ok(result?)
} }
} }
@ -320,7 +320,7 @@ impl Operation {
/// ///
/// A ControlFlow instance represents work to be done when the "run" method is /// A ControlFlow instance represents work to be done when the "run" method is
/// called. /// called.
#[derive(Debug)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct ControlFlow { pub struct ControlFlow {
if_expression: Expression, if_expression: Expression,
then_statement: Statement, then_statement: Statement,
@ -369,7 +369,7 @@ impl ControlFlow {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{Function, Table}; use crate::Table;
use super::*; use super::*;
@ -416,17 +416,6 @@ mod tests {
); );
} }
#[test]
fn evaluate_function() {
let function_str = "function <message, number> {
output message
output number
}";
todo!();
// assert_eq!("", vec![Ok(Value::Function(Function::new(function_str)))]);
}
#[test] #[test]
fn evaluate_map() { fn evaluate_map() {
let mut map = VariableMap::new(); let mut map = VariableMap::new();

View File

@ -2,14 +2,20 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{eval, eval_with_context, Result, Value, VariableMap}; use crate::{Result, Statement, Value, VariableMap};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Function(String); pub struct Function {
identifiers: Vec<String>,
statements: Vec<Statement>,
}
impl Function { impl Function {
pub fn new(body: &str) -> Self { pub fn new(identifiers: Vec<String>, statements: Vec<Statement>) -> Self {
Function(body.to_string()) Function {
identifiers,
statements,
}
} }
pub fn run(&self) -> Result<Value> { pub fn run(&self) -> Result<Value> {
@ -23,6 +29,10 @@ impl Function {
impl Display for Function { impl Display for Function {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0) write!(
f,
"function < {:?} > {{ {:?} }}",
self.identifiers, self.statements
)
} }
} }

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values. //! Types that represent runtime values.
use crate::{ use crate::{
error::{Error, Result}, error::{Error, Result},
Expression, Function, Table, Time, ValueType, VariableMap, Expression, Function, Statement, Table, Time, ValueType, VariableMap,
}; };
use json::JsonValue; use json::JsonValue;
@ -134,6 +134,31 @@ impl Value {
Ok(Value::Table(table)) Ok(Value::Table(table))
} }
"map" => todo!(), "map" => todo!(),
"function" => {
let child_count = node.child_count();
let mut identifiers = Vec::new();
let mut statements = Vec::new();
for index in 0..child_count {
let child = node.child(index).unwrap();
if child.kind() == "identifier" {
let child_identifier = Expression::new(child, source)?;
if let Expression::Identifier(identifier) = child_identifier {
identifiers.push(identifier)
}
}
if child.kind() == "statement" {
let statement = Statement::new(child, source)?;
statements.push(statement)
}
}
Ok(Value::Function(Function::new(identifiers, statements)))
}
"empty" => Ok(Value::Empty), "empty" => Ok(Value::Empty),
_ => Err(Error::UnexpectedSourceNode { _ => Err(Error::UnexpectedSourceNode {
expected: "integer, string, boolean, float, list or empty", expected: "integer, string, boolean, float, list or empty",