From 4ea600d55c05c9acb29ebbd0702727eb5ef5a5d7 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 1 Feb 2017 02:15:18 -0800 Subject: [PATCH] Abstracted most work into LanguageInterface trait Still need to handle state --- src/language.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 48 +++++---------------------------------------- 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/language.rs b/src/language.rs index acfb1c8..930529b 100644 --- a/src/language.rs +++ b/src/language.rs @@ -1,3 +1,4 @@ +use std::default::Default; use std::fmt::Debug; #[derive(Debug)] @@ -34,9 +35,54 @@ pub trait EvaluationMachine { fn new() -> Self; } -pub trait LanguageWrapper { +#[derive(Default)] +pub struct LanguageInterfaceOptions { + pub show_parse: bool, + pub show_tokens: bool, + pub show_llvm_ir: bool, } -impl LanguageWrapper for X where X: ProgrammingLanguage, T: Debug, A: Debug, E: EvaluationMachine { - +pub trait LanguageInterface { + fn evaluate_in_repl(&mut self, input: &str, options: LanguageInterfaceOptions) -> String; +} + +impl LanguageInterface for PL where PL: ProgrammingLanguage, T: Debug, A: Debug, E: EvaluationMachine { + fn evaluate_in_repl(&mut self, input: &str, options: LanguageInterfaceOptions) -> String { + let mut output = String::new(); + + let tokens = match PL::tokenize(input) { + Ok(tokens) => tokens, + Err(err) => { + output.push_str(&format!("Tokenization error: {}\n", err.msg)); + return output; + } + }; + + if options.show_tokens { + output.push_str(&format!("Tokens: {:?}\n", tokens)); + } + + let ast = match PL::parse(tokens) { + Ok(ast) => ast, + Err(err) => { + output.push_str(&format!("Parse error: {:?}\n", err.msg)); + return output; + } + }; + + if options.show_parse { + output.push_str(&format!("AST: {:?}\n", ast)); + } + + if options.show_llvm_ir { + let LLVMCodeString(s) = PL::compile(ast); + output.push_str(&s); + } else { + // for now only handle last output + let mut evaluator = PL::Evaluator::new(); + let mut full_output: Vec = PL::evaluate(ast, &mut evaluator); + output.push_str(&full_output.pop().unwrap_or("".to_string())); + } + output + } } diff --git a/src/main.rs b/src/main.rs index bd5cd46..9c4badf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use std::fs::File; use std::io::Read; use std::process; use std::io::Write; +use std::default::Default; mod schala_lang; use schala_lang::SchalaEvaluator; @@ -15,7 +16,7 @@ use schala_lang::Schala; mod maaru_lang; mod language; -use language::{ProgrammingLanguage, LanguageWrapper, LLVMCodeString, EvaluationMachine}; +use language::{ProgrammingLanguage, LanguageInterface, LLVMCodeString, EvaluationMachine}; mod llvm_wrap; @@ -97,7 +98,7 @@ struct Repl<'a> { show_tokens: bool, show_parse: bool, show_llvm_ir: bool, - languages: Vec>, + languages: Vec>, evaluator: SchalaEvaluator<'a>, interpreter_directive_sigil: char, reader: LineReader, @@ -147,47 +148,8 @@ impl<'a> Repl<'a> { } fn input_handler(&mut self, input: &str) -> String { - let schala = Schala::new(); - let mut evaluator = ::new(); - self.input_handler_new(input, schala, &mut evaluator) - } - - fn input_handler_new(&mut self, input: &str, language: T, mut evaluator: &mut T::Evaluator) -> String { - let mut output = String::new(); - - let tokens = match T::tokenize(input) { - Ok(tokens) => tokens, - Err(err) => { - output.push_str(&format!("Tokenization error: {}\n", err.msg)); - return output; - } - }; - - if self.show_tokens { - output.push_str(&format!("Tokens: {:?}\n", tokens)); - } - - let ast = match T::parse(tokens) { - Ok(ast) => ast, - Err(err) => { - output.push_str(&format!("Parse error: {:?}\n", err.msg)); - return output; - } - }; - - if self.show_parse { - output.push_str(&format!("AST: {:?}\n", ast)); - } - - if self.show_llvm_ir { - let LLVMCodeString(s) = T::compile(ast); - output.push_str(&s); - } else { - // for now only handle last output - let mut full_output: Vec = T::evaluate(ast, &mut evaluator); - output.push_str(&full_output.pop().unwrap_or("".to_string())); - } - output + let ref mut language = self.languages[0]; + language.evaluate_in_repl(input, language::LanguageInterfaceOptions::default()) } fn handle_interpreter_directive(&mut self, input: &str) -> bool {