tmcpu_isa_assembler/src/normalizer.rs

107 lines
3.8 KiB
Rust
Raw Normal View History

2023-05-08 21:59:54 +00:00
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 {
2023-05-08 22:01:50 +00:00
return Err(format!(
"line {}: expected exactly 2 arguments to 'lsh', instead got {}",
line_num,
line_split.len() - 1
)
.into());
2023-05-08 21:59:54 +00:00
}
let dest = line_split[1];
if !dest.ends_with(',') {
return Err(format!("line {}: arg 1 to 'lsh' must end in ','", line_num).into());
}
2023-05-08 22:01:50 +00:00
let dest = &dest[..dest.len() - 1];
2023-05-08 21:59:54 +00:00
let rg = line_split[2];
2023-05-08 22:01:50 +00:00
normalized += &format!(
"add {}, {} {} ; normalizer: originally '{}'\n",
dest, rg, rg, line
);
}
2023-05-08 21:59:54 +00:00
"cmp" => {
if line_split.len() != 3 {
2023-05-08 22:01:50 +00:00
return Err(format!(
"line {}: expected exactly 2 arguments to 'cmp', instead got {}",
line_num,
line_split.len() - 1
)
.into());
2023-05-08 21:59:54 +00:00
}
let a = line_split[1];
let b = line_split[2];
normalized += &format!("sub r0, {} {} ; normalizer: originally '{}'\n", a, b, line);
2023-05-08 22:01:50 +00:00
}
2023-05-08 21:59:54 +00:00
"cpy" => {
if line_split.len() != 3 {
2023-05-08 22:01:50 +00:00
return Err(format!(
"line {}: expected exactly 2 arguments to 'cpy', instead got {}",
line_num,
line_split.len() - 1
)
.into());
2023-05-08 21:59:54 +00:00
}
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";
2023-05-08 22:01:50 +00:00
normalized += &format!(
"add {}, {} r0 ; normalizer: originally '{}'\n",
&dest[..dest.len() - 1],
a,
line
);
}
2023-05-08 21:59:54 +00:00
"not" => {
if line_split.len() != 3 {
2023-05-08 22:01:50 +00:00
return Err(format!(
"line {}: expected exactly 2 arguments to 'not', instead got {}",
line_num,
line_split.len() - 1
)
.into());
2023-05-08 21:59:54 +00:00
}
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";
2023-05-08 22:01:50 +00:00
normalized += &format!(
"nor {}, {} r0 ; normalizer: originally '{}'\n",
&dest[..dest.len() - 1],
a,
line
);
2023-05-08 21:59:54 +00:00
}
_ => {
normalized += line;
normalized += "\n";
}
}
}
Ok(normalized)
2023-05-08 22:01:50 +00:00
}