This commit is contained in:
Jacob Lifshay 2026-01-05 09:41:56 -08:00
parent 3d66c853f6
commit c58bc23904
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -2942,132 +2942,200 @@ impl Parser {
final_regular_min_y: regular_min_y, 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); assert_eq!(header_start_char.font, Font::InsnHeader);
println!("{header_start_char:?}"); println!("{header_start_char:?}");
let Some(header) = self.extract_insn_header_mnemonics_and_bit_fields( let Some(header) = self.extract_insn_header_mnemonics_and_bit_fields(
header_start_char.min_y.get(), header_start_char.min_y.get(),
header_start_char, Some(header_start_char),
)? else { )?
return Err(ExtractInsnsError::PageParseError("can't find header text line".into(), Backtrace::capture())); 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 headers = vec![header];
let mut code_lines: Vec<ParsedTextLine> = Vec::new(); let mut code_lines: Vec<ParsedTextLine> = Vec::new();
let mut desc_lines: Vec<ParsedTextLine> = Vec::new(); let mut desc_lines: Vec<ParsedTextLine> = Vec::new();
let mut sp_regs_altered = None; let mut sp_regs_altered = None;
loop { loop {
let search_min_y = next_start_min_y - 70.0; let search_min_y = next_start_min_y - 70.0;
let Some(next_char) = self.find_top_left_char_in_range( let Some(next_char) = self
min_x=self.text_section.min_x.get() - 5.0, .find_top_left_char_in_range(
max_x=self.text_section.max_x.get() + 5.0, self.text_section.min_x.get() - 5.0,
min_y=max(search_min_y, self.text_section.min_y), self.text_section.max_x.get() + 5.0,
max_y=next_start_min_y, search_min_y.max(self.text_section.min_y.get()),
allow_processed=False, next_start_min_y,
)?; 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: .map_err(ExtractInsnsError::Other)?
raise InsnParseError("can't find insn code text line") else {
more_code_lines = self.extract_following_text_lines( if search_min_y <= self.text_section.min_y.get()
first_text_line=code_line, && self
min_x=code_line.chars[0].min_x, .pages
max_x=self.text_section.max_x, .get(self.text_section.next().page_num)
allowed_start_min_y_error=0.05, .map_err(ExtractInsnsError::Other)?
) .is_some()
print("more insn code lines:") {
print("\n".join(map(str, more_code_lines))) // go to next section
code_lines.extend(more_code_lines) self.text_section = self.text_section.next();
next_start_min_y = code_lines[-1].regular_min_y - 5 next_start_min_y = self.text_section.max_y.get();
case _InsnParseSection.HEADER: continue;
if len(code_lines) != 0 or len(desc_lines) != 0: } else {
break return Err(ExtractInsnsError::InsnParseError(
header = self.extract_insn_header_mnemonics_and_bit_fields( "can't find insn code or description text".into(),
start_min_y=next_char.min_y, Backtrace::capture(),
header_start_char=next_char, ));
) }
if header is None: };
raise InsnParseError("can't find header text line") let next_section = match &next_char.font {
headers.append(header) font if TextLineFonts::InsnCodeFonts.fonts().contains(font) => {
next_start_min_y = header.min_y - 5 InsnParseSection::Code
case _InsnParseSection.DESC: }
desc_line = self.extract_text_line( font if TextLineFonts::InsnDescFonts.fonts().contains(font) => {
start_char=next_char, InsnParseSection::Desc
start_min_y=next_char.min_y, }
min_x=next_char.min_x, Font::InsnHeader => InsnParseSection::Header,
max_x=self.text_section.max_x, font => {
fonts=TextLineFonts.INSN_DESC_FONTS, return Err(ExtractInsnsError::InsnParseError(
preceding_blank_lines=0 if len(desc_lines) == 0 else 1, format!("can't find insn code or description text\nfont={font:?}"),
allowed_start_min_y_error=3, Backtrace::capture(),
) ));
if desc_line is None: }
raise InsnParseError("can't find insn desc text line") };
match desc_line.get_header_text(): match next_section {
case None: InsnParseSection::Code => {
more_desc_lines = self.extract_following_text_lines( if !desc_lines.is_empty() {
first_text_line=desc_line, break;
min_x=desc_line.chars[0].min_x, }
max_x=self.text_section.max_x, let start_min_y = next_char.min_y.get();
allowed_start_min_y_error=3.5, let min_x = next_char.min_x.get();
) let Some(code_line) = self.extract_text_line(
print("more insn desc lines:") Some(next_char),
print("\n".join(map(str, more_desc_lines))) start_min_y,
desc_lines.extend(more_desc_lines) min_x,
next_start_min_y = desc_lines[-1].regular_min_y - 5 self.text_section.max_x.get(),
case "Special Registers Altered:": TextLineFonts::InsnCodeFonts,
sp_regs_altered = self.extract_insn_sp_regs_altered( if code_lines.is_empty() { 0 } else { 1 },
sp_regs_altered_text=desc_line, false,
) None,
next_start_min_y = sp_regs_altered.final_regular_min_y )?
break else {
case header_text: return Err(ExtractInsnsError::InsnParseError(
raise AssertionError(f"unhandled header text: {header_text!r}\n{desc_line}") "can't find insn code text line".into(),
case _: Backtrace::capture(),
assert_never(next_section) ));
};
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(),
));
}
}
}
}
}
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,
});
} }
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,
)
}*/
fn extract_insns(&mut self) -> Result<(), ExtractInsnsError> { fn extract_insns(&mut self) -> Result<(), ExtractInsnsError> {
loop { loop {
let Some(header_start_char) = let Some(header_start_char) =