Skip to content

Commit

Permalink
address Dongbo's feedback keeping the structs separate
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveL-MSFT committed Oct 26, 2023
1 parent 7521e10 commit 35175d2
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 20 deletions.
12 changes: 6 additions & 6 deletions dsc_lib/src/parser/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<String>>,
}

impl<'a> Expression<'a> {
impl Expression {
/// Create a new `Expression` instance.
///
/// # Arguments
Expand All @@ -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<Self, DscError> {
pub fn new(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], expression: &Node) -> Result<Self, DscError> {
let Some(function) = expression.child_by_field_name("function") else {
return Err(DscError::Parser("Function node not found".to_string()));
};
Expand Down Expand Up @@ -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<String, DscError> {
let result = self.function.invoke()?;
pub fn invoke(&self, function_dispatcher: &FunctionDispatcher) -> Result<String, DscError> {
let result = self.function.invoke(function_dispatcher)?;
if let Some(member_access) = &self.member_access {
match result {
FunctionResult::String(_) => {
Expand Down
22 changes: 10 additions & 12 deletions dsc_lib/src/parser/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ use crate::parser::{
};

#[derive(Clone)]
pub struct Function<'a> {
pub struct Function {
name: String,
args: Option<Vec<FunctionArg<'a>>>,
function_dispatcher: &'a FunctionDispatcher,
args: Option<Vec<FunctionArg>>,
}

#[derive(Clone)]
pub enum FunctionArg<'a> {
pub enum FunctionArg {
String(String),
Integer(i32),
Boolean(bool),
Expression(Expression<'a>),
Expression(Expression),
}

#[derive(Debug, PartialEq)]
Expand All @@ -31,7 +30,7 @@ pub enum FunctionResult {
Object(Value),
}

impl<'a> Function<'a> {
impl Function {
/// Create a new `Function` instance.
///
/// # Arguments
Expand All @@ -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<Self, DscError> {
pub fn new(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], function: &Node) -> Result<Self, DscError> {
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})
}
Expand All @@ -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<FunctionResult, DscError> {
pub fn invoke(&self, function_dispatcher: &FunctionDispatcher) -> Result<FunctionResult, DscError> {
// if any args are expressions, we need to invoke those first
let mut resolved_args: Vec<FunctionArg> = 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));
},
_ => {
Expand All @@ -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<Node>) -> Result<Option<Vec<FunctionArg<'a>>>, DscError> {
fn convert_args_node(function_dispatcher: &FunctionDispatcher, statement_bytes: &[u8], args: &Option<Node>) -> Result<Option<Vec<FunctionArg>>, DscError> {
let Some(args) = args else {
return Ok(None);
};
Expand Down
2 changes: 1 addition & 1 deletion dsc_lib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())))
Expand Down
3 changes: 2 additions & 1 deletion tree-sitter-dscexpression/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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+/,
Expand Down

0 comments on commit 35175d2

Please sign in to comment.