Expand Stat parsing to cover all fields
Also in this commit: taking nom for a spin.
This commit is contained in:
Generated
+23
@@ -7,6 +7,7 @@ name = "assembler"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"nom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -14,3 +15,25 @@ name = "byteorder"
|
|||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
|
nom = "7.1.3"
|
||||||
|
|||||||
+60
-13
@@ -1,4 +1,10 @@
|
|||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::take,
|
||||||
|
number::complete::{le_i16, le_u8},
|
||||||
|
sequence::tuple,
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
use std::{env, error::Error, fs, process::exit};
|
use std::{env, error::Error, fs, process::exit};
|
||||||
|
|
||||||
struct World {
|
struct World {
|
||||||
@@ -14,7 +20,20 @@ struct Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Stat {
|
struct Stat {
|
||||||
info: Vec<u8>,
|
x: u8,
|
||||||
|
y: u8,
|
||||||
|
x_step: i16,
|
||||||
|
y_step: i16,
|
||||||
|
cycle: i16,
|
||||||
|
p1: u8,
|
||||||
|
p2: u8,
|
||||||
|
p3: u8,
|
||||||
|
follower: i16,
|
||||||
|
leader: i16,
|
||||||
|
under_element: u8,
|
||||||
|
under_color: u8,
|
||||||
|
instruction_pointer: i16,
|
||||||
|
bind_index: i16,
|
||||||
code: Vec<u8>,
|
code: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,18 +93,10 @@ impl Board {
|
|||||||
u16::from_le_bytes((&bytes[offset..offset + 2]).try_into().unwrap()) as usize + 1;
|
u16::from_le_bytes((&bytes[offset..offset + 2]).try_into().unwrap()) as usize + 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
let mut stats = Vec::with_capacity(num_stats);
|
let mut stats = Vec::with_capacity(num_stats);
|
||||||
|
let mut input = &bytes[offset..];
|
||||||
for _ in 0..num_stats {
|
for _ in 0..num_stats {
|
||||||
let mut stat = Stat {
|
let (next_input, stat) = Stat::parse(input).map_err(|e| e.to_owned())?;
|
||||||
info: Vec::from(&bytes[offset..offset + 25]),
|
input = next_input;
|
||||||
code: vec![],
|
|
||||||
};
|
|
||||||
offset += 25 + 8;
|
|
||||||
let code_len = i16::from_le_bytes((&stat.info[23..25]).try_into().unwrap());
|
|
||||||
if code_len > 0 {
|
|
||||||
let code_len = code_len as usize;
|
|
||||||
stat.code = Vec::from(&bytes[offset..offset + code_len]);
|
|
||||||
offset += code_len;
|
|
||||||
}
|
|
||||||
stats.push(stat);
|
stats.push(stat);
|
||||||
}
|
}
|
||||||
Ok(Board {
|
Ok(Board {
|
||||||
@@ -97,6 +108,39 @@ impl Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Stat {
|
||||||
|
fn parse(input: &[u8]) -> IResult<&[u8], Self> {
|
||||||
|
let (input, (x, y, x_step, y_step)) = tuple((le_u8, le_u8, le_i16, le_i16))(input)?;
|
||||||
|
let (input, (cycle, p1, p2, p3)) = tuple((le_i16, le_u8, le_u8, le_u8))(input)?;
|
||||||
|
let (input, (follower, leader)) = tuple((le_i16, le_i16))(input)?;
|
||||||
|
let (input, (under_element, under_color)) = tuple((le_u8, le_u8))(input)?;
|
||||||
|
let (input, _) = take(4usize)(input)?;
|
||||||
|
let (input, (instruction_pointer, length)) = tuple((le_i16, le_i16))(input)?;
|
||||||
|
let (input, _) = take(8usize)(input)?;
|
||||||
|
let (input, code) = take(0.max(length) as usize)(input)?;
|
||||||
|
Ok((
|
||||||
|
input,
|
||||||
|
Stat {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x_step,
|
||||||
|
y_step,
|
||||||
|
follower,
|
||||||
|
leader,
|
||||||
|
cycle,
|
||||||
|
p1,
|
||||||
|
p2,
|
||||||
|
p3,
|
||||||
|
under_element,
|
||||||
|
under_color,
|
||||||
|
instruction_pointer,
|
||||||
|
bind_index: 0.min(length),
|
||||||
|
code: Vec::from(code),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_latin1(bytes: &[u8]) -> String {
|
fn to_latin1(bytes: &[u8]) -> String {
|
||||||
bytes.iter().map(|&x| x as char).collect()
|
bytes.iter().map(|&x| x as char).collect()
|
||||||
}
|
}
|
||||||
@@ -111,11 +155,14 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let bytes = fs::read(&args[1])?;
|
let bytes = fs::read(&args[1])?;
|
||||||
let world = World::from(&bytes)?;
|
let world = World::from(&bytes)?;
|
||||||
|
|
||||||
|
// Print some of the data parsed.
|
||||||
|
// TODO: Implement some macros, or other code modification
|
||||||
|
// Then, we can try writing a copy to disk.
|
||||||
println!("num boards: {}", &world.boards.len());
|
println!("num boards: {}", &world.boards.len());
|
||||||
for board in &world.boards {
|
for board in &world.boards {
|
||||||
println!("board: {}", to_latin1(&board.name));
|
println!("board: {}", to_latin1(&board.name));
|
||||||
for stat in &board.stats {
|
for stat in &board.stats {
|
||||||
let (x, y) = (stat.info[0] as usize, stat.info[1] as usize);
|
let (x, y) = (stat.x as usize, stat.y as usize);
|
||||||
println!(
|
println!(
|
||||||
" stat at ({}, {}): {:?}, {:?}",
|
" stat at ({}, {}): {:?}, {:?}",
|
||||||
x,
|
x,
|
||||||
|
|||||||
Reference in New Issue
Block a user