107 lines
3.8 KiB
Rust
107 lines
3.8 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)
|
|
}
|