(Largely) trait-ify Schala

The idea is to provide a trait `ProgrammingLanguage` that actually does
all the work, and then main.rs will just be the infra for storing its
own state
This commit is contained in:
greg 2017-01-23 00:03:08 -08:00
parent 5e474231da
commit 8326a12c9c
2 changed files with 16 additions and 8 deletions

View File

@ -8,12 +8,12 @@ pub struct ParseError {
pub msg: String,
}
pub trait ProgrammingLanguage {
pub trait ProgrammingLanguage<Evaluator> {
type Token: Debug;
type AST: Debug;
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError>;
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError>;
fn evaluate(input: &Self::AST);
fn evaluate(input: Self::AST, evaluator: &mut Evaluator) -> Vec<String>;
fn compile(input: &Self::AST);
}

View File

@ -148,9 +148,14 @@ impl<'a> Repl<'a> {
}
fn input_handler(&mut self, input: &str) -> String {
let schala = Schala { };
self.input_handler_new(input, schala)
}
fn input_handler_new<T: ProgrammingLanguage<eval::Evaluator<'a>>>(&mut self, input: &str, language: T) -> String {
let mut output = String::new();
let tokens = match tokenize(input) {
let tokens = match T::tokenize(input) {
Ok(tokens) => tokens,
Err(err) => {
output.push_str(&format!("Tokenization error: {}\n", err.msg));
@ -162,7 +167,7 @@ impl<'a> Repl<'a> {
output.push_str(&format!("Tokens: {:?}\n", tokens));
}
let ast = match parse(&tokens, &[]) {
let ast = match T::parse(tokens) {
Ok(ast) => ast,
Err(err) => {
output.push_str(&format!("Parse error: {:?}\n", err.msg));
@ -174,12 +179,15 @@ impl<'a> Repl<'a> {
output.push_str(&format!("AST: {:?}\n", ast));
}
/*
if self.show_llvm_ir {
let s = compile_ast(ast);
output.push_str(&s);
*/
if false {
} else {
// for now only handle last output
let mut full_output: Vec<String> = self.evaluator.run(ast);
let mut full_output: Vec<String> = T::evaluate(ast, &mut self.evaluator);
output.push_str(&full_output.pop().unwrap_or("".to_string()));
}
output
@ -239,7 +247,7 @@ impl<'a> Repl<'a> {
struct Schala { }
impl ProgrammingLanguage for Schala {
impl<'a> ProgrammingLanguage<eval::Evaluator<'a>> for Schala {
type Token = tokenizer::Token;
type AST = parser::AST;
@ -250,8 +258,8 @@ impl ProgrammingLanguage for Schala {
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError> {
parser::parse(&input, &[]).map_err(|x| ParseError { msg: x.msg })
}
fn evaluate(input: &Self::AST) {
unimplemented!()
fn evaluate(input: Self::AST, evaluator: &mut Evaluator) -> Vec<String> {
evaluator.run(input)
}
fn compile(input: &Self::AST) {
unimplemented!()