From 35175d2ac0bbe3c3988243bb6b44440427a1d5f3 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 25 Oct 2023 17:13:15 -0700 Subject: [PATCH] address Dongbo's feedback keeping the structs separate --- dsc_lib/src/parser/expressions.rs | 12 ++++++------ dsc_lib/src/parser/functions.rs | 22 ++++++++++------------ dsc_lib/src/parser/mod.rs | 2 +- tree-sitter-dscexpression/grammar.js | 3 ++- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dsc_lib/src/parser/expressions.rs b/dsc_lib/src/parser/expressions.rs index cefaa229..49e6d6cd 100644 --- a/dsc_lib/src/parser/expressions.rs +++ b/dsc_lib/src/parser/expressions.rs @@ -8,12 +8,12 @@ use crate::functions::FunctionDispatcher; use crate::parser::functions::{Function, FunctionResult}; #[derive(Clone)] -pub struct Expression<'a> { - function: Function<'a>, +pub struct Expression { + function: Function, member_access: Option>, } -impl<'a> Expression<'a> { +impl Expression { /// Create a new `Expression` instance. /// /// # Arguments @@ -25,7 +25,7 @@ impl<'a> Expression<'a> { /// # Errors /// /// This function will return an error if the expression node is not valid. - pub fn new(function_dispatcher: &'a FunctionDispatcher, statement_bytes: &[u8], expression: &Node) -> Result { + pub fn new(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], expression: &Node) -> Result { let Some(function) = expression.child_by_field_name("function") else { return Err(DscError::Parser("Function node not found".to_string())); }; @@ -59,8 +59,8 @@ impl<'a> Expression<'a> { /// # Errors /// /// This function will return an error if the expression fails to execute. - pub fn invoke(&self) -> Result { - let result = self.function.invoke()?; + pub fn invoke(&self, function_dispatcher: &FunctionDispatcher) -> Result { + let result = self.function.invoke(function_dispatcher)?; if let Some(member_access) = &self.member_access { match result { FunctionResult::String(_) => { diff --git a/dsc_lib/src/parser/functions.rs b/dsc_lib/src/parser/functions.rs index 25c63c4d..560a3a13 100644 --- a/dsc_lib/src/parser/functions.rs +++ b/dsc_lib/src/parser/functions.rs @@ -11,18 +11,17 @@ use crate::parser::{ }; #[derive(Clone)] -pub struct Function<'a> { +pub struct Function { name: String, - args: Option>>, - function_dispatcher: &'a FunctionDispatcher, + args: Option>, } #[derive(Clone)] -pub enum FunctionArg<'a> { +pub enum FunctionArg { String(String), Integer(i32), Boolean(bool), - Expression(Expression<'a>), + Expression(Expression), } #[derive(Debug, PartialEq)] @@ -31,7 +30,7 @@ pub enum FunctionResult { Object(Value), } -impl<'a> Function<'a> { +impl Function { /// Create a new `Function` instance. /// /// # Arguments @@ -43,14 +42,13 @@ impl<'a> Function<'a> { /// # Errors /// /// This function will return an error if the function node is not valid. - pub fn new(function_dispatcher: &'a FunctionDispatcher, statement_bytes: &[u8], function: &Node) -> Result { + pub fn new(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], function: &Node) -> Result { let Some(function_name) = function.child_by_field_name("name") else { return Err(DscError::Parser("Function name node not found".to_string())); }; let function_args = function.child_by_field_name("args"); let args = convert_args_node(function_dispatcher, statement_bytes, &function_args)?; Ok(Function{ - function_dispatcher, name: function_name.utf8_text(statement_bytes)?.to_string(), args}) } @@ -60,14 +58,14 @@ impl<'a> Function<'a> { /// # Errors /// /// This function will return an error if the function fails to execute. - pub fn invoke(&self) -> Result { + pub fn invoke(&self, function_dispatcher: &FunctionDispatcher) -> Result { // if any args are expressions, we need to invoke those first let mut resolved_args: Vec = vec![]; if let Some(args) = &self.args { for arg in args { match arg { FunctionArg::Expression(expression) => { - let value = expression.invoke()?; + let value = expression.invoke(function_dispatcher)?; resolved_args.push(FunctionArg::String(value)); }, _ => { @@ -77,11 +75,11 @@ impl<'a> Function<'a> { } } - self.function_dispatcher.invoke(&self.name, &resolved_args) + function_dispatcher.invoke(&self.name, &resolved_args) } } -fn convert_args_node<'a>(function_dispatcher: &'a FunctionDispatcher, statement_bytes: &[u8], args: &Option) -> Result>>, DscError> { +fn convert_args_node(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], args: &Option) -> Result>, DscError> { let Some(args) = args else { return Ok(None); }; diff --git a/dsc_lib/src/parser/mod.rs b/dsc_lib/src/parser/mod.rs index 79faa03f..ae8b1ef9 100644 --- a/dsc_lib/src/parser/mod.rs +++ b/dsc_lib/src/parser/mod.rs @@ -76,7 +76,7 @@ impl Statement { }, "expression" => { let expression = Expression::new(&self.function_dispatcher, statement_bytes, &child_node)?; - Ok(expression.invoke()?) + Ok(expression.invoke(&self.function_dispatcher)?) }, _ => { Err(DscError::Parser(format!("Unknown expression type {0}", child_node.kind()))) diff --git a/tree-sitter-dscexpression/grammar.js b/tree-sitter-dscexpression/grammar.js index 9fd4bf7b..b32d1fc9 100644 --- a/tree-sitter-dscexpression/grammar.js +++ b/tree-sitter-dscexpression/grammar.js @@ -24,8 +24,9 @@ module.exports = grammar({ function: $ => seq(field('name', $.functionName), '(', field('args', optional($.arguments)), ')'), functionName: $ => /[a-z][a-zA-Z0-9]*/, arguments: $ => seq($._argument, repeat(seq(',', $._argument))), - _argument: $ => choice($.expression, seq('\'', $.string, '\''), $.number, $.boolean), + _argument: $ => choice($.expression, $._quotedString, $.number, $.boolean), + _quotedString: $ => seq('\'', $.string, '\''), // ARM strings do not allow to contain single-quote characters string: $ => /[^']*/, number: $ => /-?\d+/,