diff options
Diffstat (limited to 'src/macro_processor')
| -rw-r--r-- | src/macro_processor/macro_processor.rs | 47 | 
1 files changed, 44 insertions, 3 deletions
diff --git a/src/macro_processor/macro_processor.rs b/src/macro_processor/macro_processor.rs index 0b714f0..306c8da 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; +#[cfg(feature = "deadlinks")] +use crate::macro_processor::deadlinks::smp_builtin_wodl;  use crate::macro_processor::error::SMPError;  use std::collections::HashMap;  use std::fs;  use std::process::Command; -#[cfg(feature = "deadlinks")] -use crate::macro_processor::deadlinks::smp_builtin_wodl;  // print only with debug_assertions  macro_rules! dprint {      ($($x:tt)*) => { @@ -591,6 +593,8 @@ enum ParserState {      InQuotes,      InMacro,      InMacroArgs, +    #[cfg(feature = "guile")] +    InGuile,      DNL,  } @@ -627,6 +631,8 @@ pub struct MacroProcessor {      pub macro_invocations: Vec<(String, Vec<String>)>,      /// Emitted warnings      pub warnings: Vec<MacroProcessorWarning>, +    #[cfg(feature = "guile")] +    pub guile: Guile,  }  impl MacroProcessor { @@ -635,6 +641,8 @@ impl MacroProcessor {              macros: HashMap::new(),              macro_invocations: Vec::new(),              warnings: Vec::new(), +            #[cfg(feature = "guile")] +            guile: Guile::new(),          };          smp.define_builtins();          smp @@ -729,7 +737,7 @@ impl MacroProcessor {      /// * `name` - The name of the new macro      /// * `body` - The body of the new macro, this will be expanded when macro is executed      pub fn define_macro_string(&mut self, name: String, body: String) { -        self.macros.insert(name, MacroType::String(body)); +        self.define_macro(name, MacroType::String(body));      }      /// Define a new macro as any MacroType @@ -739,6 +747,13 @@ 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);      } @@ -836,6 +851,9 @@ impl MacroProcessor {          let mut quote_level = 0;          let mut parens_level = 0; +        #[cfg(feature = "guile")] +        let mut guile_expr = String::new(); +          let mut chars = input.char_indices().peekable();          while let Some((i, c)) = chars.next() {              highlight_debug!(input, macro_name_start, i); @@ -858,6 +876,13 @@ impl MacroProcessor {                          continue;                      } +                    #[cfg(feature = "guile")] +                    if c == '%' && peek == Some(&'(') { +                        state = ParserState::InGuile; +                        chars.next(); +                        continue; +                    } +                      if c == '%' && peek == Some(&'"') {                          state = ParserState::InQuotes;                          quote_level += 1; @@ -888,6 +913,22 @@ impl MacroProcessor {                          output.push(c);                      }                  }, +                #[cfg(feature = "guile")] +                ParserState::InGuile => match c { +                    ')' if peek == Some(&'%') => { +                        let r = self +                            .guile +                            .evaluate_expression(&guile_expr) +                            .expect("fatal guile error"); +                        output.push_str(&r); +                        guile_expr.clear(); +                        state = ParserState::Normal; +                        chars.next(); +                    } +                    _ => { +                        guile_expr.push(c); +                    } +                },                  ParserState::InMacro => {                      if c.is_alphanumeric() || c == '_' {                          macro_name.push(c);  | 
