diff options
Diffstat (limited to 'src/macro_processor')
| -rw-r--r-- | src/macro_processor/macro_processor.rs | 32 | ||||
| -rw-r--r-- | src/macro_processor/main.rs | 44 | 
2 files changed, 58 insertions, 18 deletions
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<String, MacroType>, @@ -632,9 +637,11 @@ pub struct MacroProcessor {      /// Emitted warnings      pub warnings: Vec<MacroProcessorWarning>,      #[cfg(feature = "guile")] -    pub guile: Guile, +    pub guile: std::rc::Rc<Guile>,  } +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" {  | 
