From b84765abc10598c3c808ea207ba89be40211189b Mon Sep 17 00:00:00 2001 From: Qrius Date: Thu, 19 Dec 2024 14:35:56 +0100 Subject: Try to make a macro to get guile things instead --- src/macro_processor/macro_processor.rs | 32 ++++++++++++++++--------- src/macro_processor/main.rs | 44 ++++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 18 deletions(-) (limited to 'src/macro_processor') diff --git a/src/macro_processor/macro_processor.rs b/src/macro_processor/macro_processor.rs index 306c8da..52fc581 100644 --- a/src/macro_processor/macro_processor.rs +++ b/src/macro_processor/macro_processor.rs @@ -1,10 +1,12 @@ #[cfg(feature = "guile")] -use crate::guile::guile::Guile; +use crate::guile::guile::{scm_undefined, Guile}; #[cfg(feature = "deadlinks")] use crate::macro_processor::deadlinks::smp_builtin_wodl; use crate::macro_processor::error::SMPError; use std::collections::HashMap; use std::fs; +#[cfg(feature = "guile")] +use std::os::raw::c_void; use std::process::Command; // print only with debug_assertions @@ -537,6 +539,9 @@ fn smp_builtin_html_from_markdown( } fn macro_is_whitespace_deleting(s: &str) -> bool { + if s.len() == 0 { + return false; + } s.chars().nth(s.len() - 1) == Some('_') } @@ -623,7 +628,7 @@ impl MacroProcessorWarning { /// Defines a MacroProcessor object, with it's associated state /// the state mostly includes the defined macros -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct MacroProcessor { /// All currently defined macros in this MacroProcessor pub macros: HashMap, @@ -632,9 +637,11 @@ pub struct MacroProcessor { /// Emitted warnings pub warnings: Vec, #[cfg(feature = "guile")] - pub guile: Guile, + pub guile: std::rc::Rc, } +pub static mut GLOBS: Option<&MacroProcessor> = None; + impl MacroProcessor { pub fn new() -> Self { let mut smp = Self { @@ -642,12 +649,21 @@ impl MacroProcessor { macro_invocations: Vec::new(), warnings: Vec::new(), #[cfg(feature = "guile")] - guile: Guile::new(), + guile: std::rc::Rc::new(Guile::new()), }; smp.define_builtins(); smp } + pub fn defself(&mut self) { + // Find a better way to do this Rc-stuff + let guile = std::rc::Rc::as_ptr(&self.guile); + unsafe { + let data_ptr: *mut c_void = self as *mut _ as *mut c_void; + (*guile).define("smp_state_ptr", data_ptr); + } + } + /// Bootstrapping-function for defining all builtins, /// the same way all other macros might be defined fn define_builtins(&mut self) { @@ -747,13 +763,6 @@ impl MacroProcessor { /// * `name` - The name of the new macro /// * `macro_expansion` - The MacroType struct to use. pub fn define_macro(&mut self, name: String, macro_expansion: MacroType) { - #[cfg(feature = "guile")] - { - match ¯o_expansion { - MacroType::String(s) => self.guile.define_string(&(name.clone()), s), - _ => (), - } - } self.macros.insert(name, macro_expansion); } @@ -916,6 +925,7 @@ impl MacroProcessor { #[cfg(feature = "guile")] ParserState::InGuile => match c { ')' if peek == Some(&'%') => { + self.defself(); let r = self .guile .evaluate_expression(&guile_expr) diff --git a/src/macro_processor/main.rs b/src/macro_processor/main.rs index d8247d6..2435cf3 100644 --- a/src/macro_processor/main.rs +++ b/src/macro_processor/main.rs @@ -1,9 +1,31 @@ use skaldpress::macro_processor::MacroProcessor; use std::env; use std::fs; +#[cfg(not(feature = "readline"))] use std::io; +#[cfg(not(feature = "readline"))] use std::io::Write; +#[cfg(feature = "readline")] +use std::ffi::{CStr, CString}; +#[cfg(feature = "readline")] +use std::os::raw::c_char; + +#[cfg(feature = "readline")] +#[link(name = "readline")] +extern "C" { + fn readline(p: *const c_char) -> *const c_char; +} + +#[cfg(feature = "readline")] +fn readline_r(prompt: &str) -> String { + let c_prompt = CString::new(prompt).expect("Could not convert to c_string"); + unsafe { + let ret = readline(c_prompt.as_ptr()); + CStr::from_ptr(ret).to_string_lossy().into_owned() + } +} + fn repl() { println!("=Skaldpress Macro Processor (REPL)"); println!(" type \"quit\" to exit"); @@ -11,14 +33,22 @@ fn repl() { loop { let mut input = String::new(); loop { - print!("> "); - let _ = io::stdout().flush(); let mut _input = String::new(); - io::stdin() - .read_line(&mut _input) - .expect("error: unable to read user input"); - if _input == "\n" { - input.pop(); + + #[cfg(feature = "readline")] + { + _input = readline_r("> ") + } + #[cfg(not(feature = "readline"))] + { + print!("> "); + let _ = io::stdout().flush(); + io::stdin() + .read_line(&mut _input) + .expect("error: unable to read user input"); + } + + if _input == "" { break; } if _input == "quit\n" { -- cgit v1.2.3