Abstracted most work into LanguageInterface trait
Still need to handle state
This commit is contained in:
parent
6dec35d460
commit
4ea600d55c
@ -1,3 +1,4 @@
|
|||||||
|
use std::default::Default;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -34,9 +35,54 @@ pub trait EvaluationMachine {
|
|||||||
fn new() -> Self;
|
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<X, T, A, E> LanguageWrapper for X where X: ProgrammingLanguage<Token=T, AST=A, Evaluator=E>, T: Debug, A: Debug, E: EvaluationMachine {
|
pub trait LanguageInterface {
|
||||||
|
fn evaluate_in_repl(&mut self, input: &str, options: LanguageInterfaceOptions) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<PL, T, A, E> LanguageInterface for PL where PL: ProgrammingLanguage<Token=T, AST=A, Evaluator=E>, 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<String> = PL::evaluate(ast, &mut evaluator);
|
||||||
|
output.push_str(&full_output.pop().unwrap_or("".to_string()));
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
48
src/main.rs
48
src/main.rs
@ -7,6 +7,7 @@ use std::fs::File;
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::default::Default;
|
||||||
|
|
||||||
mod schala_lang;
|
mod schala_lang;
|
||||||
use schala_lang::SchalaEvaluator;
|
use schala_lang::SchalaEvaluator;
|
||||||
@ -15,7 +16,7 @@ use schala_lang::Schala;
|
|||||||
mod maaru_lang;
|
mod maaru_lang;
|
||||||
|
|
||||||
mod language;
|
mod language;
|
||||||
use language::{ProgrammingLanguage, LanguageWrapper, LLVMCodeString, EvaluationMachine};
|
use language::{ProgrammingLanguage, LanguageInterface, LLVMCodeString, EvaluationMachine};
|
||||||
|
|
||||||
mod llvm_wrap;
|
mod llvm_wrap;
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ struct Repl<'a> {
|
|||||||
show_tokens: bool,
|
show_tokens: bool,
|
||||||
show_parse: bool,
|
show_parse: bool,
|
||||||
show_llvm_ir: bool,
|
show_llvm_ir: bool,
|
||||||
languages: Vec<Box<LanguageWrapper>>,
|
languages: Vec<Box<LanguageInterface>>,
|
||||||
evaluator: SchalaEvaluator<'a>,
|
evaluator: SchalaEvaluator<'a>,
|
||||||
interpreter_directive_sigil: char,
|
interpreter_directive_sigil: char,
|
||||||
reader: LineReader,
|
reader: LineReader,
|
||||||
@ -147,47 +148,8 @@ impl<'a> Repl<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn input_handler(&mut self, input: &str) -> String {
|
fn input_handler(&mut self, input: &str) -> String {
|
||||||
let schala = Schala::new();
|
let ref mut language = self.languages[0];
|
||||||
let mut evaluator = <SchalaEvaluator as EvaluationMachine>::new();
|
language.evaluate_in_repl(input, language::LanguageInterfaceOptions::default())
|
||||||
self.input_handler_new(input, schala, &mut evaluator)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn input_handler_new<T: ProgrammingLanguage>(&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<String> = T::evaluate(ast, &mut evaluator);
|
|
||||||
output.push_str(&full_output.pop().unwrap_or("".to_string()));
|
|
||||||
}
|
|
||||||
output
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_interpreter_directive(&mut self, input: &str) -> bool {
|
fn handle_interpreter_directive(&mut self, input: &str) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user