burritos/src/simulator/mem_cmp.rs

350 lines
8.1 KiB
Rust
Raw Normal View History

use std::fs;
use std::io;
use std::io::BufRead;
2023-02-08 14:34:09 +01:00
const MEM_SIZE : usize = 4096;
2023-02-07 15:19:38 +01:00
/* TRUCS MANQUANT
* Verifier qu'il y a un nombre pair de caractere hexa dans la ligne correspondante d'une section du fichier source
* Sinon on ne peut pas automatiquement remplir chaque octect car 2 hexa = 1 octet
* OUBLI CONVERSIONS ADDR ET LEN QUI SONT AUSSI EN CARACTÈRES HEXA DS LE FICHIER
2023-02-07 15:19:38 +01:00
*/
/* FORMAT FICHIER.TXT Représentant la mémoire apres éxecution d'un prog
* PC
* SP
* Section_1
* Section_2
* ...
* ...
* Section_n
*/
/* Chaque section se divise en 3 parties, sur 2 lignes de texte
* addr ESPACE len
* content
*/
//content est une suite hexadécimale
//Section dans le fichier, champ String car informations proviennent d'un fichier txt
struct SectionFormat{
addr: String,
len: String,
content: String,
}
//Section dans le programme
struct Section{
addr: usize, // adresse dans la mémoire
len: usize, // nombre d'octets de la donnée à addr
content: Vec<u8>, // la donnée en question
}
/*
* Voir si instanciation d'une structure deplace les valeurs "locales" à la méthode from, je sais plus ....
*/
impl Section{
2023-02-07 15:19:38 +01:00
fn from(section: &SectionFormat) -> Section {
2023-02-07 15:19:38 +01:00
let mut content: Vec<u8> = Vec::new();
let addr: usize = string_hex_to_usize(&section.addr);
let len: usize = string_hex_to_usize(&section.len);
2023-02-07 15:19:38 +01:00
let mut tmp_a: char = ' ';
let mut tmp_b: char = ' ';
for (i, c) in section.content.chars().enumerate(){
if i%2 == 0 {
tmp_a = c;
}
else {
tmp_b = c;
content.push(two_hex_to_u8(tmp_a,tmp_b));
}
}
2023-02-07 15:19:38 +01:00
Section{addr:addr, len:len, content:content}
}
2023-02-08 12:37:21 +01:00
fn print_Section(s: &Section){
println!("ADDR :: {}", s.addr);
println!("LEN :: {}", s.len);
println!("CONTENT :: {:?}", s.content);
}
2023-02-07 15:19:38 +01:00
}
2023-02-07 22:50:55 +01:00
/*
* Representation de l'etat de la mémoire (apres execution.... a confirmer), sous forme de sections
*/
struct Mem_Checker{
pc: usize,
sp: usize,
sections: Vec<Section>,
}
impl Mem_Checker{
2023-02-08 12:37:21 +01:00
fn from(path: &String) -> Mem_Checker {
let file = fs::File::open("test_file_section.txt").expect("Wrong filename");
let reader = io::BufReader::new(file);
2023-02-08 12:37:21 +01:00
let mut pc: usize = 0;
let mut sp: usize = 0;
2023-02-08 12:37:21 +01:00
let mut sections: Vec<Section> = Vec::new();
let mut tmp_addr_str: String = String::new();
let mut tmp_len_str: String = String::new();
for (i,line) in reader.lines().enumerate() {
let current_line = line.unwrap();
if i == 0 {
//Lecture de PC
pc = string_hex_to_usize(&current_line);
}
else if i == 1 {
//Lecture SP
sp = string_hex_to_usize(&current_line);
}
else {
//Lecture des sections
2023-02-08 12:37:21 +01:00
if current_line.contains(' ') {
//lecture ligne ADDR LEN
let next_word_index = current_line.find(' ').unwrap();
tmp_addr_str = String::from(&current_line[0..next_word_index]);
tmp_len_str = String::from(&current_line[next_word_index+1..]);
}
else {
//lecture ligne CONTENT
let section_f = SectionFormat{
addr: tmp_addr_str.clone(),
len: tmp_len_str.clone(),
content: current_line,
};
sections.push(Section::from(&section_f));
}
}
}
2023-02-08 12:37:21 +01:00
Mem_Checker{pc:pc, sp:sp, sections:sections}
}
fn print_Mem_Checker(m_c: &Mem_Checker){
println!("PC :: {}", m_c.pc);
println!("SP :: {}", m_c.sp);
for(i,s) in m_c.sections.iter().enumerate() {
println!("\nSection {}\n", i);
Section::print_Section(&s);
}
}
2023-02-08 14:34:09 +01:00
fn Mem_Checker_check(m_c: &Mem_Checker, memory: [u8 ; MEM_SIZE]){
/*
* Check pc, sp
*/
/*
* Check sections
*/
for(i, s) in m_c.sections.iter().enumerate() {
let addr = s.addr;
let len = s.len;
let segment = &s.content;
/*
regarder dans mem[addr]
a cette adresse verifier len octets
*/
for j in 0..(len-1){
if segment[j] != memory[addr + j] {
println!("missmatch");
}
}
}
}
}
fn string_hex_to_usize(s: &String) -> usize{
let max_pow = (s.len()-1) as u32;
let mut ret_value: usize = 0;
let base: usize = 16;
for (i,c )in s.chars().enumerate(){
2023-02-08 12:37:21 +01:00
//println!("Current char :: {} :: Current pow :: {} ::", c, max_pow - (i as u32));
let tmp: usize = (one_hex_to_dec(c) as usize);
ret_value += base.pow(max_pow - (i as u32))*tmp;
}
2023-02-07 22:50:55 +01:00
return ret_value;
2023-02-07 22:50:55 +01:00
}
2023-02-07 22:50:55 +01:00
/*
* c doit etre un caractère hexadécimale
*/
fn one_hex_to_dec(c: char) -> u8 {
match c {
'A' | 'a' => 10,
'B' | 'b' => 11,
'C' | 'c' => 12,
'D' | 'd' => 13,
'E' | 'e' => 14,
'F' | 'f' => 15,
_ => {
let ret : u8 = c.to_digit(10).unwrap() as u8;
return ret;
},
}
}
2023-02-07 22:50:55 +01:00
fn two_hex_to_u8(c1: char, c2: char) -> u8 {
let a = one_hex_to_dec(c1);
let b = one_hex_to_dec(c2);
16*a + b
}
/*
* Juste pour voir si via BufReader les \n sont présent, apres test il s'avère que non
* De toute facon on limitera d'une section la lecture par len
*/
fn test_show_sections_file(){
let file = fs::File::open("test_file_section.txt").expect("Wrong filename");
let reader = io::BufReader::new(file);
for line in reader.lines() {
//println!("Tailles de la ligne : {}",
let current = line.unwrap();
//println!("Taille de la ligne : {}", current.len()); // En effet pas de \n dans chaque line, parfait
println!("{}", &current);
}
}
#[cfg(test)]
mod tests {
use super::*;
2023-02-08 12:37:21 +01:00
#[test]
fn test_create_Mem_Chercker(){
let path: String = "osef".to_string();
let m_c = Mem_Checker::from(&path);
Mem_Checker::print_Mem_Checker(&m_c);
}
#[test]
fn test_string_hex_to_usize(){
let s = String::from("AE1F20");
//println!("taille de string : {}", s.len());
let expected: usize = 11411232;
let result = string_hex_to_usize(&s);
assert_eq!(expected,result);
}
#[test]
fn tmp_fct_read_file(){
println!("Reading A file \n");
test_show_sections_file();
}
#[test]
fn test_create_section_content(){
let section_format = SectionFormat{
addr: "0".to_string(),
len: "0".to_string(),
content: "00FF0AA0A5".to_string(),
};
let section = Section::from(&section_format);
let mut expected_vec: Vec<u8> = Vec::new();
expected_vec.push(0u8);
expected_vec.push(255u8);
expected_vec.push(10u8);
expected_vec.push(160u8);
expected_vec.push(165u8);
//println!("Vec from created section {:?}", &section.content);
//println!("Expected vec {:?}", &expected_vec);
assert_eq!(section.content, expected_vec);
}
#[test]
fn test_mod(){
let cond = (0%2) == 0;
assert_eq!(true, cond);
}
#[test]
fn test_mod_2(){
let cond = (1%2) == 1;
assert_eq!(true, cond);
}
#[test]
fn test_hex_1(){
let b = two_hex_to_u8('0', '0');
assert_eq!(0u8, b);
}
#[test]
fn test_hex_2(){
let b = two_hex_to_u8('F', 'F');
assert_eq!(255u8, b);
}
#[test]
fn test_hex_3(){
let b = two_hex_to_u8('0', 'A');
assert_eq!(10u8, b);
}
#[test]
fn test_hex_4(){
let b = two_hex_to_u8('A', '0');
assert_eq!(160u8, b);
}
#[test]
fn test_hex_5(){
let b = two_hex_to_u8('A', '5');
assert_eq!(165u8, b);
}
}