2019-06-02 00:27:12 -07:00
|
|
|
use super::{Repl, InterpreterDirectiveOutput};
|
2019-06-04 15:02:51 -07:00
|
|
|
use crate::repl::help::help;
|
2019-06-02 00:27:12 -07:00
|
|
|
use crate::language::{LangMetaRequest, LangMetaResponse, DebugAsk, DebugResponse};
|
|
|
|
use itertools::Itertools;
|
|
|
|
use std::fmt::Write as FmtWrite;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum DirectiveAction {
|
|
|
|
Null,
|
|
|
|
Help,
|
|
|
|
QuitProgram,
|
|
|
|
ListPasses,
|
2019-06-02 00:43:55 -07:00
|
|
|
ShowImmediate,
|
|
|
|
Show,
|
|
|
|
Hide,
|
|
|
|
TotalTimeOff,
|
|
|
|
TotalTimeOn,
|
|
|
|
StageTimeOff,
|
|
|
|
StageTimeOn,
|
|
|
|
Doc,
|
2019-06-02 00:27:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DirectiveAction {
|
|
|
|
pub fn perform(&self, repl: &mut Repl, arguments: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
use DirectiveAction::*;
|
|
|
|
match self {
|
|
|
|
Null => None,
|
2019-06-03 15:18:53 -07:00
|
|
|
Help => help(repl, arguments),
|
2019-06-02 00:27:12 -07:00
|
|
|
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![],
|
|
|
|
};
|
|
|
|
|
|
|
|
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)
|
2019-06-02 00:43:55 -07:00
|
|
|
},
|
|
|
|
ShowImmediate => {
|
|
|
|
let cur_state = repl.get_cur_language_state();
|
2019-07-28 11:25:21 -07:00
|
|
|
let stage_name = match arguments.get(0) {
|
2019-06-02 00:43:55 -07:00
|
|
|
Some(s) => s.to_string(),
|
|
|
|
None => return Some(format!("Must specify a thing to debug")),
|
|
|
|
};
|
2019-06-19 03:27:18 -07:00
|
|
|
let meta = LangMetaRequest::ImmediateDebug(DebugAsk::ByStage { stage_name: stage_name.clone(), token: None });
|
|
|
|
let meta_response = cur_state.request_meta(meta);
|
2019-06-02 00:43:55 -07:00
|
|
|
|
2019-07-28 11:25:21 -07:00
|
|
|
let response = match meta_response {
|
2019-06-19 10:41:20 -07:00
|
|
|
LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => match ask {
|
2019-06-22 12:13:43 -07:00
|
|
|
DebugAsk::ByStage { stage_name: ref this_stage_name, ..} if *this_stage_name == stage_name => value,
|
2019-06-19 10:41:20 -07:00
|
|
|
_ => return Some(format!("Wrong debug stage"))
|
|
|
|
},
|
2019-06-02 00:43:55 -07:00
|
|
|
_ => return Some(format!("Invalid language meta response")),
|
|
|
|
};
|
|
|
|
Some(response)
|
|
|
|
},
|
|
|
|
Show => {
|
2019-06-22 12:13:43 -07:00
|
|
|
let this_stage_name = match arguments.get(0) {
|
2019-06-02 00:43:55 -07:00
|
|
|
Some(s) => s.to_string(),
|
|
|
|
None => return Some(format!("Must specify a stage to show")),
|
|
|
|
};
|
2019-06-22 12:13:43 -07:00
|
|
|
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
|
|
|
|
});
|
|
|
|
|
|
|
|
let ask = DebugAsk::ByStage { stage_name: this_stage_name, token };
|
2019-06-02 00:43:55 -07:00
|
|
|
repl.options.debug_asks.insert(ask);
|
|
|
|
None
|
|
|
|
},
|
|
|
|
Hide => {
|
2019-06-22 12:13:43 -07:00
|
|
|
let stage_name_to_remove = match arguments.get(0) {
|
2019-06-02 00:43:55 -07:00
|
|
|
Some(s) => s.to_string(),
|
|
|
|
None => return Some(format!("Must specify a stage to hide")),
|
|
|
|
};
|
2019-06-22 12:13:43 -07:00
|
|
|
repl.options.debug_asks.retain(|ask| match ask {
|
|
|
|
DebugAsk::ByStage { stage_name, .. } if *stage_name == stage_name_to_remove => false,
|
|
|
|
_ => true
|
|
|
|
});
|
2019-06-02 00:43:55 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-02 00:43:55 -07:00
|
|
|
fn total_time_on(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
repl.options.show_total_time = true;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn total_time_off(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
repl.options.show_total_time = false;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stage_time_on(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
repl.options.show_stage_times = true;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stage_time_off(repl: &mut Repl, _: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
repl.options.show_stage_times = false;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn doc(repl: &mut Repl, arguments: &[&str]) -> InterpreterDirectiveOutput {
|
|
|
|
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")))
|
|
|
|
}
|
2019-06-03 15:18:53 -07:00
|
|
|
|