74 lines
3.1 KiB
Rust
74 lines
3.1 KiB
Rust
|
use std::error::Error;
|
||
|
use std::fs;
|
||
|
use std::path::PathBuf;
|
||
|
|
||
|
pub fn normalize(file: PathBuf) -> Result<String, Box<dyn Error>> {
|
||
|
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)
|
||
|
}
|