Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 26 additions & 25 deletions src/modules/builtin/mv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::mem::swap;


use crate::fragments;
use crate::modules::command::modifier::CommandModifier;
Expand Down Expand Up @@ -42,29 +42,31 @@ impl SyntaxModule<ParserMetadata> for Mv {

impl TypeCheckModule for Mv {
fn typecheck(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
self.source.typecheck(meta)?;
self.destination.typecheck(meta)?;
self.failure_handler.typecheck(meta)?;
self.modifier.use_modifiers(meta, |_, meta| {
self.source.typecheck(meta)?;
self.destination.typecheck(meta)?;
self.failure_handler.typecheck(meta)?;

let source_type = self.source.get_type();
if source_type != Type::Text {
let position = self.source.get_position();
return error_pos!(meta, position => {
message: "Builtin function `mv` can only be used with values of type Text",
comment: format!("Given type: {}, expected type: {}", source_type, Type::Text)
});
}
let source_type = self.source.get_type();
if source_type != Type::Text {
let position = self.source.get_position();
return error_pos!(meta, position => {
message: "Builtin function `mv` can only be used with values of type Text",
comment: format!("Given type: {}, expected type: {}", source_type, Type::Text)
});
}

let dest_type = self.destination.get_type();
if dest_type != Type::Text {
let position = self.destination.get_position();
return error_pos!(meta, position => {
message: "Builtin function `mv` can only be used with values of type Text",
comment: format!("Given type: {}, expected type: {}", dest_type, Type::Text)
});
}
let dest_type = self.destination.get_type();
if dest_type != Type::Text {
let position = self.destination.get_position();
return error_pos!(meta, position => {
message: "Builtin function `mv` can only be used with values of type Text",
comment: format!("Given type: {}, expected type: {}", dest_type, Type::Text)
});
}

Ok(())
Ok(())
})
}
}

Expand All @@ -73,10 +75,9 @@ impl TranslateModule for Mv {
let source = self.source.translate(meta);
let destination = self.destination.translate(meta);
let handler = self.failure_handler.translate(meta);
let mut is_silent = self.modifier.is_silent || meta.silenced;
swap(&mut is_silent, &mut meta.silenced);
let silent = meta.gen_silent().to_frag();
swap(&mut is_silent, &mut meta.silenced);
let silent = meta.with_silenced(self.modifier.is_silent || meta.silenced, |meta| {
meta.gen_silent().to_frag()
});
BlockFragment::new(vec![
fragments!("mv ", source, " ", destination, silent),
handler,
Expand Down
86 changes: 44 additions & 42 deletions src/modules/command/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,58 +60,60 @@ impl SyntaxModule<ParserMetadata> for Command {

impl TypeCheckModule for Command {
fn typecheck(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
for interp in self.interps.iter_mut() {
interp.typecheck(meta)?;
}
self.failure_handler.typecheck(meta)
self.modifier.use_modifiers(meta, |_, meta| {
for interp in self.interps.iter_mut() {
interp.typecheck(meta)?;
}
self.failure_handler.typecheck(meta)
})
}
}

impl TranslateModule for Command {
fn translate(&self, meta: &mut TranslateMetadata) -> FragmentKind {
let translation = {
meta.with_silenced(self.modifier.is_silent || meta.silenced, |meta| {
meta.with_sudoed(self.modifier.is_sudo || meta.sudoed, |meta| {
let interps = self.interps.iter()
.map(|item| item.translate(meta).with_quotes(false))
.collect::<Vec<FragmentKind>>();
let translation = {
meta.with_silenced(self.modifier.is_silent || meta.silenced, |meta| {
meta.with_sudoed(self.modifier.is_sudo || meta.sudoed, |meta| {
let interps = self.interps.iter()
.map(|item| item.translate(meta).with_quotes(false))
.collect::<Vec<FragmentKind>>();

let translation = InterpolableFragment::new(
self.strings.clone(),
interps,
InterpolableRenderType::GlobalContext
).to_frag();
let translation = InterpolableFragment::new(
self.strings.clone(),
interps,
InterpolableRenderType::GlobalContext
).to_frag();

let silent = meta.gen_silent().to_frag();
let sudo_prefix = meta.gen_sudo_prefix().to_frag();
ListFragment::new(vec![sudo_prefix, translation, silent])
.with_spaces()
.to_frag()
})
let silent = meta.gen_silent().to_frag();
let sudo_prefix = meta.gen_sudo_prefix().to_frag();
ListFragment::new(vec![sudo_prefix, translation, silent])
.with_spaces()
.to_frag()
})
};
})
};

let handler = self.failure_handler.translate(meta);
let is_statement = !meta.expr_ctx;
let has_failure_handler = self.failure_handler.is_parsed;
let handler = self.failure_handler.translate(meta);
let is_statement = !meta.expr_ctx;
let has_failure_handler = self.failure_handler.is_parsed;

match (is_statement, has_failure_handler) {
(true, true) => {
meta.stmt_queue.push_back(translation);
handler
}
(true, false) => translation,
(false, false) => SubprocessFragment::new(translation).to_frag(),
(false, true) => {
let id = meta.gen_value_id();
let value = SubprocessFragment::new(translation).to_frag();
let var_stmt = VarStmtFragment::new("command", Type::Text, value).with_global_id(id);
let var_expr = meta.push_ephemeral_variable(var_stmt);
meta.stmt_queue.push_back(handler);
var_expr.to_frag()
}
}
}
match (is_statement, has_failure_handler) {
(true, true) => {
meta.stmt_queue.push_back(translation);
handler
}
(true, false) => translation,
(false, false) => SubprocessFragment::new(translation).to_frag(),
(false, true) => {
let id = meta.gen_value_id();
let value = SubprocessFragment::new(translation).to_frag();
let var_stmt = VarStmtFragment::new("command", Type::Text, value).with_global_id(id);
let var_expr = meta.push_ephemeral_variable(var_stmt);
meta.stmt_queue.push_back(handler);
var_expr.to_frag()
}
}
}
}

impl DocumentationModule for Command {
Expand Down
16 changes: 6 additions & 10 deletions src/modules/command/modifier.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::mem::swap;
use amber_meta::ContextManager;
use heraclitus_compiler::prelude::*;
use crate::modules::prelude::*;
use crate::modules::block::Block;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, ContextManager)]
pub struct CommandModifier {
pub block: Option<Box<Block>>,
#[context]
pub is_trust: bool,
pub is_silent: bool,
pub is_sudo: bool
Expand All @@ -24,15 +25,10 @@ impl CommandModifier {
pub fn use_modifiers<F>(
&mut self, meta: &mut ParserMetadata, context: F
) -> SyntaxResult where F: FnOnce(&mut Self, &mut ParserMetadata) -> SyntaxResult {
let mut is_trust_holder = self.is_trust;
if self.is_trust {
swap(&mut is_trust_holder, &mut meta.context.is_trust_ctx);
}
// The setter returns the old value
let old_trust = meta.context.set_is_trust_ctx(self.is_trust || meta.context.is_trust_ctx);
let result = context(self, meta);
// Swap back the value
if self.is_trust {
swap(&mut is_trust_holder, &mut meta.context.is_trust_ctx);
}
meta.context.set_is_trust_ctx(old_trust);
result
}

Expand Down
Loading