From b5a6c5903e6e0210226a0a9572f9782fea247dde Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 31 Aug 2017 20:59:43 -0700 Subject: [PATCH] Switch to contentful output types --- src/language.rs | 54 +++++++++++++++++++++++++++++++++++++++++- src/maaru_lang/mod.rs | 26 ++++++++++---------- src/main.rs | 10 ++------ src/robo_lang/mod.rs | 16 ++++++------- src/schala_lang/mod.rs | 33 ++++++++++++++++++-------- 5 files changed, 99 insertions(+), 40 deletions(-) diff --git a/src/language.rs b/src/language.rs index 37494bc..6e0844c 100644 --- a/src/language.rs +++ b/src/language.rs @@ -24,8 +24,60 @@ pub struct EvalOptions { pub trace_evaluation: bool, } +#[derive(Debug, Default)] +pub struct ReplOutput { + output: String, + artifacts: Vec +} + +impl ReplOutput { + pub fn add_artifact(&mut self, artifact: TraceArtifact) { + self.artifacts.push(artifact); + } + pub fn add_output(&mut self, output: String) { + self.output = output; + } + + pub fn to_string(&self) -> String { + let mut acc = String::new(); + for line in self.artifacts.iter() { + acc.push_str(&line.debug_output); + } + acc.push_str(&self.output); + acc + } + + pub fn print_to_screen(&self) { + for line in self.artifacts.iter() { + println!("{}: {}", line.stage_name, line.debug_output); + } + println!("{}", self.output); + } +} + +/* +//TODO I'll probably wanna implement this later +#[derive(Debug)] +pub struct CompilationOutput { + output: LLVMCodeString, + artifacts: Vec, +} +*/ + +#[derive(Debug)] +pub struct TraceArtifact { + stage_name: String, + debug_output: String, +} + +impl TraceArtifact { + pub fn new(stage: &str, debug: String) -> TraceArtifact { + TraceArtifact { stage_name: stage.to_string(), debug_output: debug } + } +} + pub trait ProgrammingLanguageInterface { - fn evaluate_in_repl(&mut self, input: &str, eval_options: EvalOptions) -> Vec; + fn evaluate_in_repl(&mut self, input: &str, eval_options: EvalOptions) -> ReplOutput; fn get_language_name(&self) -> String; fn compile(&mut self, _input: &str) -> LLVMCodeString { LLVMCodeString("".to_string()) diff --git a/src/maaru_lang/mod.rs b/src/maaru_lang/mod.rs index 4399314..77389d7 100644 --- a/src/maaru_lang/mod.rs +++ b/src/maaru_lang/mod.rs @@ -3,7 +3,7 @@ pub mod parser; pub mod eval; pub mod compilation; -use language::{ProgrammingLanguageInterface, EvalOptions, LLVMCodeString}; +use language::{ProgrammingLanguageInterface, EvalOptions, ReplOutput, TraceArtifact, LLVMCodeString}; pub use self::eval::Evaluator as MaaruEvaluator; @@ -24,18 +24,18 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> { "Maaru".to_string() } - fn evaluate_in_repl(&mut self, input: &str, options: EvalOptions) -> Vec { - let mut output = vec![]; + fn evaluate_in_repl(&mut self, input: &str, options: EvalOptions) -> ReplOutput { + let mut output = ReplOutput::default(); + let tokens = match tokenizer::tokenize(input) { Ok(tokens) => { if options.debug_tokens { - output.push(format!("{:?}", tokens)); + output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens))); } tokens }, Err(err) => { - let msg = format!("Tokenization error: {:?}\n", err.msg); - output.push(msg); + output.add_output(format!("Tokenization error: {:?}\n", err.msg)); return output; } }; @@ -43,20 +43,20 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> { let ast = match parser::parse(&tokens, &[]) { Ok(ast) => { if options.debug_parse { - output.push(format!("{:?}", ast)); + output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); } ast }, Err(err) => { - let msg = format!("Parse error: {:?}\n", err.msg); - output.push(msg); + output.add_output(format!("Parse error: {:?}\n", err.msg)); return output; } }; - - let evaluation_output = self.evaluator.run(ast); - output.extend(evaluation_output); - + let mut evaluation_output = String::new(); + for s in self.evaluator.run(ast).iter() { + evaluation_output.push_str(s); + } + output.add_output(evaluation_output); return output; } diff --git a/src/main.rs b/src/main.rs index 6f77541..59bbabe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -132,9 +132,7 @@ fn run_noninteractive(filename: &str, language: } } else { let interpretor_output = language.evaluate_in_repl(&buffer, options); - for line in interpretor_output { - println!("{}", line); - } + interpretor_output.print_to_screen(); } } @@ -202,11 +200,7 @@ impl Repl { let interpretor_output = language.evaluate_in_repl(input, options); - let mut acc = String::new(); - for i in interpretor_output { - acc.push_str(&i) - } - acc + interpretor_output.to_string() } fn handle_interpreter_directive(&mut self, input: &str) -> bool { diff --git a/src/robo_lang/mod.rs b/src/robo_lang/mod.rs index 70952cb..41ba80c 100644 --- a/src/robo_lang/mod.rs +++ b/src/robo_lang/mod.rs @@ -1,15 +1,15 @@ extern crate itertools; use self::itertools::Itertools; -use language::{ProgrammingLanguageInterface, EvalOptions, TokenError}; +use language::{ProgrammingLanguageInterface, EvalOptions, ReplOutput, TokenError}; pub struct Robo { } impl Robo { - pub fn new() -> Robo { - Robo { } - } + pub fn new() -> Robo { + Robo { } + } } #[allow(dead_code)] @@ -137,17 +137,17 @@ impl ProgrammingLanguageInterface for Robo { "Robo".to_string() } - fn evaluate_in_repl(&mut self, input: &str, _eval_options: EvalOptions) -> Vec { - let mut output = vec!(); + fn evaluate_in_repl(&mut self, input: &str, _eval_options: EvalOptions) -> ReplOutput { + let mut output = ReplOutput::default(); let tokens = match tokenize(input) { Ok(tokens) => tokens, Err(e) => { - output.push(format!("Tokenize error: {:?}", e)); + output.add_output(format!("Tokenize error: {:?}", e)); return output; } }; - output.push(format!("{:?}", tokens)); + output.add_output(format!("{:?}", tokens)); output } } diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index d8b3eb1..4a564b0 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -1,4 +1,4 @@ -use language::{ProgrammingLanguageInterface, EvalOptions}; +use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, ReplOutput}; mod parsing; @@ -16,23 +16,36 @@ impl ProgrammingLanguageInterface for Schala { "Schala".to_string() } - fn evaluate_in_repl(&mut self, input: &str, _eval_options: EvalOptions) -> Vec { - let mut output = vec!(format!("test eval")); - + fn evaluate_in_repl(&mut self, input: &str, options: EvalOptions) -> ReplOutput { + let mut output = ReplOutput::default(); let tokens = match parsing::tokenize(input) { - Ok(tokens) => tokens, - Err(e) => { output.push(format!("{}", e.msg)); + Ok(tokens) => { + if options.debug_tokens { + output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens))); + } + tokens + }, + Err(err) => { + output.add_output(format!("Tokenization error: {:?}\n", err.msg)); return output; } }; - let _ast = match parsing::parse(tokens) { - Ok(ast) => ast, - Err(e) => { output.push(format!("{}", e.msg)); + let ast = match parsing::parse(tokens) { + Ok(ast) => { + if options.debug_parse { + output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); + } + ast + }, + Err(err) => { + output.add_output(format!("Parse error: {:?}\n", err.msg)); return output; } }; - output + let evaluation_output = format!("test eval"); + output.add_output(evaluation_output); + return output; } }