188 lines
5.4 KiB
Rust
188 lines
5.4 KiB
Rust
![]() |
use super::*;
|
||
|
use std::fs::File;
|
||
|
use ::function_name::named;
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Residual<'a>(&'a str);
|
||
|
|
||
|
pub fn take_until<'a>(word : &'a str, pattern : u8) -> Option<(&'a str, Residual)> {
|
||
|
let mut new_start = 0;
|
||
|
|
||
|
for chr in word.as_bytes() {
|
||
|
if (*chr == pattern) {
|
||
|
return Some((&word[0..new_start], Residual(&word[new_start..])));
|
||
|
}
|
||
|
else {
|
||
|
new_start += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
None
|
||
|
}
|
||
|
|
||
|
fn tag<'a>(word : &'a str, pattern : &'a str) -> Option<&'a str> {
|
||
|
let lhs = word.as_bytes().iter();
|
||
|
let rhs = pattern.as_bytes();
|
||
|
let iter = lhs.zip(rhs);
|
||
|
let mut new_start = 0;
|
||
|
|
||
|
let mut res = true;
|
||
|
for (c_lhs, c_rhs) in iter {
|
||
|
res = res && (c_lhs == c_rhs);
|
||
|
if !res {return None}
|
||
|
new_start += 1;
|
||
|
}
|
||
|
|
||
|
Some(&word[new_start..])
|
||
|
}
|
||
|
|
||
|
#[named]
|
||
|
fn parse_date(word_reader : &mut WordReader) -> Result<(), String> {
|
||
|
let mut parsed_day = false;
|
||
|
let mut parsed_month = false;
|
||
|
let mut parsed_date = false;
|
||
|
let mut parsed_hh = false;
|
||
|
let mut parsed_mm = false;
|
||
|
let mut parsed_ss = false;
|
||
|
let mut parsed_year = false;
|
||
|
let mut parsed_end = false;
|
||
|
|
||
|
let day = {
|
||
|
// check for another word in the file
|
||
|
let (word, cursor) = word_reader.next_word().expect(
|
||
|
format!("reached end of file without parser leaving {}", function_name!()).as_str()
|
||
|
);
|
||
|
|
||
|
let days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
||
|
if !days.contains(&word) {
|
||
|
let msg = format!("reached end of file without parser leaving {}\n", function_name!());
|
||
|
let msg2 = format!("{word} is not a valid weekday : expected one of {days:?}\n");
|
||
|
let msg3 = format!("failure location: {cursor:?}");
|
||
|
return Err(format!("{}{}{}", msg, msg2, msg3))
|
||
|
}
|
||
|
|
||
|
word.to_string()
|
||
|
};
|
||
|
|
||
|
let month = {
|
||
|
// check for another word in the file
|
||
|
let (word, cursor) = word_reader.next_word().expect(
|
||
|
format!("reached end of file without parser leaving {}", function_name!()).as_str()
|
||
|
);
|
||
|
|
||
|
let months = [
|
||
|
"Jan", "Feb", "Mar", "Apr",
|
||
|
"May", "Jun", "Jul", "Aug",
|
||
|
"Sept", "Oct", "Nov", "Dec",
|
||
|
];
|
||
|
|
||
|
if !months.contains(&word) {
|
||
|
let msg = format!("reached end of file without parser leaving {}\n", function_name!());
|
||
|
let msg2 = format!("{word} is not a valid month : expected one of {months:?}\n");
|
||
|
let msg3 = format!("failure location: {cursor:?}");
|
||
|
return Err(format!("{}{}{}", msg, msg2, msg3))
|
||
|
}
|
||
|
|
||
|
word.to_string()
|
||
|
};
|
||
|
|
||
|
let date = {
|
||
|
// check for another word in the file
|
||
|
let (word, cursor) = word_reader.next_word().expect(
|
||
|
format!("reached end of file without parser leaving {}", function_name!()).as_str()
|
||
|
);
|
||
|
|
||
|
let date : u8 = word.to_string().parse().unwrap();
|
||
|
|
||
|
if date > 31 {
|
||
|
let msg = format!("reached end of file without parser leaving {}\n", function_name!());
|
||
|
let msg2 = format!("{word} is not a valid date : must be between 0 and 31\n");
|
||
|
let msg3 = format!("failure location: {cursor:?}");
|
||
|
return Err(format!("{}{}{}", msg, msg2, msg3))
|
||
|
|
||
|
}
|
||
|
|
||
|
word.to_string()
|
||
|
};
|
||
|
|
||
|
let (hh, mm, ss) = {
|
||
|
// check for another word in the file
|
||
|
let (word, cursor) = word_reader.next_word().expect(
|
||
|
format!("reached end of file without parser leaving {}", function_name!()).as_str()
|
||
|
);
|
||
|
|
||
|
let date : u8 = word.to_string().parse().unwrap();
|
||
|
// let hh = take_until(word, b':').unwrap();
|
||
|
|
||
|
if date > 31 {
|
||
|
let msg = format!("reached end of file without parser leaving {}\n", function_name!());
|
||
|
let msg2 = format!("{word} is not a valid date : must be between 0 and 31\n");
|
||
|
let msg3 = format!("failure location: {cursor:?}");
|
||
|
return Err(format!("{}{}{}", msg, msg2, msg3))
|
||
|
|
||
|
}
|
||
|
("", "", "")
|
||
|
};
|
||
|
|
||
|
// else if !parsed_date {
|
||
|
|
||
|
// }
|
||
|
// else if !parsed_hh {
|
||
|
|
||
|
// }
|
||
|
// else if !parsed_mm {
|
||
|
|
||
|
// }
|
||
|
// else if !parsed_ss {
|
||
|
|
||
|
// }
|
||
|
// else if !parsed_year {
|
||
|
|
||
|
// }
|
||
|
// else if !parsed_end {
|
||
|
|
||
|
// }
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
#[named]
|
||
|
fn parse_header(word_reader : &mut WordReader) -> Result<(), String> {
|
||
|
loop {
|
||
|
// check for another word in the file
|
||
|
let word = word_reader.next_word();
|
||
|
|
||
|
// if there isn't another word left in the file, then we exit
|
||
|
if word.is_none() {
|
||
|
return Err(format!("reached end of file without parser leaving {}", function_name!()))
|
||
|
}
|
||
|
|
||
|
// destructure
|
||
|
let (word, cursor) = word.unwrap();
|
||
|
let ident = tag(word, "$");
|
||
|
|
||
|
match tag(word, "$") {
|
||
|
// we hope that this word stars with a `$`
|
||
|
Some(ident) => {
|
||
|
match ident {
|
||
|
"date" => {println!("got date")}
|
||
|
"version" => {println!("got version")}
|
||
|
"timescale" => {println!("got timescale")}
|
||
|
"scope" => {return Ok(())}
|
||
|
_ => {}
|
||
|
}
|
||
|
}
|
||
|
// if not, then we keep looping
|
||
|
None => {}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
// Ok()
|
||
|
}
|
||
|
|
||
|
pub fn parse_vcd(file : File) {
|
||
|
let mut word_gen = WordReader::new(file);
|
||
|
|
||
|
parse_header(&mut word_gen);
|
||
|
}
|