From c9c7eb31737fc3ce02bed5ce0069d8e04345f00b Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 29 Sep 2023 07:17:11 -0400 Subject: [PATCH] Improve AST construction and errors --- src/error.rs | 44 ++++++---------------------------------- src/interface.rs | 52 ++++++++++++++++++++++++++++++------------------ src/value/mod.rs | 2 +- 3 files changed, 40 insertions(+), 58 deletions(-) diff --git a/src/error.rs b/src/error.rs index 3aa4a24..81feaf4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,6 +2,7 @@ //! //! To deal with errors from dependencies, either create a new error variant //! or use the MacroFailure variant if the error can only occur inside a macro. + use crate::{value::value_type::ValueType, value::Value, ToolInfo}; use std::{fmt, io, time::SystemTimeError}; @@ -18,6 +19,10 @@ pub enum Error { ExpectedFieldName, + ExpectedChildNode { + empty_node_sexp: String, + }, + /// Dust's internal type checking failed to identify a type mismatch. This should never happen, /// the error prompts the user to report the bug. TypeCheckFailure { tool_info: ToolInfo<'static>, @@ -290,14 +295,6 @@ impl From for Error { } impl Error { - pub(crate) fn expect_operator_argument_amount(actual: usize, expected: usize) -> Result<()> { - if actual == expected { - Ok(()) - } else { - Err(Error::ExpectedOperatorArgumentAmount { expected, actual }) - } - } - pub(crate) fn expect_function_argument_amount( identifier: &str, actual: usize, @@ -389,36 +386,6 @@ impl Error { Error::ExpectedCollection { actual } } - pub(crate) fn addition_error(augend: Value, addend: Value) -> Self { - Error::AdditionError { augend, addend } - } - - pub(crate) fn subtraction_error(minuend: Value, subtrahend: Value) -> Self { - Error::SubtractionError { - minuend, - subtrahend, - } - } - - pub(crate) fn negation_error(argument: Value) -> Self { - Error::NegationError { argument } - } - - pub(crate) fn multiplication_error(multiplicand: Value, multiplier: Value) -> Self { - Error::MultiplicationError { - multiplicand, - multiplier, - } - } - - pub(crate) fn division_error(dividend: Value, divisor: Value) -> Self { - Error::DivisionError { dividend, divisor } - } - - pub(crate) fn modulation_error(dividend: Value, divisor: Value) -> Self { - Error::ModulationError { dividend, divisor } - } - /// Constructs `EvalexprError::InvalidRegex(regex)` pub fn invalid_regex(regex: String, message: String) -> Self { Error::InvalidRegex { regex, message } @@ -588,6 +555,7 @@ impl fmt::Display for Error { UnexpectedSourceNode { expected, actual } => write!(f, "Unexpected source node. Expected {expected}, but found {actual}."), ExpectedFieldName => write!(f, "Expected a field name for this node, but none was found."), WrongTypeCombination { expected, actual } => write!(f, "Wrong type combination. Expected {expected}, found {actual}."), + ExpectedChildNode { empty_node_sexp } => write!(f, "Expected this node to have a child, {empty_node_sexp}."), } } } diff --git a/src/interface.rs b/src/interface.rs index cb9800e..4ff87c4 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,5 +1,6 @@ //! The top level of Dust's API with functions to interpret Dust code. +use egui::util::id_type_map; use tree_sitter::{Node, Parser, Tree, TreeCursor}; use crate::{language, Error, Result, Value, VariableMap}; @@ -33,11 +34,11 @@ pub fn eval(source: &str) -> Vec> { /// context.set_value("two".into(), 2.into()).unwrap(); // Do proper error handling here /// context.set_value("three".into(), 3.into()).unwrap(); // Do proper error handling here /// -/// let dust_code = "one + two + three; one - two - three;"; +/// let dust_code = "four = 4; one + two + three + four;"; /// /// assert_eq!( /// eval_with_context(dust_code, &mut context), -/// vec![Ok(Value::from(6)), Ok(Value::from(-4))] +/// vec![Ok(Value::Empty), Ok(Value::from(10))] /// ); /// ``` pub fn eval_with_context(source: &str, context: &mut VariableMap) -> Vec> { @@ -74,10 +75,18 @@ struct Evaluator { impl Evaluator { fn new(tree: Tree, source: &str) -> Result { let root_node = tree.root_node(); + let mut cursor = tree.walk(); let mut items = Vec::new(); - let item = Item::new(root_node, source)?; - items.push(item); + for (index, node) in root_node.children(&mut cursor).enumerate() { + let item = Item::new(node, source)?; + + items.push(item); + + if index == root_node.child_count() - 1 { + break; + } + } Ok(Evaluator { items }) } @@ -150,9 +159,14 @@ enum Statement { impl Statement { fn new(node: Node, source: &str) -> Result { + let node = if node.kind() == "statement" { + node.child(0).unwrap() + } else { + node + }; let child = node.child(0).unwrap(); - match child.kind() { + match node.kind() { "closed_statement" => Ok(Statement::Closed(Expression::new(child, source)?)), "open_statement" => Ok(Self::Open(Expression::new(child, source)?)), _ => Err(Error::UnexpectedSourceNode { @@ -189,31 +203,31 @@ enum Expression { impl Expression { fn new(node: Node, source: &str) -> Result { - let mut child = node.child(0).unwrap(); + let node = if node.kind() == "expression" { + node.child(0).unwrap() + } else { + node + }; - if child.kind() == "expression" { - child = child.child(0).unwrap(); - } - - if child.kind() == "identifier" { - let byte_range = child.byte_range(); + if node.kind() == "identifier" { + let byte_range = node.byte_range(); let identifier = &source[byte_range]; Ok(Self::Identifier(identifier.to_string())) - } else if child.kind() == "value" { - Ok(Expression::Value(Value::new(child, source)?)) - } else if child.kind() == "operation" { + } else if node.kind() == "value" { + Ok(Expression::Value(Value::new(node, source)?)) + } else if node.kind() == "operation" { Ok(Expression::Operation(Box::new(Operation::new( - child, source, + node, source, )?))) - } else if child.kind() == "control_flow" { + } else if node.kind() == "control_flow" { Ok(Expression::ControlFlow(Box::new(ControlFlow::new( - child, source, + node, source, )?))) } else { Err(Error::UnexpectedSourceNode { expected: "identifier, operation, control_flow or value", - actual: child.kind(), + actual: node.kind(), }) } } diff --git a/src/value/mod.rs b/src/value/mod.rs index e56bc49..89178fb 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -314,7 +314,7 @@ impl Sub for Value { Ok(Value::Float(addition)) } - (Value::Float(_), other) | (other, Value::Float(_)) => Err(Error::ExpectedFloat { + (Value::Float(_), other) | (other, Value::Float(_)) => Err(Error::ExpectedNumber { actual: other.clone(), }), (Value::Integer(left), Value::Integer(right)) => Ok(Value::Integer(left - right)),