2018-07-03 03:02:16 -07:00
|
|
|
use std::collections::HashMap;
|
2018-03-24 15:14:24 -07:00
|
|
|
use colored::*;
|
2018-03-24 13:20:10 -07:00
|
|
|
use std::fmt::Write;
|
2018-08-14 22:56:22 -07:00
|
|
|
use std::time;
|
2017-09-08 03:47:04 -07:00
|
|
|
|
2017-09-17 18:57:47 -07:00
|
|
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
2017-08-30 19:09:22 -07:00
|
|
|
pub struct EvalOptions {
|
2018-05-01 02:58:29 -07:00
|
|
|
pub execution_method: ExecutionMethod,
|
2018-07-15 15:01:50 -07:00
|
|
|
pub debug_passes: HashMap<String, PassDebugOptionsDescriptor>,
|
2018-10-01 02:05:07 -07:00
|
|
|
pub debug_timing: bool,
|
2018-03-20 20:29:07 -07:00
|
|
|
}
|
2018-07-03 03:02:16 -07:00
|
|
|
|
2018-07-06 03:17:37 -07:00
|
|
|
#[derive(Debug, Hash, PartialEq)]
|
|
|
|
pub struct PassDescriptor {
|
|
|
|
pub name: String,
|
|
|
|
pub debug_options: Vec<String>
|
|
|
|
}
|
|
|
|
|
2018-07-03 03:02:16 -07:00
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
2018-07-15 15:01:50 -07:00
|
|
|
pub struct PassDebugOptionsDescriptor {
|
2018-07-03 03:02:16 -07:00
|
|
|
pub opts: Vec<String>,
|
|
|
|
}
|
|
|
|
|
2018-03-20 20:29:07 -07:00
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
|
pub enum ExecutionMethod {
|
|
|
|
Compile,
|
|
|
|
Interpret,
|
|
|
|
}
|
|
|
|
impl Default for ExecutionMethod {
|
|
|
|
fn default() -> ExecutionMethod {
|
|
|
|
ExecutionMethod::Interpret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-11 14:53:08 -07:00
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct UnfinishedComputation {
|
2018-05-13 18:28:10 -07:00
|
|
|
artifacts: Vec<(String, TraceArtifact)>,
|
2018-08-14 22:56:22 -07:00
|
|
|
pub durations: Vec<time::Duration>,
|
2018-07-03 03:39:43 -07:00
|
|
|
pub cur_debug_options: Vec<String>,
|
2018-03-11 14:53:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct FinishedComputation {
|
2018-05-13 18:28:10 -07:00
|
|
|
artifacts: Vec<(String, TraceArtifact)>,
|
2018-08-14 22:56:22 -07:00
|
|
|
durations: Vec<time::Duration>,
|
2018-03-11 14:53:08 -07:00
|
|
|
text_output: Result<String, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UnfinishedComputation {
|
|
|
|
pub fn add_artifact(&mut self, artifact: TraceArtifact) {
|
2018-05-13 18:28:10 -07:00
|
|
|
self.artifacts.push((artifact.stage_name.clone(), artifact));
|
2018-03-11 14:53:08 -07:00
|
|
|
}
|
2018-04-29 04:00:41 -07:00
|
|
|
pub fn finish(self, text_output: Result<String, String>) -> FinishedComputation {
|
|
|
|
FinishedComputation {
|
|
|
|
artifacts: self.artifacts,
|
2018-08-14 22:56:22 -07:00
|
|
|
text_output,
|
2018-10-01 02:05:07 -07:00
|
|
|
durations: self.durations,
|
2018-04-29 04:00:41 -07:00
|
|
|
}
|
|
|
|
}
|
2018-03-11 14:53:08 -07:00
|
|
|
pub fn output(self, output: Result<String, String>) -> FinishedComputation {
|
|
|
|
FinishedComputation {
|
|
|
|
artifacts: self.artifacts,
|
2018-08-14 22:56:22 -07:00
|
|
|
text_output: output,
|
|
|
|
durations: self.durations,
|
2018-03-11 14:53:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-19 22:57:54 -07:00
|
|
|
impl FinishedComputation {
|
2018-10-01 02:05:07 -07:00
|
|
|
|
|
|
|
fn get_timing(&self) -> Option<String> {
|
|
|
|
if self.durations.len() != 0 {
|
|
|
|
let mut buf = String::new();
|
|
|
|
write!(&mut buf, "Timing: ").unwrap();
|
|
|
|
for duration in self.durations.iter() {
|
|
|
|
let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9);
|
|
|
|
write!(&mut buf, "{}s, ", timing).unwrap()
|
|
|
|
}
|
|
|
|
write!(&mut buf, "\n").unwrap();
|
|
|
|
Some(buf)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-20 20:29:07 -07:00
|
|
|
pub fn to_repl(&self) -> String {
|
2018-04-24 23:11:04 -07:00
|
|
|
let mut buf = String::new();
|
2018-08-16 01:47:21 -07:00
|
|
|
for (stage, artifact) in self.artifacts.iter() {
|
2018-05-11 02:33:19 -07:00
|
|
|
let color = artifact.text_color;
|
|
|
|
let stage = stage.color(color).bold();
|
|
|
|
let output = artifact.debug_output.color(color);
|
2018-08-16 01:47:21 -07:00
|
|
|
write!(&mut buf, "{}: {}\n", stage, output).unwrap();
|
2018-03-19 22:57:54 -07:00
|
|
|
}
|
2018-05-11 02:33:19 -07:00
|
|
|
|
2018-10-01 02:05:07 -07:00
|
|
|
match self.get_timing() {
|
|
|
|
Some(timing) => write!(&mut buf, "{}", timing).unwrap(),
|
|
|
|
None => ()
|
2018-08-16 01:47:21 -07:00
|
|
|
}
|
2018-10-01 02:05:07 -07:00
|
|
|
|
2018-04-24 23:11:04 -07:00
|
|
|
match self.text_output {
|
|
|
|
Ok(ref output) => write!(&mut buf, "{}", output).unwrap(),
|
|
|
|
Err(ref err) => write!(&mut buf, "{} {}", "Error: ".red().bold(), err).unwrap(),
|
|
|
|
}
|
|
|
|
buf
|
2018-03-19 22:57:54 -07:00
|
|
|
}
|
2018-03-20 20:29:07 -07:00
|
|
|
pub fn to_noninteractive(&self) -> Option<String> {
|
|
|
|
match self.text_output {
|
2018-03-27 00:50:31 -07:00
|
|
|
Ok(_) => {
|
|
|
|
let mut buf = String::new();
|
2018-05-13 18:28:10 -07:00
|
|
|
for (stage, artifact) in self.artifacts.iter() {
|
|
|
|
let color = artifact.text_color;
|
|
|
|
let stage = stage.color(color).bold();
|
|
|
|
let output = artifact.debug_output.color(color);
|
|
|
|
write!(&mut buf, "{}: {}\n", stage, output).unwrap();
|
2018-03-27 00:50:31 -07:00
|
|
|
}
|
|
|
|
if buf == "" { None } else { Some(buf) }
|
|
|
|
},
|
2018-03-22 03:37:48 -07:00
|
|
|
Err(ref s) => Some(format!("{} {}", "Error: ".red().bold(), s))
|
2018-03-20 20:29:07 -07:00
|
|
|
}
|
|
|
|
}
|
2018-03-19 22:57:54 -07:00
|
|
|
}
|
|
|
|
|
2017-08-31 20:59:43 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct TraceArtifact {
|
|
|
|
stage_name: String,
|
|
|
|
debug_output: String,
|
2017-09-08 03:47:04 -07:00
|
|
|
text_color: &'static str,
|
2017-08-31 20:59:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TraceArtifact {
|
|
|
|
pub fn new(stage: &str, debug: String) -> TraceArtifact {
|
2017-09-16 14:29:22 -07:00
|
|
|
let color = match stage {
|
2017-10-08 22:17:29 -07:00
|
|
|
"parse_trace" | "ast" => "red",
|
2018-05-11 02:58:14 -07:00
|
|
|
"ast_reducing" => "red",
|
2017-09-16 14:29:22 -07:00
|
|
|
"tokens" => "green",
|
2017-10-01 00:48:08 -07:00
|
|
|
"type_check" => "magenta",
|
2017-09-16 14:29:22 -07:00
|
|
|
_ => "blue",
|
|
|
|
};
|
|
|
|
TraceArtifact { stage_name: stage.to_string(), debug_output: debug, text_color: color}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_parse_trace(trace: Vec<String>) -> TraceArtifact {
|
2017-09-16 15:05:11 -07:00
|
|
|
let mut output = String::new();
|
|
|
|
|
|
|
|
for t in trace {
|
|
|
|
output.push_str(&t);
|
|
|
|
output.push_str("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
TraceArtifact { stage_name: "parse_trace".to_string(), debug_output: output, text_color: "red"}
|
2017-08-31 20:59:43 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-30 19:09:22 -07:00
|
|
|
pub trait ProgrammingLanguageInterface {
|
2018-04-29 00:04:31 -07:00
|
|
|
fn execute_pipeline(&mut self, _input: &str, _eval_options: &EvalOptions) -> FinishedComputation {
|
2018-08-14 22:56:22 -07:00
|
|
|
FinishedComputation { artifacts: vec![], text_output: Err(format!("Execution pipeline not done")), durations: vec![] }
|
2018-04-29 00:04:31 -07:00
|
|
|
}
|
|
|
|
|
2017-08-30 19:09:22 -07:00
|
|
|
fn get_language_name(&self) -> String;
|
2017-10-02 23:07:05 -07:00
|
|
|
fn get_source_file_suffix(&self) -> String;
|
2018-07-06 03:17:37 -07:00
|
|
|
fn get_passes(&self) -> Vec<PassDescriptor> {
|
2018-05-01 00:38:01 -07:00
|
|
|
vec![]
|
|
|
|
}
|
2018-04-29 03:22:36 -07:00
|
|
|
fn handle_custom_interpreter_directives(&mut self, _commands: &Vec<&str>) -> Option<String> {
|
2018-04-23 21:33:15 -07:00
|
|
|
None
|
|
|
|
}
|
|
|
|
fn custom_interpreter_directives_help(&self) -> String {
|
|
|
|
format!(">> No custom interpreter directives specified <<")
|
|
|
|
}
|
2018-09-22 00:24:27 -07:00
|
|
|
fn get_doc(&self, _commands: &Vec<&str>) -> Option<String> {
|
2018-09-21 19:25:58 -07:00
|
|
|
None
|
|
|
|
}
|
2019-03-13 00:13:39 -07:00
|
|
|
|
|
|
|
/* ------- */
|
|
|
|
// new trait methods
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse {
|
|
|
|
ComputationResponse {
|
|
|
|
main_output: Err(format!("Computation pipeline not implemented")),
|
|
|
|
global_output_stats: GlobalOutputStats::default(),
|
|
|
|
debug_responses: vec![],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn repl_request(&self, repl_request: String) -> String {
|
|
|
|
format!("Repl request not implemented")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-14 00:15:13 -07:00
|
|
|
//TODO source can probably be a &str
|
2019-03-13 10:10:42 -07:00
|
|
|
pub struct ComputationRequest {
|
2019-03-13 00:13:39 -07:00
|
|
|
pub source: String,
|
|
|
|
pub debug_requests: Vec<DebugRequest>,
|
|
|
|
}
|
|
|
|
|
2019-03-13 10:10:42 -07:00
|
|
|
pub struct ComputationResponse {
|
2019-03-13 00:13:39 -07:00
|
|
|
pub main_output: Result<String, String>,
|
|
|
|
pub global_output_stats: GlobalOutputStats,
|
|
|
|
pub debug_responses: Vec<DebugResponse>,
|
2017-08-30 19:09:22 -07:00
|
|
|
}
|
2019-03-12 00:01:30 -07:00
|
|
|
|
2019-03-13 10:10:42 -07:00
|
|
|
pub struct DebugRequest {
|
2019-03-13 00:13:39 -07:00
|
|
|
kind: String,
|
|
|
|
value: String
|
|
|
|
}
|
2019-03-12 00:01:30 -07:00
|
|
|
|
2019-03-13 10:10:42 -07:00
|
|
|
pub struct DebugResponse {
|
2019-03-13 00:13:39 -07:00
|
|
|
kind: String,
|
|
|
|
value: String
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default, Debug)]
|
2019-03-13 10:10:42 -07:00
|
|
|
pub struct GlobalOutputStats {
|
2019-03-13 00:13:39 -07:00
|
|
|
total_duration: Option<time::Duration>,
|
|
|
|
stage_durations: Option<Vec<(String, time::Duration)>>
|
|
|
|
}
|