Implement function value
This commit is contained in:
parent
d2d2ea1c57
commit
327a2d044b
@ -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();
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user