use std::error::Error; use std::fs; use std::path::PathBuf; pub fn normalize(file: PathBuf) -> Result> { let file_str = fs::read_to_string(file)?; let mut normalized = "; This file has only been normalized. It has not been processed or optimized.\n; This code cannot yet directly be passed into the assembler.\n".to_string(); normalized += "; t+normalizer:tmCPU t+preprocessor:none t+optimizer:none @generated\n"; for (line_num, line) in file_str.lines().enumerate() { let line_split: Vec<&str> = line.split(' ').collect(); match line_split[0] { "lsh" => { if line_split.len() != 3 { return Err(format!("line {}: expected exactly 2 arguments to 'lsh', instead got {}", line_num, line_split.len() - 1).into()); } let dest = line_split[1]; if !dest.ends_with(',') { return Err(format!("line {}: arg 1 to 'lsh' must end in ','", line_num).into()); } let dest = &dest[..dest.len()-1]; let rg = line_split[2]; normalized += &format!("add {}, {} {} ; normalizer: originally '{}'\n", dest, rg, rg, line); }, "cmp" => { if line_split.len() != 3 { return Err(format!("line {}: expected exactly 2 arguments to 'cmp', instead got {}", line_num, line_split.len() - 1).into()); } let a = line_split[1]; let b = line_split[2]; normalized += &format!("sub r0, {} {} ; normalizer: originally '{}'\n", a, b, line); }, "cpy" => { if line_split.len() != 3 { return Err(format!("line {}: expected exactly 2 arguments to 'cpy', instead got {}", line_num, line_split.len() - 1).into()); } let dest = line_split[1]; let a = line_split[2]; if !dest.ends_with(',') { return Err(format!("line {}: arg 1 to 'lsh' must end in ','", line_num).into()); } normalized += "ldi r0, 0 ; normalizer: originally below\n"; normalized += &format!("add {}, {} r0 ; normalizer: originally '{}'\n", &dest[..dest.len()-1], a, line); }, "not" => { if line_split.len() != 3 { return Err(format!("line {}: expected exactly 2 arguments to 'not', instead got {}", line_num, line_split.len() - 1).into()); } let dest = line_split[1]; let a = line_split[2]; if !dest.ends_with(',') { return Err(format!("line {}: arg 1 to 'not' must end in ','", line_num).into()); } normalized += "ldi r0, 0 ; normalizer: originally below\n"; normalized += &format!("nor {}, {} r0 ; normalizer: originally '{}'\n", &dest[..dest.len()-1], a, line); } _ => { normalized += line; normalized += "\n"; } } } Ok(normalized) }