Run cargo fmt

This commit is contained in:
Greg Shuflin 2021-11-24 23:51:30 -08:00
parent d3866a1908
commit 1470e7fbdd
10 changed files with 94 additions and 193 deletions

View File

@ -3,8 +3,5 @@ extern crate includedir_codegen;
use includedir_codegen::Compression; use includedir_codegen::Compression;
fn main() { fn main() {
includedir_codegen::start("WEBFILES") includedir_codegen::start("WEBFILES").dir("../static", Compression::Gzip).build("static.rs").unwrap();
.dir("../static", Compression::Gzip)
.build("static.rs")
.unwrap();
} }

View File

@ -1,8 +1,10 @@
use crate::directive_actions::DirectiveAction;
use crate::language::ProgrammingLanguageInterface;
use crate::{InterpreterDirectiveOutput, Repl};
use colored::*; use colored::*;
use crate::{
directive_actions::DirectiveAction, language::ProgrammingLanguageInterface, InterpreterDirectiveOutput,
Repl,
};
/// A CommandTree is either a `Terminal` or a `NonTerminal`. When command parsing reaches the first /// A CommandTree is either a `Terminal` or a `NonTerminal`. When command parsing reaches the first
/// Terminal, it will use the `DirectiveAction` found there to find an appropriate function to execute, /// Terminal, it will use the `DirectiveAction` found there to find an appropriate function to execute,
/// and then execute it with any remaining arguments /// and then execute it with any remaining arguments
@ -39,12 +41,7 @@ impl CommandTree {
children: Vec<CommandTree>, children: Vec<CommandTree>,
action: DirectiveAction, action: DirectiveAction,
) -> CommandTree { ) -> CommandTree {
CommandTree::Terminal { CommandTree::Terminal { name: s.to_string(), help_msg: help.map(|x| x.to_string()), children, action }
name: s.to_string(),
help_msg: help.map(|x| x.to_string()),
children,
action,
}
} }
pub fn nonterm(s: &str, help: Option<&str>, children: Vec<CommandTree>) -> CommandTree { pub fn nonterm(s: &str, help: Option<&str>, children: Vec<CommandTree>) -> CommandTree {
@ -65,14 +62,10 @@ impl CommandTree {
} }
pub fn get_help(&self) -> &str { pub fn get_help(&self) -> &str {
match self { match self {
CommandTree::Terminal { help_msg, .. } => help_msg CommandTree::Terminal { help_msg, .. } =>
.as_ref() help_msg.as_ref().map(|s| s.as_str()).unwrap_or("<no help text provided>"),
.map(|s| s.as_str()) CommandTree::NonTerminal { help_msg, .. } =>
.unwrap_or("<no help text provided>"), help_msg.as_ref().map(|s| s.as_str()).unwrap_or("<no help text provided>"),
CommandTree::NonTerminal { help_msg, .. } => help_msg
.as_ref()
.map(|s| s.as_str())
.unwrap_or("<no help text provided>"),
CommandTree::Top(_) => "", CommandTree::Top(_) => "",
} }
} }
@ -96,11 +89,7 @@ impl CommandTree {
let res: Result<(DirectiveAction, usize), String> = loop { let res: Result<(DirectiveAction, usize), String> = loop {
match dir_pointer { match dir_pointer {
CommandTree::Top(subcommands) CommandTree::Top(subcommands) | CommandTree::NonTerminal { children: subcommands, .. } => {
| CommandTree::NonTerminal {
children: subcommands,
..
} => {
let next_command = match arguments.get(idx) { let next_command = match arguments.get(idx) {
Some(cmd) => cmd, Some(cmd) => cmd,
None => break Err("Command requires arguments".to_owned()), None => break Err("Command requires arguments".to_owned()),

View File

@ -1,10 +1,11 @@
use crate::help::help;
use crate::language::{
LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface,
};
use crate::{InterpreterDirectiveOutput, Repl};
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use crate::{
help::help,
language::{LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface},
InterpreterDirectiveOutput, Repl,
};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum DirectiveAction { pub enum DirectiveAction {
Null, Null,
@ -31,10 +32,7 @@ impl DirectiveAction {
::std::process::exit(0) ::std::process::exit(0)
} }
ListPasses => { ListPasses => {
let pass_names = match repl let pass_names = match repl.language_state.request_meta(LangMetaRequest::StageNames) {
.language_state
.request_meta(LangMetaRequest::StageNames)
{
LangMetaResponse::StageNames(names) => names, LangMetaResponse::StageNames(names) => names,
_ => vec![], _ => vec![],
}; };

View File

@ -1,5 +1,4 @@
use crate::command_tree::CommandTree; use crate::{command_tree::CommandTree, directive_actions::DirectiveAction};
use crate::directive_actions::DirectiveAction;
pub fn directives_from_pass_names(pass_names: &[String]) -> CommandTree { pub fn directives_from_pass_names(pass_names: &[String]) -> CommandTree {
let passes_directives: Vec<CommandTree> = pass_names let passes_directives: Vec<CommandTree> = pass_names
@ -33,11 +32,7 @@ fn get_list(passes_directives: &[CommandTree], include_help: bool) -> Vec<Comman
CommandTree::terminal( CommandTree::terminal(
"help", "help",
Some("Print this help message"), Some("Print this help message"),
if include_help { if include_help { get_list(passes_directives, false) } else { vec![] },
get_list(passes_directives, false)
} else {
vec![]
},
Help, Help,
), ),
CommandTree::nonterm( CommandTree::nonterm(
@ -68,11 +63,6 @@ fn get_list(passes_directives: &[CommandTree], include_help: bool) -> Vec<Comman
), ),
], ],
), ),
CommandTree::terminal( CommandTree::terminal("doc", Some("Get language-specific help for an item"), vec![], Doc),
"doc",
Some("Get language-specific help for an item"),
vec![],
Doc,
),
] ]
} }

View File

@ -1,10 +1,11 @@
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use crate::command_tree::CommandTree;
use crate::language::ProgrammingLanguageInterface;
use crate::{InterpreterDirectiveOutput, Repl};
use colored::*; use colored::*;
use crate::{
command_tree::CommandTree, language::ProgrammingLanguageInterface, InterpreterDirectiveOutput, Repl,
};
pub fn help<L: ProgrammingLanguageInterface>( pub fn help<L: ProgrammingLanguageInterface>(
repl: &mut Repl<L>, repl: &mut Repl<L>,
arguments: &[&str], arguments: &[&str],
@ -21,8 +22,7 @@ pub fn help<L: ProgrammingLanguageInterface>(
let children = dir.get_children(); let children = dir.get_children();
writeln!(buf, "`{}` - {}", cmd, dir.get_help()).unwrap(); writeln!(buf, "`{}` - {}", cmd, dir.get_help()).unwrap();
for sub in children.iter() { for sub in children.iter() {
writeln!(buf, "\t`{} {}` - {}", cmd, sub.get_cmd(), sub.get_help()) writeln!(buf, "\t`{} {}` - {}", cmd, sub.get_cmd(), sub.get_help()).unwrap();
.unwrap();
} }
buf buf
} }
@ -31,16 +31,11 @@ pub fn help<L: ProgrammingLanguageInterface>(
} }
} }
fn get_directive_from_commands<'a>( fn get_directive_from_commands<'a>(commands: &[&str], dirs: &'a CommandTree) -> Option<&'a CommandTree> {
commands: &[&str],
dirs: &'a CommandTree,
) -> Option<&'a CommandTree> {
let mut directive_list = dirs.get_children(); let mut directive_list = dirs.get_children();
let mut matched_directive = None; let mut matched_directive = None;
for cmd in commands { for cmd in commands {
let found = directive_list let found = directive_list.iter().find(|directive| directive.get_cmd() == *cmd);
.iter()
.find(|directive| directive.get_cmd() == *cmd);
if let Some(dir) = found { if let Some(dir) = found {
directive_list = dir.get_children(); directive_list = dir.get_children();
} }
@ -53,33 +48,16 @@ fn get_directive_from_commands<'a>(
fn global_help<L: ProgrammingLanguageInterface>(repl: &mut Repl<L>) -> InterpreterDirectiveOutput { fn global_help<L: ProgrammingLanguageInterface>(repl: &mut Repl<L>) -> InterpreterDirectiveOutput {
let mut buf = String::new(); let mut buf = String::new();
writeln!( writeln!(buf, "{} version {}", "Schala REPL".bright_red().bold(), crate::VERSION_STRING).unwrap();
buf,
"{} version {}",
"Schala REPL".bright_red().bold(),
crate::VERSION_STRING
)
.unwrap();
writeln!(buf, "-----------------------").unwrap(); writeln!(buf, "-----------------------").unwrap();
for directive in repl.get_directives().get_children() { for directive in repl.get_directives().get_children() {
writeln!( writeln!(buf, "{}{} - {}", repl.sigil, directive.get_cmd(), directive.get_help()).unwrap();
buf,
"{}{} - {}",
repl.sigil,
directive.get_cmd(),
directive.get_help()
)
.unwrap();
} }
writeln!(buf).unwrap(); writeln!(buf).unwrap();
writeln!( writeln!(buf, "Language-specific help for {}", <L as ProgrammingLanguageInterface>::language_name())
buf, .unwrap();
"Language-specific help for {}",
<L as ProgrammingLanguageInterface>::language_name()
)
.unwrap();
writeln!(buf, "-----------------------").unwrap(); writeln!(buf, "-----------------------").unwrap();
Some(buf) Some(buf)
} }

View File

@ -1,5 +1,4 @@
use std::collections::HashSet; use std::{collections::HashSet, time};
use std::time;
pub trait ProgrammingLanguageInterface { pub trait ProgrammingLanguageInterface {
type Config: Default + Clone; type Config: Default + Clone;
@ -9,10 +8,7 @@ pub trait ProgrammingLanguageInterface {
fn run_computation(&mut self, _request: ComputationRequest<Self::Config>) -> ComputationResponse; fn run_computation(&mut self, _request: ComputationRequest<Self::Config>) -> ComputationResponse;
fn request_meta(&mut self, _request: LangMetaRequest) -> LangMetaResponse { fn request_meta(&mut self, _request: LangMetaRequest) -> LangMetaResponse {
LangMetaResponse::Custom { LangMetaResponse::Custom { kind: "not-implemented".to_owned(), value: format!("") }
kind: "not-implemented".to_owned(),
value: format!(""),
}
} }
} }
@ -37,10 +33,7 @@ pub struct GlobalOutputStats {
#[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize, Serialize)] #[derive(Debug, Clone, Hash, Eq, PartialEq, Deserialize, Serialize)]
pub enum DebugAsk { pub enum DebugAsk {
Timing, Timing,
ByStage { ByStage { stage_name: String, token: Option<String> },
stage_name: String,
token: Option<String>,
},
} }
pub struct DebugResponse { pub struct DebugResponse {

View File

@ -17,16 +17,14 @@ mod directives;
use directives::directives_from_pass_names; use directives::directives_from_pass_names;
mod help; mod help;
mod response; mod response;
use response::ReplResponse; use std::{collections::HashSet, sync::Arc};
use colored::*; use colored::*;
use std::collections::HashSet;
use std::sync::Arc;
pub use language::{ pub use language::{
ComputationRequest, ComputationResponse, DebugAsk, DebugResponse, GlobalOutputStats, ComputationRequest, ComputationResponse, DebugAsk, DebugResponse, GlobalOutputStats, LangMetaRequest,
LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface, LangMetaResponse, ProgrammingLanguageInterface,
}; };
use response::ReplResponse;
include!(concat!(env!("OUT_DIR"), "/static.rs")); include!(concat!(env!("OUT_DIR"), "/static.rs"));
const VERSION_STRING: &str = "0.1.0"; const VERSION_STRING: &str = "0.1.0";
@ -58,20 +56,12 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
let line_reader = Interface::new("schala-repl").unwrap(); let line_reader = Interface::new("schala-repl").unwrap();
let sigil = ':'; let sigil = ':';
Repl { Repl { sigil, line_reader, language_state: initial_state, options: ReplOptions::new() }
sigil,
line_reader,
language_state: initial_state,
options: ReplOptions::new(),
}
} }
pub fn run_repl(&mut self, config: L::Config) { 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", format!("{}help", self.sigil).bright_green().bold());
"Type {} for help with the REPL",
format!("{}help", self.sigil).bright_green().bold()
);
self.load_options(); self.load_options();
self.handle_repl_loop(config); self.handle_repl_loop(config);
self.save_before_exit(); self.save_before_exit();
@ -79,9 +69,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
} }
fn load_options(&mut self) { fn load_options(&mut self) {
self.line_reader self.line_reader.load_history(HISTORY_SAVE_FILE).unwrap_or(());
.load_history(HISTORY_SAVE_FILE)
.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;
@ -113,7 +101,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
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.next() { let repl_responses = match chars.next() {
Some(ch) if ch == self.sigil => { Some(ch) if ch == self.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());
@ -130,12 +118,11 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
} }
self.handle_input(&buf, &config) 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);
} }
continue; continue;
} },
}
_ => self.handle_input(input, &config), _ => self.handle_input(input, &config),
}; };
@ -147,8 +134,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
fn update_line_reader(&mut self) { fn update_line_reader(&mut self) {
let tab_complete_handler = TabCompleteHandler::new(self.sigil, self.get_directives()); let tab_complete_handler = TabCompleteHandler::new(self.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);
} }
@ -162,9 +148,7 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
} }
fn save_before_exit(&self) { fn save_before_exit(&self) {
self.line_reader self.line_reader.save_history(HISTORY_SAVE_FILE).unwrap_or(());
.save_history(HISTORY_SAVE_FILE)
.unwrap_or(());
self.options.save_to_file(OPTIONS_SAVE_FILE); self.options.save_to_file(OPTIONS_SAVE_FILE);
} }
@ -185,20 +169,13 @@ impl<L: ProgrammingLanguageInterface> Repl<L> {
debug_requests.insert(ask.clone()); debug_requests.insert(ask.clone());
} }
let request = ComputationRequest { let request = ComputationRequest { source: input, config: config.clone(), debug_requests };
source: input,
config: config.clone(),
debug_requests,
};
let response = self.language_state.run_computation(request); let response = self.language_state.run_computation(request);
response::handle_computation_response(response, &self.options) response::handle_computation_response(response, &self.options)
} }
fn get_directives(&mut self) -> CommandTree { fn get_directives(&mut self) -> CommandTree {
let pass_names = match self let pass_names = match self.language_state.request_meta(LangMetaRequest::StageNames) {
.language_state
.request_meta(LangMetaRequest::StageNames)
{
LangMetaResponse::StageNames(names) => names, LangMetaResponse::StageNames(names) => names,
_ => vec![], _ => vec![],
}; };
@ -212,15 +189,14 @@ struct TabCompleteHandler {
top_level_commands: CommandTree, top_level_commands: CommandTree,
} }
use linefeed::complete::{Completer, Completion}; use linefeed::{
use linefeed::terminal::Terminal; complete::{Completer, Completion},
terminal::Terminal,
};
impl TabCompleteHandler { impl TabCompleteHandler {
fn new(sigil: char, top_level_commands: CommandTree) -> TabCompleteHandler { fn new(sigil: char, top_level_commands: CommandTree) -> TabCompleteHandler {
TabCompleteHandler { TabCompleteHandler { top_level_commands, sigil }
top_level_commands,
sigil,
}
} }
} }
@ -247,11 +223,7 @@ impl<T: Terminal> Completer<T> for TabCompleteHandler {
None => { None => {
let top = matches!(command_tree, Some(CommandTree::Top(_))); let top = matches!(command_tree, Some(CommandTree::Top(_)));
let word = if top { word.get(1..).unwrap() } else { word }; let word = if top { word.get(1..).unwrap() } else { word };
for cmd in command_tree for cmd in command_tree.map(|x| x.get_subcommands()).unwrap_or_default().into_iter() {
.map(|x| x.get_subcommands())
.unwrap_or_default()
.into_iter()
{
if cmd.starts_with(word) { if cmd.starts_with(word) {
completions.push(Completion { completions.push(Completion {
completion: format!("{}{}", if top { ":" } else { "" }, cmd), completion: format!("{}{}", if top { ":" } else { "" }, cmd),
@ -265,12 +237,9 @@ impl<T: Terminal> Completer<T> for TabCompleteHandler {
Some(s) => { Some(s) => {
let new_ptr: Option<&CommandTree> = command_tree.and_then(|cm| match cm { let new_ptr: Option<&CommandTree> = command_tree.and_then(|cm| match cm {
CommandTree::Top(children) => children.iter().find(|c| c.get_cmd() == s), CommandTree::Top(children) => children.iter().find(|c| c.get_cmd() == s),
CommandTree::NonTerminal { children, .. } => { CommandTree::NonTerminal { children, .. } =>
children.iter().find(|c| c.get_cmd() == s) children.iter().find(|c| c.get_cmd() == s),
} CommandTree::Terminal { children, .. } => children.iter().find(|c| c.get_cmd() == s),
CommandTree::Terminal { children, .. } => {
children.iter().find(|c| c.get_cmd() == s)
}
}); });
command_tree = new_ptr; command_tree = new_ptr;
} }

View File

@ -1,8 +1,10 @@
use crate::language::DebugAsk; use std::{
collections::HashSet,
fs::File,
io::{self, Read, Write},
};
use std::collections::HashSet; use crate::language::DebugAsk;
use std::fs::File;
use std::io::{self, Read, Write};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct ReplOptions { pub struct ReplOptions {
@ -13,11 +15,7 @@ pub struct ReplOptions {
impl ReplOptions { impl ReplOptions {
pub fn new() -> ReplOptions { pub fn new() -> ReplOptions {
ReplOptions { ReplOptions { debug_asks: HashSet::new(), show_total_time: true, show_stage_times: false }
debug_asks: HashSet::new(),
show_total_time: true,
show_stage_times: false,
}
} }
pub fn save_to_file(&self, filename: &str) { pub fn save_to_file(&self, filename: &str) {

View File

@ -1,9 +1,11 @@
use colored::*; use std::{fmt, fmt::Write};
use std::fmt;
use std::fmt::Write;
use crate::language::{ComputationResponse, DebugAsk}; use colored::*;
use crate::ReplOptions;
use crate::{
language::{ComputationResponse, DebugAsk},
ReplOptions,
};
pub struct ReplResponse { pub struct ReplResponse {
label: Option<String>, label: Option<String>,
@ -64,16 +66,8 @@ pub fn handle_computation_response(
} }
responses.push(match response.main_output { responses.push(match response.main_output {
Ok(s) => ReplResponse { Ok(s) => ReplResponse { label: None, text: s, color: None },
label: None, Err(e) => ReplResponse { label: Some("Error".to_string()), text: e, color: Some(Color::Red) },
text: s,
color: None,
},
Err(e) => ReplResponse {
label: Some("Error".to_string()),
text: e,
color: Some(Color::Red),
},
}); });
responses responses

View File

@ -1,17 +1,15 @@
use schala_repl::{Repl, ProgrammingLanguageInterface, ComputationRequest}; use std::{collections::HashSet, fs::File, io::Read, path::PathBuf, process::exit};
use std::{fs::File, io::Read, path::PathBuf, process::exit, collections::HashSet};
use schala_lang::{Schala, SchalaConfig}; use schala_lang::{Schala, SchalaConfig};
use schala_repl::{ComputationRequest, ProgrammingLanguageInterface, Repl};
//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() {
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
let matches = command_line_options() let matches = command_line_options().parse(&args[1..]).unwrap_or_else(|e| {
.parse(&args[1..]) eprintln!("Error parsing options: {}", e);
.unwrap_or_else(|e| { exit(1);
eprintln!("Error parsing options: {}", e); });
exit(1);
});
if matches.opt_present("help") { if matches.opt_present("help") {
println!("{}", command_line_options().usage("Schala metainterpreter")); println!("{}", command_line_options().usage("Schala metainterpreter"));
@ -27,27 +25,28 @@ fn main() {
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
let filename = &paths[0]; let filename = &paths[0];
let extension = filename.extension().and_then(|e| e.to_str()) let extension = filename.extension().and_then(|e| e.to_str()).unwrap_or_else(|| {
.unwrap_or_else(|| {
eprintln!("Source file `{}` has no extension.", filename.display()); eprintln!("Source file `{}` has no extension.", filename.display());
exit(1); exit(1);
}); });
//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() {
let config = SchalaConfig { let config = SchalaConfig { repl: false };
repl: false,
};
run_noninteractive(paths, Schala::new(), config); run_noninteractive(paths, Schala::new(), config);
} else { } else {
eprintln!("Extension .{} not recognized", extension); eprintln!("Extension .{} not recognized", extension);
exit(1); exit(1);
} }
} }
} }
pub fn run_noninteractive<L: ProgrammingLanguageInterface>(filenames: Vec<PathBuf>, mut language: L, config: L::Config) { 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];
@ -55,11 +54,7 @@ pub fn run_noninteractive<L: ProgrammingLanguageInterface>(filenames: Vec<PathBu
let mut buffer = String::new(); let mut buffer = String::new();
source_file.read_to_string(&mut buffer).unwrap(); source_file.read_to_string(&mut buffer).unwrap();
let request = ComputationRequest { let request = ComputationRequest { source: &buffer, config, debug_requests: HashSet::new() };
source: &buffer,
config,
debug_requests: HashSet::new(),
};
let response = language.run_computation(request); let response = language.run_computation(request);
match response.main_output { match response.main_output {