From 32dec2a0da2b55428526aac679b0ad1254b507b7 Mon Sep 17 00:00:00 2001 From: MuhamedMagdi Date: Sat, 10 Aug 2024 13:32:21 +0300 Subject: [PATCH 1/2] feat: restrict value type for builtin functions to be of type `Text` --- src/modules/builtin/cd.rs | 9 +++++++++ src/modules/builtin/mv.rs | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/modules/builtin/cd.rs b/src/modules/builtin/cd.rs index bd56596a..6e5f2236 100644 --- a/src/modules/builtin/cd.rs +++ b/src/modules/builtin/cd.rs @@ -1,6 +1,7 @@ use heraclitus_compiler::prelude::*; use crate::modules::expression::expr::Expr; use crate::docs::module::DocumentationModule; +use crate::modules::types::{Type, Typed}; use crate::translate::module::TranslateModule; use crate::utils::{ParserMetadata, TranslateMetadata}; @@ -20,7 +21,15 @@ impl SyntaxModule for Cd { fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult { token(meta, "cd")?; + let tok = meta.get_current_token(); syntax(meta, &mut self.value)?; + let path_type = self.value.get_type(); + if path_type != Type::Text { + return error!(meta, tok => { + message: "Builtin function `cd` can only be used with values of type Text", + comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) + }); + } Ok(()) } } diff --git a/src/modules/builtin/mv.rs b/src/modules/builtin/mv.rs index 5901dcdb..59a4a6e8 100644 --- a/src/modules/builtin/mv.rs +++ b/src/modules/builtin/mv.rs @@ -5,6 +5,7 @@ use crate::modules::expression::expr::Expr; use crate::modules::condition::failed::Failed; use crate::translate::module::TranslateModule; use crate::docs::module::DocumentationModule; +use crate::modules::types::{Type, Typed}; use crate::utils::{ParserMetadata, TranslateMetadata}; use crate::modules::command::modifier::CommandModifier; @@ -32,8 +33,24 @@ impl SyntaxModule for Mv { syntax(meta, &mut self.modifier)?; self.modifier.use_modifiers(meta, |_this, meta| { token(meta, "mv")?; + let mut tok = meta.get_current_token(); syntax(meta, &mut self.source)?; + let mut path_type = self.source.get_type(); + if path_type != Type::Text { + return error!(meta, tok => { + message: "Builtin function `mv` can only be used with values of type Text", + comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) + }); + } + tok = meta.get_current_token(); syntax(meta, &mut self.destination)?; + path_type = self.destination.get_type(); + if path_type != Type::Text { + return error!(meta, tok => { + message: "Builtin function `mv` can only be used with values of type Text", + comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) + }); + } syntax(meta, &mut self.failed)?; Ok(()) }) From 33a401a5fd80fdb84536f46f6ba15ddcbb883bde Mon Sep 17 00:00:00 2001 From: MuhamedMagdi Date: Sat, 10 Aug 2024 23:07:09 +0300 Subject: [PATCH 2/2] refactor: use the new `Expr` position api --- src/modules/builtin/cd.rs | 4 ++-- src/modules/builtin/mv.rs | 8 ++++---- src/modules/expression/expr.rs | 8 ++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/modules/builtin/cd.rs b/src/modules/builtin/cd.rs index 6e5f2236..d4a6ea4d 100644 --- a/src/modules/builtin/cd.rs +++ b/src/modules/builtin/cd.rs @@ -21,11 +21,11 @@ impl SyntaxModule for Cd { fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult { token(meta, "cd")?; - let tok = meta.get_current_token(); syntax(meta, &mut self.value)?; let path_type = self.value.get_type(); if path_type != Type::Text { - return error!(meta, tok => { + let position = self.value.get_position(meta); + return error_pos!(meta, position => { message: "Builtin function `cd` can only be used with values of type Text", comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) }); diff --git a/src/modules/builtin/mv.rs b/src/modules/builtin/mv.rs index 59a4a6e8..35cec231 100644 --- a/src/modules/builtin/mv.rs +++ b/src/modules/builtin/mv.rs @@ -33,20 +33,20 @@ impl SyntaxModule for Mv { syntax(meta, &mut self.modifier)?; self.modifier.use_modifiers(meta, |_this, meta| { token(meta, "mv")?; - let mut tok = meta.get_current_token(); syntax(meta, &mut self.source)?; let mut path_type = self.source.get_type(); if path_type != Type::Text { - return error!(meta, tok => { + let position = self.source.get_position(meta); + return error_pos!(meta, position => { message: "Builtin function `mv` can only be used with values of type Text", comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) }); } - tok = meta.get_current_token(); syntax(meta, &mut self.destination)?; path_type = self.destination.get_type(); if path_type != Type::Text { - return error!(meta, tok => { + let position = self.destination.get_position(meta); + return error_pos!(meta, position => { message: "Builtin function `mv` can only be used with values of type Text", comment: format!("Given type: {}, expected type: {}", path_type, Type::Text) }); diff --git a/src/modules/expression/expr.rs b/src/modules/expression/expr.rs index 778004ab..d522b393 100644 --- a/src/modules/expression/expr.rs +++ b/src/modules/expression/expr.rs @@ -97,10 +97,14 @@ impl Typed for Expr { } impl Expr { - pub fn get_error_message(&self, meta: &mut ParserMetadata) -> Message { + pub fn get_position(&self, meta: &mut ParserMetadata) -> PositionInfo { let begin = meta.get_token_at(self.pos.0); let end = meta.get_token_at(self.pos.1); - let pos = PositionInfo::from_between_tokens(meta, begin, end); + PositionInfo::from_between_tokens(meta, begin, end) + } + + pub fn get_error_message(&self, meta: &mut ParserMetadata) -> Message { + let pos = self.get_position(meta); Message::new_err_at_position(meta, pos) }