wip
This commit is contained in:
parent
3d66c853f6
commit
c58bc23904
1 changed files with 182 additions and 114 deletions
296
src/main.rs
296
src/main.rs
|
|
@ -2942,132 +2942,200 @@ impl Parser {
|
|||
final_regular_min_y: regular_min_y,
|
||||
});
|
||||
}
|
||||
/*fn extract_insn(&mut self, header_start_char: Char) -> Result<Insn, ExtractInsnsError> {
|
||||
fn extract_insn(&mut self, header_start_char: Char) -> Result<Insn, ExtractInsnsError> {
|
||||
assert_eq!(header_start_char.font, Font::InsnHeader);
|
||||
println!("{header_start_char:?}");
|
||||
let Some(header) = self.extract_insn_header_mnemonics_and_bit_fields(
|
||||
header_start_char.min_y.get(),
|
||||
header_start_char,
|
||||
)? else {
|
||||
return Err(ExtractInsnsError::PageParseError("can't find header text line".into(), Backtrace::capture()));
|
||||
Some(header_start_char),
|
||||
)?
|
||||
else {
|
||||
return Err(ExtractInsnsError::PageParseError(
|
||||
"can't find header text line".into(),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
};
|
||||
let next_start_min_y = header.min_y.get() - 5.0;
|
||||
let mut next_start_min_y = header.min_y() - 5.0;
|
||||
let mut headers = vec![header];
|
||||
let mut code_lines: Vec<ParsedTextLine> = Vec::new();
|
||||
let mut desc_lines: Vec<ParsedTextLine> = Vec::new();
|
||||
let mut sp_regs_altered = None;
|
||||
loop {
|
||||
let search_min_y = next_start_min_y - 70.0;
|
||||
let Some(next_char) = self.find_top_left_char_in_range(
|
||||
min_x=self.text_section.min_x.get() - 5.0,
|
||||
max_x=self.text_section.max_x.get() + 5.0,
|
||||
min_y=max(search_min_y, self.text_section.min_y),
|
||||
max_y=next_start_min_y,
|
||||
allow_processed=False,
|
||||
)?;
|
||||
if next_char is None:
|
||||
if search_min_y <= self.text_section.min_y \
|
||||
and self.text_section.next is not None and \
|
||||
self.text_section.next.page_num in self.pages:
|
||||
# go to next section
|
||||
self.text_section = self.text_section.next
|
||||
next_start_min_y = self.text_section.max_y
|
||||
continue
|
||||
else:
|
||||
raise InsnParseError("can't find insn code or description text")
|
||||
match next_char.font:
|
||||
case font if font in TextLineFonts.INSN_CODE_FONTS.fonts:
|
||||
next_section = _InsnParseSection.CODE
|
||||
case font if font in TextLineFonts.INSN_DESC_FONTS.fonts:
|
||||
next_section = _InsnParseSection.DESC
|
||||
case Font.INSN_HEADER:
|
||||
next_section = _InsnParseSection.HEADER
|
||||
case font:
|
||||
raise InsnParseError(f"can't find insn code or description text\nfont={font}")
|
||||
match next_section:
|
||||
case _InsnParseSection.CODE:
|
||||
if len(desc_lines) != 0:
|
||||
break
|
||||
code_line = self.extract_text_line(
|
||||
start_char=next_char,
|
||||
start_min_y=next_char.min_y,
|
||||
min_x=next_char.min_x,
|
||||
max_x=self.text_section.max_x,
|
||||
fonts=TextLineFonts.INSN_CODE_FONTS,
|
||||
preceding_blank_lines=0 if len(code_lines) == 0 else 1,
|
||||
)
|
||||
if code_line is None:
|
||||
raise InsnParseError("can't find insn code text line")
|
||||
more_code_lines = self.extract_following_text_lines(
|
||||
first_text_line=code_line,
|
||||
min_x=code_line.chars[0].min_x,
|
||||
max_x=self.text_section.max_x,
|
||||
allowed_start_min_y_error=0.05,
|
||||
)
|
||||
print("more insn code lines:")
|
||||
print("\n".join(map(str, more_code_lines)))
|
||||
code_lines.extend(more_code_lines)
|
||||
next_start_min_y = code_lines[-1].regular_min_y - 5
|
||||
case _InsnParseSection.HEADER:
|
||||
if len(code_lines) != 0 or len(desc_lines) != 0:
|
||||
break
|
||||
header = self.extract_insn_header_mnemonics_and_bit_fields(
|
||||
start_min_y=next_char.min_y,
|
||||
header_start_char=next_char,
|
||||
)
|
||||
if header is None:
|
||||
raise InsnParseError("can't find header text line")
|
||||
headers.append(header)
|
||||
next_start_min_y = header.min_y - 5
|
||||
case _InsnParseSection.DESC:
|
||||
desc_line = self.extract_text_line(
|
||||
start_char=next_char,
|
||||
start_min_y=next_char.min_y,
|
||||
min_x=next_char.min_x,
|
||||
max_x=self.text_section.max_x,
|
||||
fonts=TextLineFonts.INSN_DESC_FONTS,
|
||||
preceding_blank_lines=0 if len(desc_lines) == 0 else 1,
|
||||
allowed_start_min_y_error=3,
|
||||
)
|
||||
if desc_line is None:
|
||||
raise InsnParseError("can't find insn desc text line")
|
||||
match desc_line.get_header_text():
|
||||
case None:
|
||||
more_desc_lines = self.extract_following_text_lines(
|
||||
first_text_line=desc_line,
|
||||
min_x=desc_line.chars[0].min_x,
|
||||
max_x=self.text_section.max_x,
|
||||
allowed_start_min_y_error=3.5,
|
||||
)
|
||||
print("more insn desc lines:")
|
||||
print("\n".join(map(str, more_desc_lines)))
|
||||
desc_lines.extend(more_desc_lines)
|
||||
next_start_min_y = desc_lines[-1].regular_min_y - 5
|
||||
case "Special Registers Altered:":
|
||||
sp_regs_altered = self.extract_insn_sp_regs_altered(
|
||||
sp_regs_altered_text=desc_line,
|
||||
)
|
||||
next_start_min_y = sp_regs_altered.final_regular_min_y
|
||||
break
|
||||
case header_text:
|
||||
raise AssertionError(f"unhandled header text: {header_text!r}\n{desc_line}")
|
||||
case _:
|
||||
assert_never(next_section)
|
||||
let Some(next_char) = self
|
||||
.find_top_left_char_in_range(
|
||||
self.text_section.min_x.get() - 5.0,
|
||||
self.text_section.max_x.get() + 5.0,
|
||||
search_min_y.max(self.text_section.min_y.get()),
|
||||
next_start_min_y,
|
||||
false,
|
||||
)
|
||||
.map_err(ExtractInsnsError::Other)?
|
||||
else {
|
||||
if search_min_y <= self.text_section.min_y.get()
|
||||
&& self
|
||||
.pages
|
||||
.get(self.text_section.next().page_num)
|
||||
.map_err(ExtractInsnsError::Other)?
|
||||
.is_some()
|
||||
{
|
||||
// go to next section
|
||||
self.text_section = self.text_section.next();
|
||||
next_start_min_y = self.text_section.max_y.get();
|
||||
continue;
|
||||
} else {
|
||||
return Err(ExtractInsnsError::InsnParseError(
|
||||
"can't find insn code or description text".into(),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
}
|
||||
};
|
||||
let next_section = match &next_char.font {
|
||||
font if TextLineFonts::InsnCodeFonts.fonts().contains(font) => {
|
||||
InsnParseSection::Code
|
||||
}
|
||||
font if TextLineFonts::InsnDescFonts.fonts().contains(font) => {
|
||||
InsnParseSection::Desc
|
||||
}
|
||||
Font::InsnHeader => InsnParseSection::Header,
|
||||
font => {
|
||||
return Err(ExtractInsnsError::InsnParseError(
|
||||
format!("can't find insn code or description text\nfont={font:?}"),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
}
|
||||
};
|
||||
match next_section {
|
||||
InsnParseSection::Code => {
|
||||
if !desc_lines.is_empty() {
|
||||
break;
|
||||
}
|
||||
let start_min_y = next_char.min_y.get();
|
||||
let min_x = next_char.min_x.get();
|
||||
let Some(code_line) = self.extract_text_line(
|
||||
Some(next_char),
|
||||
start_min_y,
|
||||
min_x,
|
||||
self.text_section.max_x.get(),
|
||||
TextLineFonts::InsnCodeFonts,
|
||||
if code_lines.is_empty() { 0 } else { 1 },
|
||||
false,
|
||||
None,
|
||||
)?
|
||||
else {
|
||||
return Err(ExtractInsnsError::InsnParseError(
|
||||
"can't find insn code text line".into(),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
};
|
||||
let min_x = code_line.chars[0].min_x.get();
|
||||
let more_code_lines = self.extract_following_text_lines(
|
||||
code_line,
|
||||
min_x,
|
||||
self.text_section.max_x.get(),
|
||||
Some(0.05),
|
||||
)?;
|
||||
println!("more insn code lines:");
|
||||
for i in &more_code_lines {
|
||||
println!("{i}");
|
||||
}
|
||||
code_lines.extend(more_code_lines);
|
||||
let Some(last) = code_lines.last() else {
|
||||
unreachable!()
|
||||
};
|
||||
next_start_min_y = last.regular_min_y - 5.0;
|
||||
}
|
||||
InsnParseSection::Header => {
|
||||
if !(code_lines.is_empty() && desc_lines.is_empty()) {
|
||||
break;
|
||||
}
|
||||
let Some(header) = self.extract_insn_header_mnemonics_and_bit_fields(
|
||||
next_char.min_y.get(),
|
||||
Some(next_char),
|
||||
)?
|
||||
else {
|
||||
return Err(ExtractInsnsError::InsnParseError(
|
||||
"can't find header text line".into(),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
};
|
||||
next_start_min_y = header.min_y() - 5.0;
|
||||
headers.push(header);
|
||||
}
|
||||
InsnParseSection::Desc => {
|
||||
let start_min_y = next_char.min_y.get();
|
||||
let min_x = next_char.min_x.get();
|
||||
let Some(desc_line) = self.extract_text_line(
|
||||
Some(next_char),
|
||||
start_min_y,
|
||||
min_x,
|
||||
self.text_section.max_x.get(),
|
||||
TextLineFonts::InsnDescFonts,
|
||||
if desc_lines.is_empty() { 0 } else { 1 },
|
||||
false,
|
||||
Some(3.0),
|
||||
)?
|
||||
else {
|
||||
return Err(ExtractInsnsError::InsnParseError(
|
||||
"can't find insn desc text line".into(),
|
||||
Backtrace::capture(),
|
||||
));
|
||||
};
|
||||
match desc_line.get_header_text() {
|
||||
None => {
|
||||
let min_x = desc_line.chars[0].min_x.get();
|
||||
let more_desc_lines = self.extract_following_text_lines(
|
||||
desc_line,
|
||||
min_x,
|
||||
self.text_section.max_x.get(),
|
||||
Some(3.5),
|
||||
)?;
|
||||
println!("more insn desc lines:");
|
||||
for i in &more_desc_lines {
|
||||
println!("{i}");
|
||||
}
|
||||
desc_lines.extend(more_desc_lines);
|
||||
next_start_min_y = desc_lines
|
||||
.last()
|
||||
.expect("known to be non-empty")
|
||||
.regular_min_y
|
||||
- 5.0;
|
||||
}
|
||||
Some(header_text) if header_text == "Special Registers Altered:" => {
|
||||
let new_sp_regs_altered =
|
||||
self.extract_insn_sp_regs_altered(desc_line)?;
|
||||
next_start_min_y = new_sp_regs_altered.final_regular_min_y;
|
||||
sp_regs_altered = Some(new_sp_regs_altered);
|
||||
break;
|
||||
}
|
||||
Some(header_text) => {
|
||||
return Err(ExtractInsnsError::Other(
|
||||
format!("unhandled header text: {header_text:?}\n{desc_line}")
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print("insn code lines:")
|
||||
print("\n".join(map(str, code_lines)))
|
||||
print("insn desc lines:")
|
||||
print("\n".join(map(str, desc_lines)))
|
||||
print("sp_regs_altered:")
|
||||
print(sp_regs_altered)
|
||||
# TODO: finish
|
||||
return Insn(
|
||||
headers=tuple(headers),
|
||||
code_lines=tuple(code_lines),
|
||||
desc_lines=tuple(desc_lines),
|
||||
sp_regs_altered=sp_regs_altered,
|
||||
)
|
||||
}*/
|
||||
println!("insn code lines:");
|
||||
for i in &code_lines {
|
||||
println!("{i}");
|
||||
}
|
||||
println!("insn desc lines:");
|
||||
for i in &desc_lines {
|
||||
println!("{i}");
|
||||
}
|
||||
println!("sp_regs_altered:");
|
||||
println!("{sp_regs_altered:?}");
|
||||
// TODO: finish
|
||||
return Ok(Insn {
|
||||
headers,
|
||||
code_lines,
|
||||
desc_lines,
|
||||
sp_regs_altered,
|
||||
});
|
||||
}
|
||||
fn extract_insns(&mut self) -> Result<(), ExtractInsnsError> {
|
||||
loop {
|
||||
let Some(header_start_char) =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue