From 6dec35d460390ec8b0ef06951fae737f79989ad1 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 31 Jan 2017 00:53:31 -0800 Subject: [PATCH] Think I've nearly gotten it traitified correctly... --- src/language.rs | 12 ++++++++++-- src/maaru_lang/mod.rs | 5 +++-- src/main.rs | 19 +++++++++++-------- src/schala_lang/mod.rs | 14 ++++++++++---- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/language.rs b/src/language.rs index 80e12d5..acfb1c8 100644 --- a/src/language.rs +++ b/src/language.rs @@ -18,13 +18,14 @@ pub struct ParseError { pub struct LLVMCodeString(pub String); -pub trait ProgrammingLanguage { +pub trait ProgrammingLanguage { type Token: Debug; type AST: Debug; + type Evaluator: EvaluationMachine; fn tokenize(input: &str) -> Result, TokenError>; fn parse(input: Vec) -> Result; - fn evaluate(ast: Self::AST, evaluator: &mut E) -> Vec; + fn evaluate(ast: Self::AST, evaluator: &mut Self::Evaluator) -> Vec; fn compile(ast: Self::AST) -> LLVMCodeString; } @@ -32,3 +33,10 @@ pub trait EvaluationMachine { fn set_option(&mut self, option: &str, value: bool) -> bool; fn new() -> Self; } + +pub trait LanguageWrapper { +} + +impl LanguageWrapper for X where X: ProgrammingLanguage, T: Debug, A: Debug, E: EvaluationMachine { + +} diff --git a/src/maaru_lang/mod.rs b/src/maaru_lang/mod.rs index e6d9dd7..891305c 100644 --- a/src/maaru_lang/mod.rs +++ b/src/maaru_lang/mod.rs @@ -14,9 +14,10 @@ pub struct Token { } #[derive(Debug)] pub struct AST { } -impl ProgrammingLanguage for Maaru { +impl ProgrammingLanguage for Maaru { type Token = Token; type AST = AST; + type Evaluator = MaaruEvaluator; fn tokenize(input: &str) -> Result, TokenError> { Ok(vec![Token { }]) @@ -25,7 +26,7 @@ impl ProgrammingLanguage for Maaru { fn parse(input: Vec) -> Result { Ok(AST { }) } - fn evaluate(ast: Self::AST, evaluator: &mut MaaruEvaluator) -> Vec { + fn evaluate(ast: Self::AST, evaluator: &mut Self::Evaluator) -> Vec { vec!["Unimplemented".to_string()] } fn compile(ast: Self::AST) -> LLVMCodeString { diff --git a/src/main.rs b/src/main.rs index 469ace8..bd5cd46 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ use schala_lang::Schala; mod maaru_lang; mod language; -use language::{ProgrammingLanguage, LLVMCodeString, EvaluationMachine}; +use language::{ProgrammingLanguage, LanguageWrapper, LLVMCodeString, EvaluationMachine}; mod llvm_wrap; @@ -36,7 +36,7 @@ fn main() { repl.run(); } [_, ref filename, _..] => { - let language = Schala { }; + let language = Schala::new(); run_noninteractive(filename, !option_matches.opt_present("i"), trace, &language); } }; @@ -56,7 +56,7 @@ fn program_options() -> getopts::Options { options } -fn run_noninteractive<'a, T: ProgrammingLanguage>>(filename: &str, compile: bool, trace_evaluation: bool, language: &T) { +fn run_noninteractive<'a, T: ProgrammingLanguage>(filename: &str, compile: bool, trace_evaluation: bool, language: &T) { let mut source_file = File::open(&Path::new(filename)).unwrap(); let mut buffer = String::new(); source_file.read_to_string(&mut buffer).unwrap(); @@ -81,7 +81,7 @@ fn run_noninteractive<'a, T: ProgrammingLanguage>>(filename: if compile { compilation_sequence(T::compile(ast), filename); } else { - let mut evaluator = ::new(); + let mut evaluator = ::Evaluator::new(); if trace_evaluation { evaluator.set_option("trace_evaluation", true); } @@ -97,6 +97,7 @@ struct Repl<'a> { show_tokens: bool, show_parse: bool, show_llvm_ir: bool, + languages: Vec>, evaluator: SchalaEvaluator<'a>, interpreter_directive_sigil: char, reader: LineReader, @@ -114,6 +115,7 @@ impl<'a> Repl<'a> { show_tokens: false, show_parse: false, show_llvm_ir: show_llvm, + languages: vec![Box::new(Schala::new())], evaluator: evaluator, interpreter_directive_sigil: '.', reader: reader, @@ -145,11 +147,12 @@ impl<'a> Repl<'a> { } fn input_handler(&mut self, input: &str) -> String { - let schala = Schala { }; - self.input_handler_new(input, schala) + 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) -> String { + 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) { @@ -181,7 +184,7 @@ impl<'a> Repl<'a> { output.push_str(&s); } else { // for now only handle last output - let mut full_output: Vec = T::evaluate(ast, &mut self.evaluator); + let mut full_output: Vec = T::evaluate(ast, &mut evaluator); output.push_str(&full_output.pop().unwrap_or("".to_string())); } output diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index 3867381..c5a7e83 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -1,3 +1,4 @@ +use ::std::marker::PhantomData; pub mod tokenizer; pub mod parser; pub mod eval; @@ -7,20 +8,25 @@ use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, L pub use self::eval::Evaluator as SchalaEvaluator; -pub struct Schala { } +pub struct Schala<'a> { marker: PhantomData<&'a ()> } +impl<'a> Schala<'a> { + pub fn new() -> Schala<'a> { + Schala { marker: PhantomData } + } +} -impl<'a> ProgrammingLanguage> for Schala { +impl<'a> ProgrammingLanguage for Schala<'a> { type Token = tokenizer::Token; type AST = parser::AST; + type Evaluator = SchalaEvaluator<'a>; fn tokenize(input: &str) -> Result, TokenError> { tokenizer::tokenize(input) } - fn parse(input: Vec) -> Result { parser::parse(&input, &[]).map_err(|x| ParseError { msg: x.msg }) } - fn evaluate(ast: Self::AST, evaluator: &mut eval::Evaluator) -> Vec { + fn evaluate(ast: Self::AST, evaluator: &mut Self::Evaluator) -> Vec { evaluator.run(ast) } fn compile(ast: Self::AST) -> LLVMCodeString {