diff --git a/schala-lib/src/language.rs b/schala-lib/src/language.rs index 6c9e531..8a90059 100644 --- a/schala-lib/src/language.rs +++ b/schala-lib/src/language.rs @@ -7,6 +7,9 @@ pub struct LLVMCodeString(pub String); #[derive(Debug, Default, Serialize, Deserialize)] pub struct EvalOptions { + pub debug: DebugOptions, + pub execution_method: ExecutionMethod + /* pub debug_tokens: bool, pub debug_parse: bool, pub debug_type: bool, @@ -14,6 +17,28 @@ pub struct EvalOptions { pub show_llvm_ir: bool, pub trace_evaluation: bool, pub compile: bool, + */ +} +#[derive(Debug, Serialize, Deserialize)] +pub enum ExecutionMethod { + Compile, + Interpret, +} +impl Default for ExecutionMethod { + fn default() -> ExecutionMethod { + ExecutionMethod::Interpret + } +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct DebugOptions { + pub tokens: bool, + pub parse_tree: bool, + pub ast: bool, + pub type_checking: bool, + pub symbol_table: bool, + pub evaluation: bool, + pub llvm_ir: bool, } #[derive(Debug, Default)] @@ -76,23 +101,20 @@ impl UnfinishedComputation { } impl FinishedComputation { - pub fn to_string(&self) -> String { + pub fn to_repl(&self) -> String { match self.text_output { Ok(ref s) => s.clone(), Err(ref s) => format!("Error: {}", s) } } + pub fn to_noninteractive(&self) -> Option { + match self.text_output { + Ok(ref s) => None, + Err(ref s) => Some(format!("Error: {}", s)), + } + } } -/* -//TODO I'll probably wanna implement this later -#[derive(Debug)] -pub struct CompilationOutput { - output: LLVMCodeString, - artifacts: Vec, -} -*/ - #[derive(Debug)] pub struct TraceArtifact { stage_name: String, @@ -124,14 +146,17 @@ impl TraceArtifact { } pub trait ProgrammingLanguageInterface { + /* old */ fn evaluate_in_repl(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput { LanguageOutput { output: format!("Defunct"), artifacts: vec![], failed: false } } fn evaluate_noninteractive(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput { self.evaluate_in_repl(input, eval_options) } + /* old */ - fn repl_evaluate(&mut self, input: &str, eval_options: &EvalOptions) -> FinishedComputation { + + fn execute(&mut self, input: &str, eval_options: &EvalOptions) -> FinishedComputation { FinishedComputation { artifacts: HashMap::new(), text_output: Err(format!("REPL evaluation not implemented")) } } fn get_language_name(&self) -> String; diff --git a/schala-lib/src/lib.rs b/schala-lib/src/lib.rs index f41436b..cbe1c10 100644 --- a/schala-lib/src/lib.rs +++ b/schala-lib/src/lib.rs @@ -5,6 +5,7 @@ extern crate getopts; extern crate rustyline; extern crate itertools; + #[macro_use] extern crate lazy_static; #[macro_use] @@ -32,7 +33,7 @@ pub mod llvm_wrap; include!(concat!(env!("OUT_DIR"), "/static.rs")); -pub use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, LLVMCodeString, FinishedComputation, UnfinishedComputation}; +pub use language::{ProgrammingLanguageInterface, EvalOptions, ExecutionMethod, TraceArtifact, LanguageOutput, LLVMCodeString, FinishedComputation, UnfinishedComputation}; pub type PLIGenerator = Box Box + Send + Sync>; pub fn schala_main(generators: Vec) { @@ -67,15 +68,14 @@ pub fn schala_main(generators: Vec) { .unwrap_or(0); let mut options = EvalOptions::default(); - options.compile = match option_matches.opt_str("eval-style") { - Some(ref s) if s == "compile" => true, - _ => false + options.execution_method = match option_matches.opt_str("eval-style") { + Some(ref s) if s == "compile" => ExecutionMethod::Compile, + _ => ExecutionMethod::Interpret, }; match option_matches.free[..] { [] | [_] => { let mut repl = Repl::new(languages, initial_index); - repl.options.show_llvm_ir = true; //TODO make this be configurable repl.run(); } [_, ref filename, _..] => { @@ -102,17 +102,17 @@ fn run_noninteractive(filename: &str, languages: Vec { + /* let llvm_bytecode = language.compile(&buffer); compilation_sequence(llvm_bytecode, filename); - } - } else { - let output = language.evaluate_in_repl(&buffer, &options); - if output.failed { - println!("{}", output.to_string()); + */ + panic!("Not ready to go yet"); + }, + ExecutionMethod::Interpret => { + let output = language.execute(&buffer, &options); + output.to_noninteractive().map(|text| println!("{}", text)); } } } @@ -198,8 +198,8 @@ impl Repl { fn input_handler(&mut self, input: &str) -> String { let ref mut language = self.languages[self.current_language_index]; - let interpreter_output = language.repl_evaluate(input, &self.options); - interpreter_output.to_string() + let interpreter_output = language.execute(input, &self.options); + interpreter_output.to_repl() } fn handle_interpreter_directive(&mut self, input: &str) -> bool { @@ -285,14 +285,11 @@ impl Repl { } }; match commands.get(2) { - Some(&"tokens") => self.options.debug_tokens = show, - Some(&"parse") => self.options.debug_parse = show, - Some(&"symbols") => self.options.debug_symbol_table = show, - Some(&"eval") => { - //let ref mut language = self.languages[self.current_language_index]; - //language.set_option("trace_evaluation", show); - }, - Some(&"llvm") => self.options.show_llvm_ir = show, + Some(&"tokens") => self.options.debug.tokens = show, + Some(&"parse") => self.options.debug.parse_tree = show, + Some(&"ast") => self.options.debug.ast = show, + Some(&"symbols") => self.options.debug.symbol_table = show, + Some(&"llvm") => self.options.debug.llvm_ir = show, Some(e) => { println!("Bad `show`/`hide` argument: {}", e); return true; diff --git a/src/maaru_lang/mod.rs b/src/maaru_lang/mod.rs index 37ab100..c1b784e 100644 --- a/src/maaru_lang/mod.rs +++ b/src/maaru_lang/mod.rs @@ -43,7 +43,7 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> { let tokens = match tokenizer::tokenize(input) { Ok(tokens) => { - if options.debug_tokens { + if options.debug.tokens { output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens))); } tokens @@ -56,7 +56,7 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> { let ast = match parser::parse(&tokens, &[]) { Ok(ast) => { - if options.debug_parse { + if options.debug.ast { output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); } ast diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index 0392559..533436e 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, UnfinishedComputation, FinishedComputation}; +use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, UnfinishedComputation, FinishedComputation}; macro_rules! bx { ($e:expr) => { Box::new($e) } @@ -12,7 +12,6 @@ mod parsing; mod typechecking; mod eval; - use self::typechecking::{TypeContext}; pub struct Schala { @@ -38,7 +37,7 @@ impl ProgrammingLanguageInterface for Schala { format!("schala") } - fn repl_evaluate(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation { + fn execute(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation { let mut evaluation = UnfinishedComputation::default(); //tokenzing