From 1622a6ce44ca59bd4c4207ba34017bad7cb43c94 Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 14 Mar 2019 00:51:33 -0700 Subject: [PATCH] Grand culling Deleting a bunch of old code related to the old way the interpreter worked --- Cargo.toml | 2 - maaru/src/lib.rs | 72 ++++++------ robo/src/lib.rs | 14 +-- rukka/src/lib.rs | 20 +--- schala-lang/language/Cargo.toml | 1 - schala-lang/language/src/lib.rs | 2 - schala-repl-codegen/Cargo.toml | 13 --- schala-repl-codegen/src/lib.rs | 199 -------------------------------- schala-repl/src/language.rs | 175 ++++------------------------ schala-repl/src/lib.rs | 127 +++----------------- schala-repl/src/repl/mod.rs | 161 +++++++------------------- schala-repl/src/webapp.rs | 11 +- src/main.rs | 2 +- 13 files changed, 122 insertions(+), 677 deletions(-) delete mode 100644 schala-repl-codegen/Cargo.toml delete mode 100644 schala-repl-codegen/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index f7a8b12..2e14890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,10 @@ authors = ["greg "] [dependencies] schala-repl = { path = "schala-repl" } -schala-repl-codegen = { path = "schala-repl-codegen" } maaru-lang = { path = "maaru" } rukka-lang = { path = "rukka" } robo-lang = { path = "robo" } schala-lang = { path = "schala-lang/language" } -schala-lang-codegen = { path = "schala-lang/codegen" } [build-dependencies] includedir_codegen = "0.2.0" diff --git a/maaru/src/lib.rs b/maaru/src/lib.rs index b9c00d6..c9056e5 100644 --- a/maaru/src/lib.rs +++ b/maaru/src/lib.rs @@ -6,8 +6,6 @@ mod tokenizer; mod parser; mod eval; -use schala_repl::{ProgrammingLanguageInterface, EvalOptions, UnfinishedComputation, FinishedComputation, TraceArtifact}; - #[derive(Debug)] pub struct TokenError { pub msg: String, @@ -33,6 +31,42 @@ impl<'a> Maaru<'a> { } } +/* +fn execute_pipeline(&mut self, input: &str, options: &EvalOptions) -> Result { + let mut output = UnfinishedComputation::default(); + + let tokens = match tokenizer::tokenize(input) { + Ok(tokens) => { + if let Some(_) = options.debug_passes.get("tokens") { + output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens))); + } + tokens + }, + Err(err) => { + return output.finish(Err(format!("Tokenization error: {:?}\n", err.msg))) + } + }; + + let ast = match parser::parse(&tokens, &[]) { + Ok(ast) => { + if let Some(_) = options.debug_passes.get("ast") { + output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); + } + ast + }, + Err(err) => { + return output.finish(Err(format!("Parse error: {:?}\n", err.msg))) + } + }; + let mut evaluation_output = String::new(); + for s in self.evaluator.run(ast).iter() { + evaluation_output.push_str(s); + } + Ok(evaluation_output) +} +*/ + +/* impl<'a> ProgrammingLanguageInterface for Maaru<'a> { fn get_language_name(&self) -> String { "Maaru".to_string() @@ -40,37 +74,5 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> { fn get_source_file_suffix(&self) -> String { format!("maaru") } - - fn execute_pipeline(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation { - let mut output = UnfinishedComputation::default(); - - let tokens = match tokenizer::tokenize(input) { - Ok(tokens) => { - if let Some(_) = options.debug_passes.get("tokens") { - output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens))); - } - tokens - }, - Err(err) => { - return output.finish(Err(format!("Tokenization error: {:?}\n", err.msg))) - } - }; - - let ast = match parser::parse(&tokens, &[]) { - Ok(ast) => { - if let Some(_) = options.debug_passes.get("ast") { - output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); - } - ast - }, - Err(err) => { - return output.finish(Err(format!("Parse error: {:?}\n", err.msg))) - } - }; - let mut evaluation_output = String::new(); - for s in self.evaluator.run(ast).iter() { - evaluation_output.push_str(s); - } - output.finish(Ok(evaluation_output)) - } } + */ diff --git a/robo/src/lib.rs b/robo/src/lib.rs index f6cf2b1..d87afab 100644 --- a/robo/src/lib.rs +++ b/robo/src/lib.rs @@ -4,7 +4,7 @@ extern crate itertools; extern crate schala_repl; use itertools::Itertools; -use schala_repl::{ProgrammingLanguageInterface, EvalOptions, FinishedComputation, UnfinishedComputation}; +use schala_repl::{ProgrammingLanguageInterface, EvalOptions}; pub struct Robo { } @@ -154,17 +154,5 @@ impl ProgrammingLanguageInterface for Robo { fn get_source_file_suffix(&self) -> String { format!("robo") } - - fn execute_pipeline(&mut self, input: &str, _eval_options: &EvalOptions) -> FinishedComputation { - let output = UnfinishedComputation::default(); - let tokens = match tokenize(input) { - Ok(tokens) => tokens, - Err(e) => { - return output.finish(Err(format!("Tokenize error: {:?}", e))); - } - }; - - output.finish(Ok(format!("{:?}", tokens))) - } } diff --git a/rukka/src/lib.rs b/rukka/src/lib.rs index 6332ed3..854e559 100644 --- a/rukka/src/lib.rs +++ b/rukka/src/lib.rs @@ -4,7 +4,7 @@ extern crate itertools; extern crate schala_repl; use itertools::Itertools; -use schala_repl::{ProgrammingLanguageInterface, EvalOptions, UnfinishedComputation, FinishedComputation}; +use schala_repl::{ProgrammingLanguageInterface, EvalOptions}; use std::iter::Peekable; use std::vec::IntoIter; use std::str::Chars; @@ -72,24 +72,6 @@ impl ProgrammingLanguageInterface for Rukka { fn get_source_file_suffix(&self) -> String { format!("rukka") } - - fn execute_pipeline(&mut self, input: &str, _eval_options: &EvalOptions) -> FinishedComputation { - let output = UnfinishedComputation::default(); - let sexps = match read(input) { - Err(err) => { - return output.finish(Err(format!("Error: {}", err))); - }, - Ok(sexps) => sexps - }; - - let output_str: String = sexps.into_iter().enumerate().map(|(i, sexp)| { - match self.state.eval(sexp) { - Ok(result) => format!("{}: {}", i, result.print()), - Err(err) => format!("{} Error: {}", i, err), - } - }).intersperse(format!("\n")).collect(); - output.finish(Ok(output_str)) - } } impl EvaluatorState { diff --git a/schala-lang/language/Cargo.toml b/schala-lang/language/Cargo.toml index a210754..733e168 100644 --- a/schala-lang/language/Cargo.toml +++ b/schala-lang/language/Cargo.toml @@ -15,4 +15,3 @@ ena = "0.11.0" schala-lang-codegen = { path = "../codegen" } schala-repl = { path = "../../schala-repl" } -schala-repl-codegen = { path = "../../schala-repl-codegen" } diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 4cda23d..9efbff6 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -14,8 +14,6 @@ extern crate lazy_static; extern crate maplit; extern crate schala_repl; #[macro_use] -extern crate schala_repl_codegen; -#[macro_use] extern crate schala_lang_codegen; extern crate ena; diff --git a/schala-repl-codegen/Cargo.toml b/schala-repl-codegen/Cargo.toml deleted file mode 100644 index a1b561c..0000000 --- a/schala-repl-codegen/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "schala-repl-codegen" -version = "0.1.0" -authors = ["greg "] - -[dependencies] -syn = { version = "0.15.6", features = ["full", "extra-traits"] } -quote = "0.6.8" -proc-macro2 = "0.4.19" -schala-repl = { path = "../schala-repl" } - -[lib] -proc-macro = true diff --git a/schala-repl-codegen/src/lib.rs b/schala-repl-codegen/src/lib.rs deleted file mode 100644 index 8112f91..0000000 --- a/schala-repl-codegen/src/lib.rs +++ /dev/null @@ -1,199 +0,0 @@ -#![feature(trace_macros)] -#![recursion_limit="128"] -extern crate proc_macro; -extern crate proc_macro2; -#[macro_use] -extern crate quote; -extern crate syn; - -use proc_macro::TokenStream; -use syn::{Ident, Attribute, DeriveInput}; - -fn find_attr_by_name<'a>(name: &str, attrs: &'a Vec) -> Option<&'a Attribute> { - attrs.iter().find(|attr| { - let first = attr.path.segments.first(); - let seg: Option<&&syn::PathSegment> = first.as_ref().map(|x| x.value()); - seg.map(|seg| seg.ident.to_string() == name).unwrap_or(false) - }) -} - -fn extract_attribute_arg_by_name(name: &str, attrs: &Vec) -> Option { - use syn::{Meta, Lit, MetaNameValue}; - find_attr_by_name(name, attrs) - .and_then(|attr| { - match attr.interpret_meta() { - Some(Meta::NameValue(MetaNameValue { lit: Lit::Str(litstr), .. })) => Some(litstr.value()), - _ => None, - } - }) -} - -fn extract_attribute_list(name: &str, attrs: &Vec) -> Option>)>> { - use syn::{Meta, MetaList, NestedMeta}; - find_attr_by_name(name, attrs) - .and_then(|attr| { - match attr.interpret_meta() { - Some(Meta::List(MetaList { nested, .. })) => { - Some(nested.iter().map(|nested_meta| match nested_meta { - &NestedMeta::Meta(Meta::Word(ref ident)) => (ident.clone(), None), - &NestedMeta::Meta(Meta::List(MetaList { ref ident, nested: ref nested2, .. })) => { - let own_args = nested2.iter().map(|nested_meta2| match nested_meta2 { - &NestedMeta::Meta(Meta::Word(ref ident)) => ident.clone(), - _ => panic!("Bad format for doubly-nested attribute list") - }).collect(); - (ident.clone(), Some(own_args)) - }, - _ => panic!("Bad format for nested list") - }).collect()) - }, - _ => panic!("{} must be a comma-delimited list surrounded by parens", name) - } - }) -} - -fn get_attribute_identifier(attr_name: &str, attrs: &Vec) -> Option { - find_attr_by_name(attr_name, attrs).and_then(|attr| { - let tts = attr.tts.clone().into_iter().collect::>(); - - if tts.len() == 2 { - let ref after_equals: proc_macro2::TokenTree = tts[1]; - match after_equals { - proc_macro2::TokenTree::Ident(ident) => Some(ident.clone()), - _ => None - } - } else { - None - } - }) -} - -/* a pass_chain function signature with input A and output B looks like: - * fn(A, &mut ProgrammingLanguageInterface, Option<&mut DebugHandler>) -> Result - * - * TODO use some kind of failure-handling library to make this better - */ -fn generate_pass_chain(idents: Vec) -> proc_macro2::TokenStream { - let final_return = quote! { - { - let final_output: FinishedComputation = unfinished_computation.finish(Ok(input_to_next_stage)); - final_output - } - }; - - let nested_passes = idents.iter() - .rev() - .fold(final_return, |later_fragment, pass_name| { - quote! { - { - let pass_name = stringify!(#pass_name); - let (output, duration) = { - let ref debug_map = eval_options.debug_passes; - let debug_handle = match debug_map.get(pass_name) { - Some(PassDebugOptionsDescriptor { opts }) => { - let ptr = &mut unfinished_computation; - ptr.cur_debug_options = opts.clone(); - Some(ptr) - } - _ => None - }; - let start = time::Instant::now(); - let pass_output = #pass_name(input_to_next_stage, self, debug_handle); - let elapsed = start.elapsed(); - (pass_output, elapsed) - }; - if eval_options.debug_timing { - unfinished_computation.durations.push(duration); - } - match output { - Ok(input_to_next_stage) => #later_fragment, - //TODO this error type needs to be guaranteed to provide a useable string - Err(err) => return unfinished_computation.output(Err(format!("Pass {} failed:\n{}", pass_name, err))), - } - } - } - }); - - quote! { - { - use std::time; - use schala_repl::PassDebugOptionsDescriptor; - - let eval_options = options; - let input_to_next_stage = input; - let mut unfinished_computation = UnfinishedComputation::default(); - #nested_passes - } - } -} - -#[proc_macro_derive(ProgrammingLanguageInterface, - attributes(LanguageName, SourceFileExtension, PipelineSteps, DocMethod, HandleCustomInterpreterDirectives))] -pub fn derive_programming_language_interface(input: TokenStream) -> TokenStream { - let ast: DeriveInput = syn::parse(input).unwrap(); - let name = &ast.ident; - let attrs = &ast.attrs; - - let language_name: String = extract_attribute_arg_by_name("LanguageName", attrs).expect("LanguageName is required"); - let file_ext = extract_attribute_arg_by_name("SourceFileExtension", attrs).expect("SourceFileExtension is required"); - let passes = extract_attribute_list("PipelineSteps", attrs).expect("PipelineSteps are required"); - let pass_idents = passes.iter().map(|x| x.0.clone()); - - let get_doc_impl = match get_attribute_identifier("DocMethod", attrs) { - None => quote! { }, - Some(method_name) => quote! { - fn get_doc(&self, commands: &Vec<&str>) -> Option { - self.#method_name(commands) - } - } - }; - - let handle_custom_interpreter_directives_impl = match get_attribute_identifier("HandleCustomInterpreterDirectives", attrs) { - None => quote! { }, - Some(method_name) => quote! { - fn handle_custom_interpreter_directives(&mut self, commands: &Vec<&str>) -> Option { - //println!("If #method_name is &self not &mut self, this runs forever"); - self.#method_name(commands) - } - } - }; - - let pass_descriptors = passes.iter().map(|pass| { - let name = pass.0.to_string(); - let opts: Vec = match &pass.1 { - None => vec![], - Some(opts) => opts.iter().map(|o| o.to_string()).collect(), - }; - - quote! { - PassDescriptor { - name: #name.to_string(), - debug_options: vec![#(format!(#opts)),*] - } - } - }); - - let pass_chain = generate_pass_chain(pass_idents.collect()); - - let tokens = quote! { - use schala_repl::PassDescriptor; - impl ProgrammingLanguageInterface for #name { - fn get_language_name(&self) -> String { - #language_name.to_string() - } - fn get_source_file_suffix(&self) -> String { - #file_ext.to_string() - } - fn execute_pipeline(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation { - #pass_chain - } - fn get_passes(&self) -> Vec { - vec![ #(#pass_descriptors),* ] - } - #get_doc_impl - #handle_custom_interpreter_directives_impl - } - }; - - let output: TokenStream = tokens.into(); - output -} diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index 203eaa8..1d532ce 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -1,24 +1,10 @@ use std::collections::HashMap; use colored::*; -use std::fmt::Write; use std::time; #[derive(Debug, Default, Serialize, Deserialize)] pub struct EvalOptions { pub execution_method: ExecutionMethod, - pub debug_passes: HashMap, - pub debug_timing: bool, -} - -#[derive(Debug, Hash, PartialEq)] -pub struct PassDescriptor { - pub name: String, - pub debug_options: Vec -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct PassDebugOptionsDescriptor { - pub opts: Vec, } #[derive(Debug, Serialize, Deserialize)] @@ -32,149 +18,9 @@ impl Default for ExecutionMethod { } } -#[derive(Debug, Default)] -pub struct UnfinishedComputation { - artifacts: Vec<(String, TraceArtifact)>, - pub durations: Vec, - pub cur_debug_options: Vec, -} - -#[derive(Debug)] -pub struct FinishedComputation { - artifacts: Vec<(String, TraceArtifact)>, - durations: Vec, - text_output: Result, -} - -impl UnfinishedComputation { - pub fn add_artifact(&mut self, artifact: TraceArtifact) { - self.artifacts.push((artifact.stage_name.clone(), artifact)); - } - pub fn finish(self, text_output: Result) -> FinishedComputation { - FinishedComputation { - artifacts: self.artifacts, - text_output, - durations: self.durations, - } - } - pub fn output(self, output: Result) -> FinishedComputation { - FinishedComputation { - artifacts: self.artifacts, - text_output: output, - durations: self.durations, - } - } -} - -impl FinishedComputation { - - fn get_timing(&self) -> Option { - if self.durations.len() != 0 { - let mut buf = String::new(); - write!(&mut buf, "Timing: ").unwrap(); - for duration in self.durations.iter() { - let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9); - write!(&mut buf, "{}s, ", timing).unwrap() - } - write!(&mut buf, "\n").unwrap(); - Some(buf) - } else { - None - } - } - - pub fn to_repl(&self) -> String { - let mut buf = String::new(); - for (stage, artifact) in self.artifacts.iter() { - let color = artifact.text_color; - let stage = stage.color(color).bold(); - let output = artifact.debug_output.color(color); - write!(&mut buf, "{}: {}\n", stage, output).unwrap(); - } - - match self.get_timing() { - Some(timing) => write!(&mut buf, "{}", timing).unwrap(), - None => () - } - - match self.text_output { - Ok(ref output) => write!(&mut buf, "{}", output).unwrap(), - Err(ref err) => write!(&mut buf, "{} {}", "Error: ".red().bold(), err).unwrap(), - } - buf - } - pub fn to_noninteractive(&self) -> Option { - match self.text_output { - Ok(_) => { - let mut buf = String::new(); - for (stage, artifact) in self.artifacts.iter() { - let color = artifact.text_color; - let stage = stage.color(color).bold(); - let output = artifact.debug_output.color(color); - write!(&mut buf, "{}: {}\n", stage, output).unwrap(); - } - if buf == "" { None } else { Some(buf) } - }, - Err(ref s) => Some(format!("{} {}", "Error: ".red().bold(), s)) - } - } -} - -#[derive(Debug)] -pub struct TraceArtifact { - stage_name: String, - debug_output: String, - text_color: &'static str, -} - -impl TraceArtifact { - pub fn new(stage: &str, debug: String) -> TraceArtifact { - let color = match stage { - "parse_trace" | "ast" => "red", - "ast_reducing" => "red", - "tokens" => "green", - "type_check" => "magenta", - _ => "blue", - }; - TraceArtifact { stage_name: stage.to_string(), debug_output: debug, text_color: color} - } - - pub fn new_parse_trace(trace: Vec) -> TraceArtifact { - let mut output = String::new(); - - for t in trace { - output.push_str(&t); - output.push_str("\n"); - } - - TraceArtifact { stage_name: "parse_trace".to_string(), debug_output: output, text_color: "red"} - } -} - pub trait ProgrammingLanguageInterface { - fn execute_pipeline(&mut self, _input: &str, _eval_options: &EvalOptions) -> FinishedComputation { - FinishedComputation { artifacts: vec![], text_output: Err(format!("Execution pipeline not done")), durations: vec![] } - } - fn get_language_name(&self) -> String; fn get_source_file_suffix(&self) -> String; - fn get_passes(&self) -> Vec { - vec![] - } - fn handle_custom_interpreter_directives(&mut self, _commands: &Vec<&str>) -> Option { - None - } - fn custom_interpreter_directives_help(&self) -> String { - format!(">> No custom interpreter directives specified <<") - } - fn get_doc(&self, _commands: &Vec<&str>) -> Option { - None - } - - /* ------- */ - // new trait methods - // - // fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse { ComputationResponse { @@ -185,7 +31,7 @@ pub trait ProgrammingLanguageInterface { } fn repl_request(&self, repl_request: String) -> String { - format!("Repl request not implemented") + format!(">> No custom interpreter directives or help info specified <<") } } @@ -216,3 +62,22 @@ pub struct GlobalOutputStats { total_duration: Option, stage_durations: Option> } + + /* +impl GlobalOutputStats { + fn get_timing(&self) -> Option { + if self.durations.len() != 0 { + let mut buf = String::new(); + write!(&mut buf, "Timing: ").unwrap(); + for duration in self.durations.iter() { + let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9); + write!(&mut buf, "{}s, ", timing).unwrap() + } + write!(&mut buf, "\n").unwrap(); + Some(buf) + } else { + None + } + } +} +*/ diff --git a/schala-repl/src/lib.rs b/schala-repl/src/lib.rs index 013e9ec..c7d95e6 100644 --- a/schala-repl/src/lib.rs +++ b/schala-repl/src/lib.rs @@ -25,99 +25,35 @@ mod repl; mod language; mod webapp; +pub use language::{ProgrammingLanguageInterface, EvalOptions, + ExecutionMethod, ComputationRequest, ComputationResponse, GlobalOutputStats}; + include!(concat!(env!("OUT_DIR"), "/static.rs")); const VERSION_STRING: &'static str = "0.1.0"; pub fn start_repl(langs: Vec>) { - let command_line_options = command_line_options().parse(std::env::args()).unwrap_or_else(|e| { + let options = command_line_options().parse(std::env::args()).unwrap_or_else(|e| { println!("{:?}", e); exit(1); }); - if command_line_options.opt_present("help") { - println!("{}", program_options().usage("Schala metainterpreter")); + if options.opt_present("help") { + println!("{}", command_line_options().usage("Schala metainterpreter")); exit(0); } - let mut repl = repl::NewRepl::new(langs); - repl.run_repl(); -} - -fn command_line_options() -> getopts::Options { - let mut options = getopts::Options::new(); - options.optflag("h", - "help", - "Show help text"); - options.optflag("w", - "webapp", - "Start up web interpreter"); - options -} - -/* --------------------------- */ - -pub use language::{ProgrammingLanguageInterface, EvalOptions, - ExecutionMethod, TraceArtifact, FinishedComputation, UnfinishedComputation, PassDebugOptionsDescriptor, PassDescriptor, ComputationRequest, ComputationResponse, GlobalOutputStats}; - -pub type PLIGenerator = Box Box + Send + Sync>; - -pub fn repl_main(generators: Vec) { - let languages: Vec> = generators.iter().map(|x| x()).collect(); - - let option_matches = program_options().parse(std::env::args()).unwrap_or_else(|e| { - println!("{:?}", e); - exit(1); - }); - - if option_matches.opt_present("list-languages") { - for lang in languages { - println!("{}", lang.get_language_name()); - } - exit(1); - } - - if option_matches.opt_present("help") { - println!("{}", program_options().usage("Schala metainterpreter")); - exit(0); - } - - if option_matches.opt_present("webapp") { - webapp::web_main(generators); - exit(0); - } - - let mut options = EvalOptions::default(); - let debug_passes = if let Some(opts) = option_matches.opt_str("debug") { - let output: Vec = opts.split_terminator(",").map(|s| s.to_string()).collect(); - output - } else { - vec![] - }; - - let language_names: Vec = languages.iter().map(|lang| {lang.get_language_name()}).collect(); - let initial_index: usize = - option_matches.opt_str("lang") - .and_then(|lang| { language_names.iter().position(|x| { x.to_lowercase() == lang.to_lowercase() }) }) - .unwrap_or(0); - - options.execution_method = match option_matches.opt_str("eval-style") { - Some(ref s) if s == "compile" => ExecutionMethod::Compile, - _ => ExecutionMethod::Interpret, - }; - - match option_matches.free[..] { + match options.free[..] { [] | [_] => { - let mut repl = repl::Repl::new(languages, initial_index); - repl.run(); + let mut repl = repl::NewRepl::new(langs); + repl.run_repl(); } [_, ref filename, _..] => { - - run_noninteractive(filename, languages, options, debug_passes); + run_noninteractive(filename, langs); } }; } -fn run_noninteractive(filename: &str, languages: Vec>, mut options: EvalOptions, debug_passes: Vec) { +fn run_noninteractive(filename: &str, languages: Vec>) { let path = Path::new(filename); let ext = path.extension().and_then(|e| e.to_str()).unwrap_or_else(|| { println!("Source file lacks extension"); @@ -131,53 +67,20 @@ fn run_noninteractive(filename: &str, languages: Vec { - /* - let llvm_bytecode = language.compile(&buffer); - compilation_sequence(llvm_bytecode, filename); - */ - panic!("Not ready to go yet"); - }, - ExecutionMethod::Interpret => { - let output = language.execute_pipeline(&buffer, &options); - output.to_noninteractive().map(|text| println!("{}", text)); - } - } + println!("NON-INTERACTIVE OUTPUT DOESN'T WORK YET"); + panic!(); } -fn program_options() -> getopts::Options { + +fn command_line_options() -> getopts::Options { let mut options = getopts::Options::new(); - options.optopt("s", - "eval-style", - "Specify whether to compile (if supported) or interpret the language. If not specified, the default is language-specific", - "[compile|interpret]" - ); - options.optflag("", - "list-languages", - "Show a list of all supported languages"); - options.optopt("l", - "lang", - "Start up REPL in a language", - "LANGUAGE"); options.optflag("h", "help", "Show help text"); options.optflag("w", "webapp", "Start up web interpreter"); - options.optopt("d", - "debug", - "Debug a stage (l = tokenizer, a = AST, r = parse trace, s = symbol table)", - "[l|a|r|s]"); options } diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index 11186ed..7fdcffb 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -5,8 +5,7 @@ use std::sync::Arc; use colored::*; use itertools::Itertools; -use crate::language::{ProgrammingLanguageInterface, EvalOptions, - PassDebugOptionsDescriptor, ComputationRequest, ComputationResponse}; +use crate::language::{ProgrammingLanguageInterface, EvalOptions, ComputationRequest, ComputationResponse}; mod command_tree; use self::command_tree::CommandTree; @@ -91,10 +90,6 @@ impl NewRepl { */ } - fn get_directives(&self) -> CommandTree { - CommandTree::Top(vec![]) - } - fn handle_interpreter_directive(&mut self, input: &str) -> Option { Some(format!("you typed {}, which is unsupported", input)) } @@ -120,122 +115,11 @@ impl NewRepl { Err(e) => format!("{} {}", "Error".red(), e) } } -} - - - - -/* --------------------------------------------- */ - - - - - - - -pub struct Repl { - options: EvalOptions, - languages: Vec>, - current_language_index: usize, - interpreter_directive_sigil: char, - line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>, -} - -impl Repl { - pub fn new(languages: Vec>, initial_index: usize) -> Repl { - use linefeed::Interface; - let current_language_index = if initial_index < languages.len() { initial_index } else { 0 }; - - let line_reader = Interface::new("schala-repl").unwrap(); - - Repl { - options: Repl::get_options(), - languages, - current_language_index, - interpreter_directive_sigil: ':', - line_reader - } - } - - fn get_cur_language(&self) -> &ProgrammingLanguageInterface { - self.languages[self.current_language_index].as_ref() - } - - fn get_options() -> EvalOptions { - File::open(OPTIONS_SAVE_FILE) - .and_then(|mut file| { - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - Ok(contents) - }) - .and_then(|contents| { - let options: EvalOptions = ::serde_json::from_str(&contents)?; - Ok(options) - }).unwrap_or(EvalOptions::default()) - } - - fn save_options(&self) { - let ref options = self.options; - let read = File::create(OPTIONS_SAVE_FILE) - .and_then(|mut file| { - let buf = ::serde_json::to_string(options).unwrap(); - file.write_all(buf.as_bytes()) - }); - - if let Err(err) = read { - println!("Error saving {} file {}", OPTIONS_SAVE_FILE, err); - } - } - - pub fn run(&mut self) { - use linefeed::ReadResult; - - println!("Schala MetaInterpreter version {}", crate::VERSION_STRING); - println!("Type {}help for help with the REPL", self.interpreter_directive_sigil); - - self.line_reader.load_history(HISTORY_SAVE_FILE).unwrap_or(()); - - loop { - let language_name = self.get_cur_language().get_language_name(); - let directives = self.get_directives(); - let tab_complete_handler = TabCompleteHandler::new(self.interpreter_directive_sigil, directives); - self.line_reader.set_completer(Arc::new(tab_complete_handler)); - - let prompt_str = format!("{} >> ", language_name); - self.line_reader.set_prompt(&prompt_str).unwrap(); - - match self.line_reader.read_line() { - Err(e) => { - println!("Terminal read error: {}", e); - }, - Ok(ReadResult::Eof) => break, - Ok(ReadResult::Signal(_)) => break, - Ok(ReadResult::Input(ref input)) => { - self.line_reader.add_history_unique(input.to_string()); - let output = match input.chars().nth(0) { - Some(ch) if ch == self.interpreter_directive_sigil => self.handle_interpreter_directive(input), - _ => Some(self.input_handler(input)), - }; - if let Some(o) = output { - println!("=> {}", o); - } - } - } - } - self.line_reader.save_history(HISTORY_SAVE_FILE).unwrap_or(()); - self.save_options(); - println!("Exiting..."); - } - - fn input_handler(&mut self, input: &str) -> String { - let ref mut language = self.languages[self.current_language_index]; - let interpreter_output = language.execute_pipeline(input, &self.options); - interpreter_output.to_repl() - } fn get_directives(&self) -> CommandTree { + let passes_directives = vec![]; + /* let ref passes = self.get_cur_language().get_passes(); - let passes_directives: Vec = passes.iter() .map(|pass_descriptor| { let name = &pass_descriptor.name; @@ -252,6 +136,7 @@ impl Repl { } } }).collect(); + */ CommandTree::Top(vec![ CommandTree::term("exit", Some("exit the REPL")), @@ -280,7 +165,41 @@ impl Repl { CommandTree::term("doc", Some("Get language-specific help for an item")), ]) } +} +/* --------------------------------------------- */ + + +/* + fn get_options() -> EvalOptions { + File::open(OPTIONS_SAVE_FILE) + .and_then(|mut file| { + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + Ok(contents) + }) + .and_then(|contents| { + let options: EvalOptions = ::serde_json::from_str(&contents)?; + Ok(options) + }).unwrap_or(EvalOptions::default()) + } + + fn save_options(&self) { + let ref options = self.options; + let read = File::create(OPTIONS_SAVE_FILE) + .and_then(|mut file| { + let buf = ::serde_json::to_string(options).unwrap(); + file.write_all(buf.as_bytes()) + }); + + if let Err(err) = read { + println!("Error saving {} file {}", OPTIONS_SAVE_FILE, err); + } + } + */ + + +/* fn handle_interpreter_directive(&mut self, input: &str) -> Option { let mut iter = input.chars(); iter.next(); @@ -364,6 +283,8 @@ impl Repl { } } } +*/ +/* fn handle_debug(&mut self, commands: Vec<&str>) -> Option { let passes = self.get_cur_language().get_passes(); match commands.get(1) { @@ -410,7 +331,7 @@ impl Repl { _ => Some(format!("Unknown debug command")) } } -} + */ struct TabCompleteHandler { sigil: char, diff --git a/schala-repl/src/webapp.rs b/schala-repl/src/webapp.rs index a1b7869..d0c046f 100644 --- a/schala-repl/src/webapp.rs +++ b/schala-repl/src/webapp.rs @@ -5,7 +5,6 @@ use rocket::http::ContentType; use rocket_contrib::json::Json; use crate::language::{ProgrammingLanguageInterface, EvalOptions}; use crate::WEBFILES; -use crate::PLIGenerator; #[get("/")] fn index() -> Content { @@ -31,14 +30,16 @@ struct Output { text: String, } +/* #[post("/input", format = "application/json", data = "")] fn interpreter_input(input: Json, generators: State>) -> Json { - let schala_gen = generators.get(0).unwrap(); let mut schala: Box = schala_gen(); - let code_output = schala.execute_pipeline(&input.source, &EvalOptions::default()); + //let code_output = schala.execute_pipeline(&input.source, &EvalOptions::default()); + let code_output = format!("NOTDONE"); Json(Output { text: code_output.to_repl() }) } +*/ -pub fn web_main(language_generators: Vec) { - rocket::ignite().manage(language_generators).mount("/", routes![index, js_bundle, interpreter_input]).launch(); +pub fn web_main(/*language_generators: Vec*/) { + rocket::ignite()/*.manage(language_generators)*/.mount("/", routes![index, js_bundle, /*interpreter_input*/]).launch(); } diff --git a/src/main.rs b/src/main.rs index dbefccb..ff40304 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ extern crate maaru_lang; extern crate rukka_lang; extern crate robo_lang; extern crate schala_lang; -use schala_repl::{PLIGenerator, ProgrammingLanguageInterface, repl_main, start_repl}; +use schala_repl::{ProgrammingLanguageInterface, start_repl}; extern { }