Abstract evaluation into EvaluationMachine trait
This commit is contained in:
parent
f37ab80163
commit
421a9a7e9b
@ -18,12 +18,17 @@ pub struct ParseError {
|
|||||||
|
|
||||||
pub struct LLVMCodeString(pub String);
|
pub struct LLVMCodeString(pub String);
|
||||||
|
|
||||||
pub trait ProgrammingLanguage<Evaluator> {
|
pub trait ProgrammingLanguage<E: EvaluationMachine> {
|
||||||
type Token: Debug;
|
type Token: Debug;
|
||||||
type AST: Debug;
|
type AST: Debug;
|
||||||
|
|
||||||
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError>;
|
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError>;
|
||||||
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError>;
|
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError>;
|
||||||
fn evaluate(ast: Self::AST, evaluator: &mut Evaluator) -> Vec<String>;
|
fn evaluate(ast: Self::AST, evaluator: &mut E) -> Vec<String>;
|
||||||
fn compile(ast: Self::AST) -> LLVMCodeString;
|
fn compile(ast: Self::AST) -> LLVMCodeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait EvaluationMachine {
|
||||||
|
fn set_option(&mut self, option: &str, value: bool) -> bool;
|
||||||
|
fn new() -> Self;
|
||||||
|
}
|
||||||
|
23
src/main.rs
23
src/main.rs
@ -9,11 +9,11 @@ use std::process;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
mod schala_lang;
|
mod schala_lang;
|
||||||
use schala_lang::eval::Evaluator;
|
use schala_lang::SchalaEvaluator;
|
||||||
use schala_lang::Schala;
|
use schala_lang::Schala;
|
||||||
|
|
||||||
use language::{ProgrammingLanguage, LLVMCodeString};
|
|
||||||
mod language;
|
mod language;
|
||||||
|
use language::{ProgrammingLanguage, LLVMCodeString, EvaluationMachine};
|
||||||
|
|
||||||
mod llvm_wrap;
|
mod llvm_wrap;
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ fn program_options() -> getopts::Options {
|
|||||||
options
|
options
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_noninteractive<'a, T: ProgrammingLanguage<Evaluator<'a>>>(filename: &str, compile: bool, trace_evaluation: bool, language: &T) {
|
fn run_noninteractive<'a, T: ProgrammingLanguage<SchalaEvaluator<'a>>>(filename: &str, compile: bool, trace_evaluation: bool, language: &T) {
|
||||||
let mut source_file = File::open(&Path::new(filename)).unwrap();
|
let mut source_file = File::open(&Path::new(filename)).unwrap();
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
source_file.read_to_string(&mut buffer).unwrap();
|
source_file.read_to_string(&mut buffer).unwrap();
|
||||||
@ -79,7 +79,10 @@ fn run_noninteractive<'a, T: ProgrammingLanguage<Evaluator<'a>>>(filename: &str,
|
|||||||
if compile {
|
if compile {
|
||||||
compilation_sequence(T::compile(ast), filename);
|
compilation_sequence(T::compile(ast), filename);
|
||||||
} else {
|
} else {
|
||||||
let mut evaluator = Evaluator::new_with_opts(None, trace_evaluation);
|
let mut evaluator = <SchalaEvaluator as EvaluationMachine>::new();
|
||||||
|
if trace_evaluation {
|
||||||
|
evaluator.set_option("trace_evaluation", true);
|
||||||
|
}
|
||||||
let results = T::evaluate(ast, &mut evaluator);
|
let results = T::evaluate(ast, &mut evaluator);
|
||||||
for result in results.iter() {
|
for result in results.iter() {
|
||||||
println!("{}", result);
|
println!("{}", result);
|
||||||
@ -92,7 +95,7 @@ struct Repl<'a> {
|
|||||||
show_tokens: bool,
|
show_tokens: bool,
|
||||||
show_parse: bool,
|
show_parse: bool,
|
||||||
show_llvm_ir: bool,
|
show_llvm_ir: bool,
|
||||||
evaluator: Evaluator<'a>,
|
evaluator: SchalaEvaluator<'a>,
|
||||||
interpreter_directive_sigil: char,
|
interpreter_directive_sigil: char,
|
||||||
reader: LineReader,
|
reader: LineReader,
|
||||||
}
|
}
|
||||||
@ -101,11 +104,15 @@ impl<'a> Repl<'a> {
|
|||||||
fn new(trace_evaluation: bool, show_llvm: bool) -> Repl<'a> {
|
fn new(trace_evaluation: bool, show_llvm: bool) -> Repl<'a> {
|
||||||
let mut reader: linefeed::Reader<_> = linefeed::Reader::new("Schala").unwrap();
|
let mut reader: linefeed::Reader<_> = linefeed::Reader::new("Schala").unwrap();
|
||||||
reader.set_prompt(">> ");
|
reader.set_prompt(">> ");
|
||||||
|
|
||||||
|
let mut evaluator = <SchalaEvaluator as EvaluationMachine>::new();
|
||||||
|
evaluator.set_option("trace_evaluation", trace_evaluation);
|
||||||
|
|
||||||
Repl {
|
Repl {
|
||||||
show_tokens: false,
|
show_tokens: false,
|
||||||
show_parse: false,
|
show_parse: false,
|
||||||
show_llvm_ir: show_llvm,
|
show_llvm_ir: show_llvm,
|
||||||
evaluator: Evaluator::new_with_opts(None, trace_evaluation),
|
evaluator: evaluator,
|
||||||
interpreter_directive_sigil: '.',
|
interpreter_directive_sigil: '.',
|
||||||
reader: reader,
|
reader: reader,
|
||||||
}
|
}
|
||||||
@ -140,7 +147,7 @@ impl<'a> Repl<'a> {
|
|||||||
self.input_handler_new(input, schala)
|
self.input_handler_new(input, schala)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input_handler_new<T: ProgrammingLanguage<Evaluator<'a>>>(&mut self, input: &str, language: T) -> String {
|
fn input_handler_new<T: ProgrammingLanguage<SchalaEvaluator<'a>>>(&mut self, input: &str, language: T) -> String {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
|
||||||
let tokens = match T::tokenize(input) {
|
let tokens = match T::tokenize(input) {
|
||||||
@ -216,7 +223,7 @@ impl<'a> Repl<'a> {
|
|||||||
match commands[2] {
|
match commands[2] {
|
||||||
"tokens" => self.show_tokens = show,
|
"tokens" => self.show_tokens = show,
|
||||||
"parse" => self.show_parse = show,
|
"parse" => self.show_parse = show,
|
||||||
"eval" => self.evaluator.trace_evaluation = show,
|
"eval" => { self.evaluator.set_option("trace_evaluation", show); },
|
||||||
"llvm" => self.show_llvm_ir = show,
|
"llvm" => self.show_llvm_ir = show,
|
||||||
e => {
|
e => {
|
||||||
println!("Bad `show`/`hide` argument: {}", e);
|
println!("Bad `show`/`hide` argument: {}", e);
|
||||||
|
@ -54,11 +54,6 @@ pub struct Evaluator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Evaluator<'a> {
|
impl<'a> Evaluator<'a> {
|
||||||
pub fn new_with_opts(parent: Option<&'a Evaluator>, trace_evaluation: bool) -> Evaluator<'a> {
|
|
||||||
let mut e = Evaluator::new(parent);
|
|
||||||
e.trace_evaluation = trace_evaluation;
|
|
||||||
e
|
|
||||||
}
|
|
||||||
pub fn new(parent: Option<&'a Evaluator>) -> Evaluator<'a> {
|
pub fn new(parent: Option<&'a Evaluator>) -> Evaluator<'a> {
|
||||||
Evaluator {
|
Evaluator {
|
||||||
variables: HashMap::new(),
|
variables: HashMap::new(),
|
||||||
|
@ -3,7 +3,9 @@ pub mod parser;
|
|||||||
pub mod eval;
|
pub mod eval;
|
||||||
pub mod compilation;
|
pub mod compilation;
|
||||||
|
|
||||||
use language::{ProgrammingLanguage, ParseError, TokenError, LLVMCodeString};
|
use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, LLVMCodeString};
|
||||||
|
|
||||||
|
pub use self::eval::Evaluator as SchalaEvaluator;
|
||||||
|
|
||||||
pub struct Schala { }
|
pub struct Schala { }
|
||||||
|
|
||||||
@ -26,3 +28,17 @@ impl<'a> ProgrammingLanguage<eval::Evaluator<'a>> for Schala {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EvaluationMachine for SchalaEvaluator<'a> {
|
||||||
|
fn set_option(&mut self, option: &str, value: bool) -> bool {
|
||||||
|
if option == "trace_evaluation" {
|
||||||
|
self.trace_evaluation = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> SchalaEvaluator<'a> {
|
||||||
|
SchalaEvaluator::new(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
use schala_lang::tokenizer::{Token, Kw, OpTok};
|
use schala_lang::tokenizer::{Token, Kw, OpTok};
|
||||||
use schala_lang::tokenizer::Token::*;
|
use schala_lang::tokenizer::Token::*;
|
||||||
use language::ProgrammingLanguage;
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -5,7 +5,7 @@ use std::str::Chars;
|
|||||||
use self::itertools::Itertools;
|
use self::itertools::Itertools;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use language::{TokenError, ProgrammingLanguage};
|
use language::TokenError;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
|
Loading…
Reference in New Issue
Block a user