schala/schala-repl/src/repl/directive_actions.rs

146 lines
5.2 KiB
Rust
Raw Normal View History

2021-10-07 01:19:35 -07:00
use super::{InterpreterDirectiveOutput, Repl};
use crate::language::{DebugAsk, DebugResponse, LangMetaRequest, LangMetaResponse};
2019-06-04 15:02:51 -07:00
use crate::repl::help::help;
2019-06-02 00:27:12 -07:00
use std::fmt::Write as FmtWrite;
#[derive(Debug, Clone)]
pub enum DirectiveAction {
2021-10-07 01:19:35 -07:00
Null,
Help,
QuitProgram,
ListPasses,
ShowImmediate,
Show,
Hide,
TotalTimeOff,
TotalTimeOn,
StageTimeOff,
StageTimeOn,
Doc,
2019-06-02 00:27:12 -07:00
}
impl DirectiveAction {
2021-10-07 01:19:35 -07:00
pub fn perform(&self, repl: &mut Repl, arguments: &[&str]) -> InterpreterDirectiveOutput {
use DirectiveAction::*;
match self {
Null => None,
Help => help(repl, arguments),
QuitProgram => {
repl.save_before_exit();
::std::process::exit(0)
}
ListPasses => {
let language_state = repl.get_cur_language_state();
let pass_names = match language_state.request_meta(LangMetaRequest::StageNames) {
LangMetaResponse::StageNames(names) => names,
_ => vec![],
};
2019-06-02 00:27:12 -07:00
2021-10-07 01:19:35 -07:00
let mut buf = String::new();
for pass in pass_names.iter().map(|name| Some(name)).intersperse(None) {
match pass {
Some(pass) => write!(buf, "{}", pass).unwrap(),
None => write!(buf, " -> ").unwrap(),
}
}
Some(buf)
}
ShowImmediate => {
let cur_state = repl.get_cur_language_state();
let stage_name = match arguments.get(0) {
Some(s) => s.to_string(),
None => return Some(format!("Must specify a thing to debug")),
};
let meta = LangMetaRequest::ImmediateDebug(DebugAsk::ByStage {
stage_name: stage_name.clone(),
token: None,
});
let meta_response = cur_state.request_meta(meta);
2021-10-07 01:19:35 -07:00
let response = match meta_response {
LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => match ask {
DebugAsk::ByStage {
stage_name: ref this_stage_name,
..
} if *this_stage_name == stage_name => value,
_ => return Some(format!("Wrong debug stage")),
},
_ => return Some(format!("Invalid language meta response")),
};
Some(response)
}
Show => {
let this_stage_name = match arguments.get(0) {
Some(s) => s.to_string(),
None => return Some(format!("Must specify a stage to show")),
};
let token = arguments.get(1).map(|s| s.to_string());
repl.options.debug_asks.retain(|ask| match ask {
DebugAsk::ByStage { stage_name, .. } if *stage_name == this_stage_name => false,
_ => true,
});
2019-06-22 12:13:43 -07:00
2021-10-07 01:19:35 -07:00
let ask = DebugAsk::ByStage {
stage_name: this_stage_name,
token,
};
repl.options.debug_asks.insert(ask);
None
}
Hide => {
let stage_name_to_remove = match arguments.get(0) {
Some(s) => s.to_string(),
None => return Some(format!("Must specify a stage to hide")),
};
repl.options.debug_asks.retain(|ask| match ask {
DebugAsk::ByStage { stage_name, .. } if *stage_name == stage_name_to_remove => {
false
}
_ => true,
});
None
}
TotalTimeOff => total_time_off(repl, arguments),
TotalTimeOn => total_time_on(repl, arguments),
StageTimeOff => stage_time_off(repl, arguments),
StageTimeOn => stage_time_on(repl, arguments),
Doc => doc(repl, arguments),
}
2019-06-02 00:27:12 -07:00
}
}
fn total_time_on(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
2021-10-07 01:19:35 -07:00
repl.options.show_total_time = true;
None
}
fn total_time_off(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
2021-10-07 01:19:35 -07:00
repl.options.show_total_time = false;
None
}
fn stage_time_on(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
2021-10-07 01:19:35 -07:00
repl.options.show_stage_times = true;
None
}
fn stage_time_off(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
2021-10-07 01:19:35 -07:00
repl.options.show_stage_times = false;
None
}
fn doc(repl: &mut Repl, arguments: &[&str]) -> InterpreterDirectiveOutput {
2021-10-07 01:19:35 -07:00
arguments
.get(0)
.map(|cmd| {
let source = cmd.to_string();
let meta = LangMetaRequest::Docs { source };
let cur_state = repl.get_cur_language_state();
match cur_state.request_meta(meta) {
LangMetaResponse::Docs { doc_string } => Some(doc_string),
_ => Some(format!("Invalid doc response")),
}
})
.unwrap_or(Some(format!(":docs needs an argument")))
}