diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index c5675d7..d024369 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -31,4 +31,4 @@ mod identifier; mod schala; -pub use schala::Schala; +pub use schala::{Schala, SchalaConfig}; diff --git a/schala-lang/language/src/schala.rs b/schala-lang/language/src/schala.rs index 5751137..90e350f 100644 --- a/schala-lang/language/src/schala.rs +++ b/schala-lang/language/src/schala.rs @@ -57,7 +57,7 @@ impl<'a> Schala<'a> { let prelude = include_str!("../source-files/prelude.schala"); let mut env = Schala::new_blank_env(); - let response = env.run_pipeline(prelude); + let response = env.run_pipeline(prelude, SchalaConfig::default()); if let Err(err) = response { panic!("Error in prelude, panicking: {}", err.display()); } @@ -67,7 +67,7 @@ impl<'a> Schala<'a> { /// This is where the actual action of interpreting/compilation happens. /// Note: this should eventually use a query-based system for parallelization, cf. /// https://rustc-dev-guide.rust-lang.org/overview.html - fn run_pipeline(&mut self, source: &str) -> Result { + fn run_pipeline(&mut self, source: &str, config: SchalaConfig) -> Result { // 1st stage - tokenization // TODO tokenize should return its own error type let tokens = tokenizing::tokenize(source); @@ -93,7 +93,7 @@ impl<'a> Schala<'a> { let reduced_ir = reduced_ir::reduce(&ast, &self.symbol_table, &self.type_context); - let evaluation_outputs = self.eval_state.evaluate(reduced_ir, &self.type_context, true); + let evaluation_outputs = self.eval_state.evaluate(reduced_ir, &self.type_context, config.repl); let text_output: Result, String> = evaluation_outputs.into_iter().collect(); let text_output: Result, SchalaError> = @@ -145,9 +145,14 @@ fn stage_names() -> Vec<&'static str> { vec!["tokenizing", "parsing", "symbol-table", "typechecking", "ast-reduction", "ast-walking-evaluation"] } +#[derive(Default, Clone)] +pub struct SchalaConfig { + pub repl: bool, +} + impl<'a> ProgrammingLanguageInterface for Schala<'a> { //TODO flesh out Config - type Config = (); + type Config = SchalaConfig; fn language_name() -> String { "Schala".to_owned() } @@ -161,7 +166,8 @@ impl<'a> ProgrammingLanguageInterface for Schala<'a> { self.source_reference.load_new_source(source); let sw = Stopwatch::start_new(); - let main_output = self.run_pipeline(source).map_err(|schala_err| schala_err.display()); + let main_output = + self.run_pipeline(source, request.config).map_err(|schala_err| schala_err.display()); let global_output_stats = GlobalOutputStats { total_duration: sw.elapsed(), stage_durations: vec![] }; diff --git a/schala-lang/language/src/tree_walk_eval/evaluator.rs b/schala-lang/language/src/tree_walk_eval/evaluator.rs index 8760f79..734a79f 100644 --- a/schala-lang/language/src/tree_walk_eval/evaluator.rs +++ b/schala-lang/language/src/tree_walk_eval/evaluator.rs @@ -50,7 +50,6 @@ impl<'a, 'b> Evaluator<'a, 'b> { fn statement(&mut self, stmt: Statement) -> EvalResult> { match stmt { Statement::Binding { ref id, expr, constant: _ } => { - println!("eval() binding id: {}", id); let evaluated = self.expression(expr)?; self.state.environments.insert(id.into(), evaluated.into()); Ok(None) diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index d205446..eb11629 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::time; pub trait ProgrammingLanguageInterface { - type Config: Default; + type Config: Default + Clone; fn language_name() -> String; fn source_file_suffix() -> String; diff --git a/schala-repl/src/lib.rs b/schala-repl/src/lib.rs index fc75deb..72cddb0 100644 --- a/schala-repl/src/lib.rs +++ b/schala-repl/src/lib.rs @@ -66,14 +66,14 @@ impl Repl { } } - pub fn run_repl(&mut self) { + pub fn run_repl(&mut self, config: L::Config) { println!("Schala meta-interpeter version {}", VERSION_STRING); println!( "Type {} for help with the REPL", format!("{}help", self.sigil).bright_green().bold() ); self.load_options(); - self.handle_repl_loop(); + self.handle_repl_loop(config); self.save_before_exit(); println!("Exiting..."); } @@ -90,7 +90,7 @@ impl Repl { } } - fn handle_repl_loop(&mut self) { + fn handle_repl_loop(&mut self, config: L::Config) { use linefeed::ReadResult::*; 'main: loop { @@ -128,7 +128,7 @@ impl Repl { buf.push('\n'); } } - self.handle_input(&buf) + self.handle_input(&buf, &config) } else { if let Some(output) = self.handle_interpreter_directive(input.get(1..).unwrap()) { println!("{}", output); @@ -136,7 +136,7 @@ impl Repl { continue; } } - _ => self.handle_input(input), + _ => self.handle_input(input, &config), }; for repl_response in repl_responses.iter() { @@ -179,7 +179,7 @@ impl Repl { directives.perform(self, &arguments) } - fn handle_input(&mut self, input: &str) -> Vec { + fn handle_input(&mut self, input: &str, config: &L::Config) -> Vec { let mut debug_requests = HashSet::new(); for ask in self.options.debug_asks.iter() { debug_requests.insert(ask.clone()); @@ -187,7 +187,7 @@ impl Repl { let request = ComputationRequest { source: input, - config: Default::default(), + config: config.clone(), debug_requests, }; let response = self.language_state.run_computation(request); diff --git a/src/main.rs b/src/main.rs index af17153..6caa217 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use schala_repl::{Repl, ProgrammingLanguageInterface, ComputationRequest}; use std::{fs::File, io::Read, path::PathBuf, process::exit, collections::HashSet}; -use schala_lang::Schala; +use schala_lang::{Schala, SchalaConfig}; //TODO specify multiple langs, and have a way to switch between them fn main() { @@ -21,7 +21,8 @@ fn main() { if matches.free.is_empty() { let state = Schala::new(); let mut repl = Repl::new(state); - repl.run_repl(); + let config = SchalaConfig { repl: true }; + repl.run_repl(config); } else { let paths: Vec = matches.free.iter().map(PathBuf::from).collect(); //TODO handle more than one file @@ -34,7 +35,11 @@ fn main() { //TODO this proably should be a macro for every supported language if extension == Schala::source_file_suffix() { - run_noninteractive(paths, Schala::new()); + let config = SchalaConfig { + repl: false, + }; + + run_noninteractive(paths, Schala::new(), config); } else { eprintln!("Extension .{} not recognized", extension); exit(1); @@ -42,7 +47,7 @@ fn main() { } } -pub fn run_noninteractive(filenames: Vec, mut language: L) { +pub fn run_noninteractive(filenames: Vec, mut language: L, config: L::Config) { // for now, ony do something with the first filename let filename = &filenames[0]; @@ -52,7 +57,7 @@ pub fn run_noninteractive(filenames: Vec