Run cargo fmt
This commit is contained in:
parent
d3866a1908
commit
1470e7fbdd
@ -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();
|
|
||||||
}
|
}
|
||||||
|
@ -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()),
|
||||||
|
@ -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![],
|
||||||
};
|
};
|
||||||
|
@ -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,
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
41
src/main.rs
41
src/main.rs
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user