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 \ .map_err(ExtractInsnsError::Other)?
and self.text_section.next is not None and \ else {
self.text_section.next.page_num in self.pages: if search_min_y <= self.text_section.min_y.get()
# go to next section && self
self.text_section = self.text_section.next .pages
next_start_min_y = self.text_section.max_y .get(self.text_section.next().page_num)
continue .map_err(ExtractInsnsError::Other)?
else: .is_some()
raise InsnParseError("can't find insn code or description text") {
match next_char.font: // go to next section
case font if font in TextLineFonts.INSN_CODE_FONTS.fonts: self.text_section = self.text_section.next();
next_section = _InsnParseSection.CODE next_start_min_y = self.text_section.max_y.get();
case font if font in TextLineFonts.INSN_DESC_FONTS.fonts: continue;
next_section = _InsnParseSection.DESC } else {
case Font.INSN_HEADER: return Err(ExtractInsnsError::InsnParseError(
next_section = _InsnParseSection.HEADER "can't find insn code or description text".into(),
case font: Backtrace::capture(),
raise InsnParseError(f"can't find insn code or description text\nfont={font}") ));
match next_section: }
case _InsnParseSection.CODE: };
if len(desc_lines) != 0: let next_section = match &next_char.font {
break font if TextLineFonts::InsnCodeFonts.fonts().contains(font) => {
code_line = self.extract_text_line( InsnParseSection::Code
start_char=next_char, }
start_min_y=next_char.min_y, font if TextLineFonts::InsnDescFonts.fonts().contains(font) => {
min_x=next_char.min_x, InsnParseSection::Desc
max_x=self.text_section.max_x, }
fonts=TextLineFonts.INSN_CODE_FONTS, Font::InsnHeader => InsnParseSection::Header,
preceding_blank_lines=0 if len(code_lines) == 0 else 1, font => {
) return Err(ExtractInsnsError::InsnParseError(
if code_line is None: format!("can't find insn code or description text\nfont={font:?}"),
raise InsnParseError("can't find insn code text line") Backtrace::capture(),
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, match next_section {
allowed_start_min_y_error=0.05, InsnParseSection::Code => {
) if !desc_lines.is_empty() {
print("more insn code lines:") break;
print("\n".join(map(str, more_code_lines))) }
code_lines.extend(more_code_lines) let start_min_y = next_char.min_y.get();
next_start_min_y = code_lines[-1].regular_min_y - 5 let min_x = next_char.min_x.get();
case _InsnParseSection.HEADER: let Some(code_line) = self.extract_text_line(
if len(code_lines) != 0 or len(desc_lines) != 0: Some(next_char),
break start_min_y,
header = self.extract_insn_header_mnemonics_and_bit_fields( min_x,
start_min_y=next_char.min_y, self.text_section.max_x.get(),
header_start_char=next_char, TextLineFonts::InsnCodeFonts,
) if code_lines.is_empty() { 0 } else { 1 },
if header is None: false,
raise InsnParseError("can't find header text line") None,
headers.append(header) )?
next_start_min_y = header.min_y - 5 else {
case _InsnParseSection.DESC: return Err(ExtractInsnsError::InsnParseError(
desc_line = self.extract_text_line( "can't find insn code text line".into(),
start_char=next_char, Backtrace::capture(),
start_min_y=next_char.min_y, ));
min_x=next_char.min_x, };
max_x=self.text_section.max_x, let min_x = code_line.chars[0].min_x.get();
fonts=TextLineFonts.INSN_DESC_FONTS, let more_code_lines = self.extract_following_text_lines(
preceding_blank_lines=0 if len(desc_lines) == 0 else 1, code_line,
allowed_start_min_y_error=3, min_x,
) self.text_section.max_x.get(),
if desc_line is None: Some(0.05),
raise InsnParseError("can't find insn desc text line") )?;
match desc_line.get_header_text(): println!("more insn code lines:");
case None: for i in &more_code_lines {
more_desc_lines = self.extract_following_text_lines( println!("{i}");
first_text_line=desc_line, }
min_x=desc_line.chars[0].min_x, code_lines.extend(more_code_lines);
max_x=self.text_section.max_x, let Some(last) = code_lines.last() else {
allowed_start_min_y_error=3.5, unreachable!()
) };
print("more insn desc lines:") next_start_min_y = last.regular_min_y - 5.0;
print("\n".join(map(str, more_desc_lines))) }
desc_lines.extend(more_desc_lines) InsnParseSection::Header => {
next_start_min_y = desc_lines[-1].regular_min_y - 5 if !(code_lines.is_empty() && desc_lines.is_empty()) {
case "Special Registers Altered:": break;
sp_regs_altered = self.extract_insn_sp_regs_altered( }
sp_regs_altered_text=desc_line, let Some(header) = self.extract_insn_header_mnemonics_and_bit_fields(
) next_char.min_y.get(),
next_start_min_y = sp_regs_altered.final_regular_min_y Some(next_char),
break )?
case header_text: else {
raise AssertionError(f"unhandled header text: {header_text!r}\n{desc_line}") return Err(ExtractInsnsError::InsnParseError(
case _: "can't find header text line".into(),
assert_never(next_section) 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:") println!("insn code lines:");
print("\n".join(map(str, code_lines))) for i in &code_lines {
print("insn desc lines:") println!("{i}");
print("\n".join(map(str, desc_lines))) }
print("sp_regs_altered:") println!("insn desc lines:");
print(sp_regs_altered) for i in &desc_lines {
# TODO: finish println!("{i}");
return Insn( }
headers=tuple(headers), println!("sp_regs_altered:");
code_lines=tuple(code_lines), println!("{sp_regs_altered:?}");
desc_lines=tuple(desc_lines), // TODO: finish
sp_regs_altered=sp_regs_altered, return Ok(Insn {
) headers,
}*/ code_lines,
desc_lines,
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) =