summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/poem/read.rs79
-rw-r--r--src/poem/read/parse.rs28
2 files changed, 65 insertions, 42 deletions
diff --git a/src/poem/read.rs b/src/poem/read.rs
index 3578a92..875bf76 100644
--- a/src/poem/read.rs
+++ b/src/poem/read.rs
@@ -5,7 +5,7 @@ use super::{
use core::fmt;
mod parse;
use crate::compose::Environment;
-use crate::{append, next, poem, remark, string};
+use crate::{next, poem, remark, string};
#[derive(Debug, PartialEq, Eq)]
pub enum Mishap {
@@ -41,7 +41,13 @@ impl fmt::Display for Mishap {
/// A [Poem] can add more [Verse]s to itself
trait Appendable {
type Type;
- fn add(&mut self, verse: &mut Self::Type, meter: Rune, last: Rune);
+ fn add(
+ &mut self,
+ verse: &mut Self::Type,
+ meter: Rune,
+ last: Rune,
+ env: &Environment,
+ ) -> Result<(), Mishap>;
}
impl Appendable for Poem {
@@ -51,20 +57,65 @@ impl Appendable for Poem {
///
/// Push a [Verse] to the [Poem] after checking that the [Verse] is not
/// empty. Also sets the meter of the [Verse].
- fn add(&mut self, verse: &mut Self::Type, last: Rune, meter: Rune) {
+ fn add(
+ &mut self,
+ verse: &mut Self::Type,
+ last: Rune,
+ meter: Rune,
+ env: &Environment,
+ ) -> Result<(), Mishap> {
if verse.is_empty() {
- return;
+ return Ok(());
}
- // Check the meter
- verse.meter = meter;
- if last == Rune::Couplet || meter == Rune::Couplet {
- verse.couplet = true;
+ // Check for aliases
+ match env.aliases.get(&verse.verb()) {
+ Some(alias) => {
+ // Interpret the alias (could be a complex poem)
+ let mut poem = Poem::read(alias.to_string(), env)?;
+
+ // Try and get the last verse
+ let lv = match poem.last_mut() {
+ Some(lv) => lv,
+ None => unreachable!(), // Should be caught by a Mishap above
+ };
+
+ // If the verse has a clause, add it to the last verse in
+ // the poem from the alias
+ if verse.clause().is_some() {
+ for word in verse.clause().unwrap().iter() {
+ lv.stanza.push(word.to_string());
+ }
+ }
+
+ // Check the meter
+ lv.meter = meter;
+ if last == Rune::Couplet || meter == Rune::Couplet {
+ verse.couplet = true;
+ }
+
+ // Push verse(s)
+ for v in poem.iter() {
+ self.push(v.clone());
+ }
+ }
+ None => {
+ // Check the meter
+ verse.meter = meter;
+ if last == Rune::Couplet || meter == Rune::Couplet {
+ verse.couplet = true;
+ }
+
+ // Push verse(s)
+ self.push(verse.clone());
+ }
}
- // Push verse(s) and clear the current verse stack
- self.push(verse.clone());
+ // Clear the current verse stack
verse.clear();
+
+ // Unit
+ Ok(())
}
}
@@ -127,8 +178,8 @@ impl Readable for Poem {
}
// Push the verse and break
- // poem.add(&mut verse, last, Rune::None);
- append!(poem, last, Rune::None, verse, env);
+ poem.add(&mut verse, last, Rune::None, env)?;
+ // append!(poem, last, Rune::None, verse, env);
break;
}
};
@@ -232,8 +283,8 @@ impl Readable for Poem {
// These meters indicate the end of a verse
Rune::Couplet | Rune::Quiet | Rune::And | Rune::Continue => {
verse.add(&mut word);
- // poem.add(&mut verse, last, rune);
- append!(poem, last, rune, verse, env);
+ poem.add(&mut verse, last, rune, env)?;
+ // append!(poem, last, rune, verse, env);
}
// Interpret ~ as $HOME
diff --git a/src/poem/read/parse.rs b/src/poem/read/parse.rs
index 58c8fde..7b01d85 100644
--- a/src/poem/read/parse.rs
+++ b/src/poem/read/parse.rs
@@ -84,31 +84,3 @@ macro_rules! poem {
$word.push('\x0b');
};
}
-
-/// Append a verse to the poem
-///
-/// Append a verse to poem, first checking for aliases in the environment, and
-/// processing the alias first, if necessary.
-#[macro_export]
-macro_rules! append {
- ($poem:expr, $last:expr, $meter:expr, $verse:expr, $env:expr) => {
- if !$verse.is_empty() {
- match $env.aliases.get(&$verse.verb()) {
- Some(alias) => {
- let alias = alias.to_string();
- let mut poem = Poem::read(alias, $env)?;
- let len = poem.len();
- for (i, verse) in poem.iter_mut().enumerate() {
- if $verse.clause().is_some() && i + 1 == len {
- verse.stanza.append(&mut $verse.clause().unwrap());
- }
- $poem.push(verse.clone());
- }
- }
- None => {
- $poem.add(&mut $verse, $last, $meter);
- }
- }
- }
- };
-}