diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 493db55..22bf991 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -21,7 +21,10 @@ use std::cell::RefCell; use std::rc::Rc; use itertools::Itertools; -use schala_repl::{ProgrammingLanguageInterface, ComputationRequest, ComputationResponse, LangMetaRequest, LangMetaResponse, GlobalOutputStats, DebugRequest, DebugResponse}; +use schala_repl::{ProgrammingLanguageInterface, +ComputationRequest, ComputationResponse, +LangMetaRequest, LangMetaResponse, GlobalOutputStats, +DebugRequest, DebugResponse, DebugAsk}; macro_rules! bx { ($e:expr) => { Box::new($e) } @@ -84,14 +87,25 @@ impl Schala { } fn handle_debug_immediate(&self, request: DebugRequest) -> DebugResponse { - if request.kind == "symbol-table" { - let debug = self.symbol_table.borrow().debug_symbol_table(); - return DebugResponse { kind: format!("symbol-table"), value: debug }; - } - - DebugResponse { - kind: format!("unknown"), - value: format!(""), + use DebugAsk::*; + let ask = request.ask; + match ask { + Timing => DebugResponse { ask: Timing, value: format!("Invalid") }, + ByStage { stage_name } => match &stage_name[..] { + "symbol-table" => { + let value = self.symbol_table.borrow().debug_symbol_table(); + DebugResponse { + ask: ByStage { stage_name: format!("symbol-table") }, + value + } + }, + s => { + DebugResponse { + ask: ByStage { stage_name: s.to_string() }, + value: format!("Not-implemented") + } + } + } } } } @@ -259,8 +273,8 @@ impl ProgrammingLanguageInterface for Schala { fn request_meta(&mut self, request: LangMetaRequest) -> LangMetaResponse { match request { LangMetaRequest::StageNames => LangMetaResponse::StageNames( - vec!["tokenizing".into(), "parsing".into(), "typechecking".into(), - "ast reduction".into(), "ast-walking-evaluation".into()] + vec!["tokenizing".into(), "parsing".into(), "typechecking".into(), "symbol-table".into(), + "ast-reduction".into(), "ast-walking-evaluation".into()] ), LangMetaRequest::Docs { source } => self.handle_docs(source), LangMetaRequest::ImmediateDebug(debug_request) => diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index 8430e61..61f90fe 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -29,12 +29,17 @@ pub struct ComputationResponse { } pub struct DebugRequest { - pub kind: String, - pub value: String + pub ask: DebugAsk, +} + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub enum DebugAsk { + Timing, + ByStage { stage_name: String }, } pub struct DebugResponse { - pub kind: String, + pub ask: DebugAsk, pub value: String } diff --git a/schala-repl/src/lib.rs b/schala-repl/src/lib.rs index 7ff83cb..6961be3 100644 --- a/schala-repl/src/lib.rs +++ b/schala-repl/src/lib.rs @@ -24,7 +24,10 @@ mod repl; mod language; mod webapp; -pub use language::{ProgrammingLanguageInterface, ComputationRequest, ComputationResponse, LangMetaRequest, LangMetaResponse, DebugRequest, DebugResponse, GlobalOutputStats}; +pub use language::{ProgrammingLanguageInterface, +ComputationRequest, ComputationResponse, +LangMetaRequest, LangMetaResponse, +DebugRequest, DebugResponse, DebugAsk, GlobalOutputStats}; include!(concat!(env!("OUT_DIR"), "/static.rs")); const VERSION_STRING: &'static str = "0.1.0"; diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index fc3f640..be3d183 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -2,10 +2,15 @@ use std::fmt::Write as FmtWrite; use std::io::{Read, Write}; use std::fs::File; use std::sync::Arc; +use std::collections::HashSet; use colored::*; use itertools::Itertools; -use crate::language::{ProgrammingLanguageInterface, ComputationRequest, ComputationResponse, LangMetaRequest, LangMetaResponse, DebugRequest, DebugResponse}; +use crate::language::{ProgrammingLanguageInterface, +ComputationRequest, ComputationResponse, +LangMetaRequest, LangMetaResponse, +DebugRequest, DebugAsk, DebugResponse}; + mod command_tree; use self::command_tree::{CommandTree, BoxedCommandFunction}; @@ -16,7 +21,7 @@ pub struct Repl { interpreter_directive_sigil: char, line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>, language_states: Vec>, - debug_asks: Vec, + debug_asks: HashSet, } impl Repl { @@ -24,7 +29,7 @@ impl Repl { use linefeed::Interface; let line_reader = Interface::new("schala-repl").unwrap(); let interpreter_directive_sigil = ':'; - let debug_asks = vec![]; + let debug_asks = HashSet::new(); Repl { interpreter_directive_sigil, line_reader, language_states: initial_states, debug_asks @@ -175,13 +180,18 @@ impl Repl { } fn handle_input(&mut self, input: &str) -> String { - let ref mut language_state = self.get_cur_language_state(); + let mut debug_requests = vec![]; + for ask in self.debug_asks.iter() { + debug_requests.push(DebugRequest { ask: ask.clone() }); + } let request = ComputationRequest { source: input, - debug_requests: vec![], + debug_requests, }; + let ref mut language_state = self.get_cur_language_state(); + let ComputationResponse { main_output, global_output_stats, debug_responses } = language_state.run_computation(request); @@ -245,20 +255,45 @@ impl Repl { let mut cur_state = repl.get_cur_language_state(); match cmds.get(0) { Some(&"show-immediate") => { - let debug_stage = match cmds.get(1) { + let stage_name = match cmds.get(1) { Some(s) => s.to_string(), None => return Some(format!("Must specify a thing to debug")), }; - let meta = LangMetaRequest::ImmediateDebug(DebugRequest { - kind: debug_stage, - value: format!(""), - }); - let response = cur_state.request_meta(meta); + let meta = LangMetaRequest::ImmediateDebug( + DebugRequest { ask: DebugAsk::ByStage { stage_name: stage_name.clone() } } + ); + let response = match cur_state.request_meta(meta) { + LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => { + if (ask != DebugAsk::ByStage { stage_name: stage_name }) { + return Some(format!("Didn't get debug stage requested")); + } + value + }, + _ => return Some(format!("Invalid language meta response")), + }; + Some(response) + }, + cmd @ Some(&"show") | cmd @ Some(&"hide") => { + let stage_name = match cmds.get(1) { + Some(s) => s.to_string(), + None => return Some(format!("Must specify a stage to show or hide")), + }; + let ask = DebugAsk::ByStage { stage_name }; + if cmd == Some(&"show") { + repl.debug_asks.insert(ask); + } else { + repl.debug_asks.remove(&ask); + } + None + }, + Some(&"timing") => { + match cmds.get(1) { + Some(&"on") => repl.debug_asks.insert(DebugAsk::Timing), + Some(&"off") => repl.debug_asks.remove(&DebugAsk::Timing), + _ => return Some(format!("Must specify 'on' or 'off'")), + }; None }, - Some(&"show") => panic!(), - Some(&"hide") => panic!(), - Some(&"timing") => panic!(), e => Some(format!("Unsupported command: {:?}", e)), } })