Compare commits

..

No commits in common. "d01d280452d3ee62c86651a187fc2cf00f3950d9" and "7b7e20859f021191cb7695a7980a24fae9052d5d" have entirely different histories.

7 changed files with 43 additions and 40 deletions

View File

@ -251,13 +251,8 @@ fn stage_names() -> Vec<&'static str> {
impl ProgrammingLanguageInterface for Schala { impl ProgrammingLanguageInterface for Schala {
fn language_name(&self) -> String { fn get_language_name(&self) -> String { format!("Schala") }
"Schala".to_owned() fn get_source_file_suffix(&self) -> String { format!("schala") }
}
fn source_file_suffix(&self) -> String {
"schala".to_owned()
}
fn run_computation(&mut self, request: ComputationRequest) -> ComputationResponse { fn run_computation(&mut self, request: ComputationRequest) -> ComputationResponse {
struct PassToken<'a> { struct PassToken<'a> {

View File

@ -12,9 +12,9 @@ itertools = "0.10"
lazy_static = "0.2.8" lazy_static = "0.2.8"
maplit = "*" maplit = "*"
colored = "1.8" colored = "1.8"
serde = "1.0" serde = "1.0.91"
serde_derive = "1.0" serde_derive = "1.0.91"
serde_json = "1.0" serde_json = "1.0.15"
phf = "0.7.12" phf = "0.7.12"
includedir = "0.2.0" includedir = "0.2.0"
linefeed = "0.6.0" linefeed = "0.6.0"

View File

@ -2,10 +2,16 @@ use std::collections::HashSet;
use std::time; use std::time;
pub trait ProgrammingLanguageInterface { pub trait ProgrammingLanguageInterface {
fn language_name(&self) -> String; fn get_language_name(&self) -> String;
fn source_file_suffix(&self) -> String; fn get_source_file_suffix(&self) -> String;
fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse; fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse {
ComputationResponse {
main_output: Err(format!("Computation pipeline not implemented")),
global_output_stats: GlobalOutputStats::default(),
debug_responses: vec![],
}
}
fn request_meta(&mut self, _request: LangMetaRequest) -> LangMetaResponse { fn request_meta(&mut self, _request: LangMetaRequest) -> LangMetaResponse {
LangMetaResponse::Custom { LangMetaResponse::Custom {

View File

@ -44,7 +44,7 @@ pub fn run_noninteractive(filenames: Vec<PathBuf>, languages: Vec<Box<dyn Progra
let mut language = Box::new( let mut language = Box::new(
languages languages
.into_iter() .into_iter()
.find(|lang| lang.source_file_suffix() == ext) .find(|lang| lang.get_source_file_suffix() == ext)
.unwrap_or_else(|| { .unwrap_or_else(|| {
println!("Extension .{} not recognized", ext); println!("Extension .{} not recognized", ext);
exit(1); exit(1);

View File

@ -48,6 +48,7 @@ fn get_directive_from_commands<'a>(
fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput { fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput {
let mut buf = String::new(); let mut buf = String::new();
let sigil = repl.interpreter_directive_sigil;
writeln!( writeln!(
buf, buf,
@ -62,7 +63,7 @@ fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput {
writeln!( writeln!(
buf, buf,
"{}{} - {}", "{}{} - {}",
repl.sigil, sigil,
directive.get_cmd(), directive.get_cmd(),
directive.get_help() directive.get_help()
) )
@ -74,7 +75,7 @@ fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput {
writeln!( writeln!(
buf, buf,
"Language-specific help for {}", "Language-specific help for {}",
lang.language_name() lang.get_language_name()
) )
.unwrap(); .unwrap();
writeln!(buf, "-----------------------").unwrap(); writeln!(buf, "-----------------------").unwrap();

View File

@ -1,6 +1,5 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
use colored::*;
use crate::language::{ use crate::language::{
ComputationRequest, LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface, ComputationRequest, LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface,
@ -23,10 +22,7 @@ const OPTIONS_SAVE_FILE: &'static str = ".schala_repl";
type InterpreterDirectiveOutput = Option<String>; type InterpreterDirectiveOutput = Option<String>;
pub struct Repl { pub struct Repl {
/// If this is the first character typed by a user into the repl, the following pub interpreter_directive_sigil: char,
/// will be interpreted as a directive to the REPL rather than a command in the
/// running programming language.
sigil: char,
line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>, line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>,
language_states: Vec<Box<dyn ProgrammingLanguageInterface>>, language_states: Vec<Box<dyn ProgrammingLanguageInterface>>,
options: ReplOptions, options: ReplOptions,
@ -42,10 +38,10 @@ impl Repl {
pub fn new(initial_states: Vec<Box<dyn ProgrammingLanguageInterface>>) -> Repl { pub fn new(initial_states: Vec<Box<dyn ProgrammingLanguageInterface>>) -> Repl {
use linefeed::Interface; use linefeed::Interface;
let line_reader = Interface::new("schala-repl").unwrap(); let line_reader = Interface::new("schala-repl").unwrap();
let sigil = ':'; let interpreter_directive_sigil = ':';
Repl { Repl {
sigil, interpreter_directive_sigil,
line_reader, line_reader,
language_states: initial_states, language_states: initial_states,
options: ReplOptions::new(), options: ReplOptions::new(),
@ -53,9 +49,10 @@ impl Repl {
} }
pub fn run_repl(&mut self) { pub fn run_repl(&mut self) {
println!("Schala meta-interpeter version {}", crate::VERSION_STRING); println!("Schala MetaInterpreter version {}", crate::VERSION_STRING);
println!( println!(
"Type {} for help with the REPL", format!("{}help", self.sigil).bright_green().bold() "Type {}help for help with the REPL",
self.interpreter_directive_sigil
); );
self.load_options(); self.load_options();
self.handle_repl_loop(); self.handle_repl_loop();
@ -68,15 +65,16 @@ impl Repl {
.load_history(HISTORY_SAVE_FILE) .load_history(HISTORY_SAVE_FILE)
.unwrap_or(()); .unwrap_or(());
match ReplOptions::load_from_file(OPTIONS_SAVE_FILE) { match ReplOptions::load_from_file(OPTIONS_SAVE_FILE) {
Ok(options) => { Ok(options) => {
self.options = options; self.options = options;
} }
Err(e) => eprintln!("{}",e) Err(()) => (),
} };
} }
fn handle_repl_loop(&mut self) { fn handle_repl_loop(&mut self) {
use linefeed::ReadResult::*; use linefeed::ReadResult::*;
let sigil = self.interpreter_directive_sigil;
'main: loop { 'main: loop {
macro_rules! match_or_break { macro_rules! match_or_break {
@ -98,7 +96,7 @@ impl Repl {
self.line_reader.add_history_unique(input.to_string()); self.line_reader.add_history_unique(input.to_string());
let mut chars = input.chars().peekable(); let mut chars = input.chars().peekable();
let repl_responses = match chars.nth(0) { let repl_responses = match chars.nth(0) {
Some(ch) if ch == self.sigil => { Some(ch) if ch == sigil => {
if chars.peek() == Some(&'{') { if chars.peek() == Some(&'{') {
let mut buf = String::new(); let mut buf = String::new();
buf.push_str(input.get(2..).unwrap()); buf.push_str(input.get(2..).unwrap());
@ -115,8 +113,8 @@ impl Repl {
} }
self.handle_input(&buf) self.handle_input(&buf)
} else { } else {
match self.handle_interpreter_directive(input.get(1..).unwrap()) { match self.handle_interpreter_directive(input) {
Some(directive_output) => println!("{}", directive_output), Some(directive_output) => println!("<> {}", directive_output),
None => (), None => (),
} }
continue; continue;
@ -133,7 +131,7 @@ impl Repl {
fn update_line_reader(&mut self) { fn update_line_reader(&mut self) {
let tab_complete_handler = let tab_complete_handler =
TabCompleteHandler::new(self.sigil, self.get_directives()); TabCompleteHandler::new(self.interpreter_directive_sigil, self.get_directives());
self.line_reader self.line_reader
.set_completer(Arc::new(tab_complete_handler)); //TODO fix this here .set_completer(Arc::new(tab_complete_handler)); //TODO fix this here
self.set_prompt(PromptStyle::Normal); self.set_prompt(PromptStyle::Normal);
@ -141,8 +139,8 @@ impl Repl {
fn set_prompt(&mut self, prompt_style: PromptStyle) { fn set_prompt(&mut self, prompt_style: PromptStyle) {
let prompt_str = match prompt_style { let prompt_str = match prompt_style {
PromptStyle::Normal => ">> ", PromptStyle::Normal => ">> ".to_string(),
PromptStyle::Multiline => ">| ", PromptStyle::Multiline => ">| ".to_string(),
}; };
self.line_reader.set_prompt(&prompt_str).unwrap(); self.line_reader.set_prompt(&prompt_str).unwrap();
@ -156,7 +154,9 @@ impl Repl {
} }
fn handle_interpreter_directive(&mut self, input: &str) -> InterpreterDirectiveOutput { fn handle_interpreter_directive(&mut self, input: &str) -> InterpreterDirectiveOutput {
let arguments: Vec<&str> = input.split_whitespace().collect(); let mut iter = input.chars();
iter.next();
let arguments: Vec<&str> = iter.as_str().split_whitespace().collect();
if arguments.len() < 1 { if arguments.len() < 1 {
return None; return None;

View File

@ -2,7 +2,7 @@ use crate::language::DebugAsk;
use std::collections::HashSet; use std::collections::HashSet;
use std::fs::File; use std::fs::File;
use std::io::{self, Read, Write}; use std::io::{Read, Write};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct ReplOptions { pub struct ReplOptions {
@ -26,11 +26,11 @@ impl ReplOptions {
file.write_all(buf.as_bytes()) file.write_all(buf.as_bytes())
}); });
if let Err(err) = res { if let Err(err) = res {
eprintln!("Error saving {} file {}", filename, err); println!("Error saving {} file {}", filename, err);
} }
} }
pub fn load_from_file(filename: &str) -> Result<ReplOptions, io::Error> { pub fn load_from_file(filename: &str) -> Result<ReplOptions, ()> {
File::open(filename) File::open(filename)
.and_then(|mut file| { .and_then(|mut file| {
let mut contents = String::new(); let mut contents = String::new();
@ -41,5 +41,6 @@ impl ReplOptions {
let output: ReplOptions = crate::serde_json::from_str(&contents)?; let output: ReplOptions = crate::serde_json::from_str(&contents)?;
Ok(output) Ok(output)
}) })
.map_err(|_| ())
} }
} }