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,
|
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) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue