Thread SchalaConfig for repl/non-repl in runner
This commit is contained in:
parent
d084deac80
commit
76f7524fdb
@ -31,4 +31,4 @@ mod identifier;
|
|||||||
|
|
||||||
mod schala;
|
mod schala;
|
||||||
|
|
||||||
pub use schala::Schala;
|
pub use schala::{Schala, SchalaConfig};
|
||||||
|
@ -57,7 +57,7 @@ impl<'a> Schala<'a> {
|
|||||||
let prelude = include_str!("../source-files/prelude.schala");
|
let prelude = include_str!("../source-files/prelude.schala");
|
||||||
let mut env = Schala::new_blank_env();
|
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 {
|
if let Err(err) = response {
|
||||||
panic!("Error in prelude, panicking: {}", err.display());
|
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.
|
/// This is where the actual action of interpreting/compilation happens.
|
||||||
/// Note: this should eventually use a query-based system for parallelization, cf.
|
/// Note: this should eventually use a query-based system for parallelization, cf.
|
||||||
/// https://rustc-dev-guide.rust-lang.org/overview.html
|
/// 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
|
// 1st stage - tokenization
|
||||||
// TODO tokenize should return its own error type
|
// TODO tokenize should return its own error type
|
||||||
let tokens = tokenizing::tokenize(source);
|
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 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>, String> = evaluation_outputs.into_iter().collect();
|
||||||
|
|
||||||
let text_output: Result<Vec<String>, SchalaError> =
|
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"]
|
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> {
|
impl<'a> ProgrammingLanguageInterface for Schala<'a> {
|
||||||
//TODO flesh out Config
|
//TODO flesh out Config
|
||||||
type Config = ();
|
type Config = SchalaConfig;
|
||||||
fn language_name() -> String {
|
fn language_name() -> String {
|
||||||
"Schala".to_owned()
|
"Schala".to_owned()
|
||||||
}
|
}
|
||||||
@ -161,7 +166,8 @@ impl<'a> ProgrammingLanguageInterface for Schala<'a> {
|
|||||||
self.source_reference.load_new_source(source);
|
self.source_reference.load_new_source(source);
|
||||||
let sw = Stopwatch::start_new();
|
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![] };
|
let global_output_stats = GlobalOutputStats { total_duration: sw.elapsed(), stage_durations: vec![] };
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ impl<'a, 'b> Evaluator<'a, 'b> {
|
|||||||
fn statement(&mut self, stmt: Statement) -> EvalResult<Option<MemoryValue>> {
|
fn statement(&mut self, stmt: Statement) -> EvalResult<Option<MemoryValue>> {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Binding { ref id, expr, constant: _ } => {
|
Statement::Binding { ref id, expr, constant: _ } => {
|
||||||
println!("eval() binding id: {}", id);
|
|
||||||
let evaluated = self.expression(expr)?;
|
let evaluated = self.expression(expr)?;
|
||||||
self.state.environments.insert(id.into(), evaluated.into());
|
self.state.environments.insert(id.into(), evaluated.into());
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
|||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
pub trait ProgrammingLanguageInterface {
|
pub trait ProgrammingLanguageInterface {
|
||||||
type Config: Default;
|
type Config: Default + Clone;
|
||||||
fn language_name() -> String;
|
fn language_name() -> String;
|
||||||
fn source_file_suffix() -> String;
|
fn source_file_suffix() -> String;
|
||||||
|
|
||||||
|
@ -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!("Schala meta-interpeter version {}", VERSION_STRING);
|
||||||
println!(
|
println!(
|
||||||
"Type {} for help with the REPL",
|
"Type {} for help with the REPL",
|
||||||
format!("{}help", self.sigil).bright_green().bold()
|
format!("{}help", self.sigil).bright_green().bold()
|
||||||
);
|
);
|
||||||
self.load_options();
|
self.load_options();
|
||||||
self.handle_repl_loop();
|
self.handle_repl_loop(config);
|
||||||
self.save_before_exit();
|
self.save_before_exit();
|
||||||
println!("Exiting...");
|
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::*;
|
use linefeed::ReadResult::*;
|
||||||
|
|
||||||
'main: loop {
|
'main: loop {
|
||||||
@ -128,7 +128,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
|
|||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.handle_input(&buf)
|
self.handle_input(&buf, &config)
|
||||||
} else {
|
} else {
|
||||||
if let Some(output) = self.handle_interpreter_directive(input.get(1..).unwrap()) {
|
if let Some(output) = self.handle_interpreter_directive(input.get(1..).unwrap()) {
|
||||||
println!("{}", output);
|
println!("{}", output);
|
||||||
@ -136,7 +136,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self.handle_input(input),
|
_ => self.handle_input(input, &config),
|
||||||
};
|
};
|
||||||
|
|
||||||
for repl_response in repl_responses.iter() {
|
for repl_response in repl_responses.iter() {
|
||||||
@ -179,7 +179,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
|
|||||||
directives.perform(self, &arguments)
|
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();
|
let mut debug_requests = HashSet::new();
|
||||||
for ask in self.options.debug_asks.iter() {
|
for ask in self.options.debug_asks.iter() {
|
||||||
debug_requests.insert(ask.clone());
|
debug_requests.insert(ask.clone());
|
||||||
@ -187,7 +187,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
|
|||||||
|
|
||||||
let request = ComputationRequest {
|
let request = ComputationRequest {
|
||||||
source: input,
|
source: input,
|
||||||
config: Default::default(),
|
config: config.clone(),
|
||||||
debug_requests,
|
debug_requests,
|
||||||
};
|
};
|
||||||
let response = self.language_state.run_computation(request);
|
let response = self.language_state.run_computation(request);
|
||||||
|
15
src/main.rs
15
src/main.rs
@ -1,7 +1,7 @@
|
|||||||
use schala_repl::{Repl, ProgrammingLanguageInterface, ComputationRequest};
|
use schala_repl::{Repl, ProgrammingLanguageInterface, ComputationRequest};
|
||||||
|
|
||||||
use std::{fs::File, io::Read, path::PathBuf, process::exit, collections::HashSet};
|
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
|
//TODO specify multiple langs, and have a way to switch between them
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -21,7 +21,8 @@ fn main() {
|
|||||||
if matches.free.is_empty() {
|
if matches.free.is_empty() {
|
||||||
let state = Schala::new();
|
let state = Schala::new();
|
||||||
let mut repl = Repl::new(state);
|
let mut repl = Repl::new(state);
|
||||||
repl.run_repl();
|
let config = SchalaConfig { repl: true };
|
||||||
|
repl.run_repl(config);
|
||||||
} else {
|
} else {
|
||||||
let paths: Vec<PathBuf> = matches.free.iter().map(PathBuf::from).collect();
|
let paths: Vec<PathBuf> = matches.free.iter().map(PathBuf::from).collect();
|
||||||
//TODO handle more than one file
|
//TODO handle more than one file
|
||||||
@ -34,7 +35,11 @@ fn main() {
|
|||||||
|
|
||||||
//TODO this proably should be a macro for every supported language
|
//TODO this proably should be a macro for every supported language
|
||||||
if extension == Schala::source_file_suffix() {
|
if extension == Schala::source_file_suffix() {
|
||||||
run_noninteractive(paths, Schala::new());
|
let config = SchalaConfig {
|
||||||
|
repl: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
run_noninteractive(paths, Schala::new(), config);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Extension .{} not recognized", extension);
|
eprintln!("Extension .{} not recognized", extension);
|
||||||
exit(1);
|
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
|
// for now, ony do something with the first filename
|
||||||
|
|
||||||
let filename = &filenames[0];
|
let filename = &filenames[0];
|
||||||
@ -52,7 +57,7 @@ pub fn run_noninteractive<L: ProgrammingLanguageInterface>(filenames: Vec<PathBu
|
|||||||
|
|
||||||
let request = ComputationRequest {
|
let request = ComputationRequest {
|
||||||
source: &buffer,
|
source: &buffer,
|
||||||
config: Default::default(),
|
config,
|
||||||
debug_requests: HashSet::new(),
|
debug_requests: HashSet::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user