Thread SchalaConfig for repl/non-repl in runner

This commit is contained in:
Greg Shuflin 2021-10-31 03:30:45 -07:00
parent d084deac80
commit 76f7524fdb
6 changed files with 30 additions and 20 deletions

View File

@ -31,4 +31,4 @@ mod identifier;
mod schala;
pub use schala::Schala;
pub use schala::{Schala, SchalaConfig};

View File

@ -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<String, SchalaError> {
fn run_pipeline(&mut self, source: &str, config: SchalaConfig) -> Result<String, SchalaError> {
// 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<Vec<String>, String> = evaluation_outputs.into_iter().collect();
let text_output: Result<Vec<String>, 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![] };

View File

@ -50,7 +50,6 @@ impl<'a, 'b> Evaluator<'a, 'b> {
fn statement(&mut self, stmt: Statement) -> EvalResult<Option<MemoryValue>> {
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)

View File

@ -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;

View File

@ -66,14 +66,14 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
}
}
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<L: ProgrammingLanguageInterface> Repl<L> {
}
}
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<L: ProgrammingLanguageInterface> Repl<L> {
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<L: ProgrammingLanguageInterface> Repl<L> {
continue;
}
}
_ => self.handle_input(input),
_ => self.handle_input(input, &config),
};
for repl_response in repl_responses.iter() {
@ -179,7 +179,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
directives.perform(self, &arguments)
}
fn handle_input(&mut self, input: &str) -> Vec<ReplResponse> {
fn handle_input(&mut self, input: &str, config: &L::Config) -> Vec<ReplResponse> {
let mut debug_requests = HashSet::new();
for ask in self.options.debug_asks.iter() {
debug_requests.insert(ask.clone());
@ -187,7 +187,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
let request = ComputationRequest {
source: input,
config: Default::default(),
config: config.clone(),
debug_requests,
};
let response = self.language_state.run_computation(request);

View File

@ -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<PathBuf> = 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<L: ProgrammingLanguageInterface>(filenames: Vec<PathBuf>, mut language: L) {
pub fn run_noninteractive<L: ProgrammingLanguageInterface>(filenames: Vec<PathBuf>, 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<L: ProgrammingLanguageInterface>(filenames: Vec<PathBu
let request = ComputationRequest {
source: &buffer,
config: Default::default(),
config,
debug_requests: HashSet::new(),
};