From c82a07e75c9df42740edb4bebdc97eda51be610b Mon Sep 17 00:00:00 2001 From: Matt Paras Date: Tue, 31 Dec 2024 17:40:57 -0800 Subject: [PATCH] checkpoint --- cogs/installer/parser.scm | 10 ++-- crates/steel-core/src/steel_vm/vm.rs | 1 + crates/steel-repl/src/highlight.rs | 3 ++ crates/steel-repl/src/lib.rs | 4 ++ crates/steel-repl/src/repl.rs | 81 +++++++++++++++++++++++++++- src/lib.rs | 4 +- 6 files changed, 94 insertions(+), 9 deletions(-) diff --git a/cogs/installer/parser.scm b/cogs/installer/parser.scm index 545059a4f..f775fa918 100644 --- a/cogs/installer/parser.scm +++ b/cogs/installer/parser.scm @@ -18,9 +18,7 @@ (into-hashmap))) (define (convert-path path) - (if (equal? (current-os!) "windows") - (string-replace path "/" "\\") - path)) + (if (equal? (current-os!) "windows") (string-replace path "/" "\\") path)) (define (parse-cog module [search-from #f]) ;; TODO: This needs to handle relative paths @@ -41,6 +39,7 @@ ; (displayln "Searching in: " new-search-path) (parse-cog new-search-path)) + ;; Try installing? (error! "Unable to locate the module " module)))) ;; Parses a cog file directly into a hashmap @@ -53,10 +52,7 @@ ;; TODO: Move this out - also make sure (if (member (car p) '(dylibs dependencies)) (list (car p) - (map (lambda (spec) - (if (list? spec) - (apply hash spec) - spec)) + (map (lambda (spec) (if (list? spec) (apply hash spec) spec)) (cadr p))) p))) (into-hashmap))) diff --git a/crates/steel-core/src/steel_vm/vm.rs b/crates/steel-core/src/steel_vm/vm.rs index 72ceb6119..e8e047090 100644 --- a/crates/steel-core/src/steel_vm/vm.rs +++ b/crates/steel-core/src/steel_vm/vm.rs @@ -1662,6 +1662,7 @@ impl<'a> VmCore<'a> { } pub fn snapshot_stack_trace(&self) -> DehydratedStackTrace { + dbg!(self.thread.stack_frames.len()); DehydratedStackTrace::new( self.thread .stack_frames diff --git a/crates/steel-repl/src/highlight.rs b/crates/steel-repl/src/highlight.rs index 2ec27ee7a..d3b5d83f0 100644 --- a/crates/steel-repl/src/highlight.rs +++ b/crates/steel-repl/src/highlight.rs @@ -29,6 +29,9 @@ pub struct RustylineHelper { bracket: std::cell::Cell>, // keywords: HashSet<&'static str>, } +unsafe impl Send for RustylineHelper {} +unsafe impl Sync for RustylineHelper {} + impl RustylineHelper { pub fn new(engine: Rc>) -> Self { Self { diff --git a/crates/steel-repl/src/lib.rs b/crates/steel-repl/src/lib.rs index a0893de85..2b83483b0 100644 --- a/crates/steel-repl/src/lib.rs +++ b/crates/steel-repl/src/lib.rs @@ -6,3 +6,7 @@ mod highlight; pub fn run_repl(vm: steel::steel_vm::engine::Engine) -> std::io::Result<()> { repl::repl_base(vm) } + +pub fn register_readline_module(vm: &mut steel::steel_vm::engine::Engine) { + repl::readline_module(vm) +} diff --git a/crates/steel-repl/src/repl.rs b/crates/steel-repl/src/repl.rs index d9a7ceebe..360b7efad 100644 --- a/crates/steel-repl/src/repl.rs +++ b/crates/steel-repl/src/repl.rs @@ -1,7 +1,10 @@ extern crate rustyline; use colored::*; +use rustyline::history::FileHistory; use steel::compiler::modules::steel_home; +use steel::rvals::Custom; +use std::error::Error; use std::{cell::RefCell, rc::Rc, sync::mpsc::channel}; use rustyline::error::ReadlineError; @@ -130,7 +133,83 @@ fn finish_or_interrupt(vm: &mut Engine, line: String) { } } -/// Entire point for the repl +#[derive(Debug)] +struct RustyLine(Editor); +impl Custom for RustyLine {} + +#[derive(Debug)] +struct RustyLineError(rustyline::error::ReadlineError); + +impl Custom for RustyLineError {} + +impl std::fmt::Display for RustyLineError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl Error for RustyLineError {} + +pub fn readline_module(vm: &mut Engine) { + let mut module = steel::steel_vm::builtin::BuiltInModule::new("#%private/steel/readline"); + + module.register_fn("#%create-repl", || { + display_startup(); + + // #[cfg(target_os = "windows")] + // let prompt = String::from("λ > "); + + // #[cfg(not(target_os = "windows"))] + // let prompt = format!("{}", "λ > ".bright_green().bold().italic()); + + let mut rl = Editor::::new() + .expect("Unable to instantiate the repl!"); + rl.set_check_cursor_position(true); + + // Load repl history + let history_path = get_repl_history_path(); + if let Err(_) = rl.load_history(&history_path) { + if let Err(_) = File::create(&history_path) { + eprintln!("Unable to create repl history file {:?}", history_path) + } + }; + + // let mut print_time = false; + + // let (tx, rx) = channel(); + // let tx = std::sync::Mutex::new(tx); + + // let cancellation_function = move || { + // tx.lock().unwrap().send(()).unwrap(); + // }; + + // let safepoint = vm.get_thread_state_controller(); + + // let safepoint = safepoint.clone(); + // let ctrlc_safepoint = safepoint.clone(); + + // ctrlc::set_handler(move || { + // ctrlc_safepoint.clone().interrupt(); + // }) + // .unwrap(); + + // let clear_interrupted = move || { + // safepoint.resume(); + // }; + + RustyLine(rl) + }); + + module.register_fn("#%read-line", |rl: &mut RustyLine| { + let prompt = format!("{}", "λ > ".bright_green().bold().italic()); + + rl.0.readline(&prompt).map_err(RustyLineError) + }); + + vm.register_module(module); +} + +/// Entry point for the repl /// Automatically adds the prelude and contracts for the core library pub fn repl_base(mut vm: Engine) -> std::io::Result<()> { display_startup(); diff --git a/src/lib.rs b/src/lib.rs index 643cc738e..889e2eb45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ extern crate steel_repl; use steel::steel_vm::engine::Engine; use steel_doc::walk_dir; -use steel_repl::run_repl; +use steel_repl::{register_readline_module, run_repl}; use std::path::PathBuf; use std::process; @@ -70,6 +70,8 @@ pub fn run(clap_args: Args) -> Result<(), Box> { let mut vm = Engine::new(); vm.register_value("std::env::args", steel::SteelVal::ListV(vec![].into())); + register_readline_module(&mut vm); + match clap_args { Args { default_file: None,