diff --git a/src/labels/mod.rs b/src/labels/mod.rs index 55b9445..146d27b 100644 --- a/src/labels/mod.rs +++ b/src/labels/mod.rs @@ -1,2 +1,3 @@ pub mod parse; +pub mod process; pub mod sanitize; diff --git a/src/labels/parse.rs b/src/labels/parse.rs index 65567ea..cdb8eca 100644 --- a/src/labels/parse.rs +++ b/src/labels/parse.rs @@ -8,8 +8,8 @@ use crate::{ world::Stat, }; -type ParsedStat = Vec; -enum Chunk { +pub type ParsedStat = Vec; +pub enum Chunk { Verbatim(String), Label(LabelName), Reference(LabelName), @@ -22,7 +22,7 @@ pub struct LabelName { pub local: Option, } -fn parse_stat_labels(stat: &Stat) -> ParsedStat { +pub fn parse_stat_labels(stat: &Stat) -> ParsedStat { let code = &stat.code; let mut parser = ParseState::new(code); assert!( diff --git a/src/labels/process.rs b/src/labels/process.rs new file mode 100644 index 0000000..796a5ed --- /dev/null +++ b/src/labels/process.rs @@ -0,0 +1,41 @@ +use crate::world::Board; + +use super::{ + parse::{Chunk, ParsedStat, parse_stat_labels}, + sanitize::Registry, +}; + +pub fn process_labels(board: &mut Board) { + // Parse stats into chunks + let mut stats: Vec = board + .stats + .iter() + .map(|stat| parse_stat_labels(&stat)) + .collect(); + let mut registry = Registry::new(); + + // Replace each label with its sanitized equivalent + for stat in stats.iter_mut() { + for chunk in stat.iter_mut() { + match chunk { + Chunk::Verbatim(_) => {} + Chunk::Label(name) | Chunk::Reference(name) => { + let sanitized = registry.sanitize(name); + *chunk = Chunk::Verbatim(sanitized.into()); + } + } + } + } + + // Join chunks together and replace old stats' code + for (old_stat, parsed_stat) in board.stats.iter_mut().zip(stats.into_iter()) { + let new_code = parsed_stat + .into_iter() + .map(|chunk| match chunk { + Chunk::Verbatim(s) => s, + _ => unreachable!(), + }) + .collect(); + old_stat.code = new_code; + } +} diff --git a/src/main.rs b/src/main.rs index 32dd62e..eb81f8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ mod preprocess; mod world; use anyhow::anyhow; -use labels::parse::print_labels; +use labels::{parse::print_labels, process::process_labels}; use preprocess::eval::Context; use std::{env, error::Error, fs, path::PathBuf, process::exit}; use world::World; @@ -55,6 +55,10 @@ fn main() -> Result<(), Box> { } } + for mut board in &mut world.boards { + process_labels(&mut board); + } + // Try to write a modified world file fs::write("tmp.zzt", world.to_bytes()?)?;