Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/transform/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,23 +317,33 @@ pub(crate) trait MinCheckLevel {
}

impl CheckLevel {
pub(crate) fn check<T>(&self, op: &str, errors: &[(String, String, T)]) -> anyhow::Result<()>
pub(crate) fn check<'a, T>(
&self,
target: impl Into<Option<&'a str>>,
op: &str,
errors: &[(String, String, T)],
) -> anyhow::Result<()>
where
T: core::fmt::Display + MinCheckLevel,
{
let mut had_breaking_error = false;
let target = target.into().unwrap_or(module_path!());

for (main, other, error) in errors {
let min_check_level = error.min_check_level();

if self >= &min_check_level {
log::error!("{op} {main} and {other}: {error}");
let level = if self >= &min_check_level {
had_breaking_error = true;
log::Level::Error
} else if min_check_level == CheckLevel::Descriptions {
log::debug!("{op} {main} and {other}: {error}");
log::Level::Debug
} else if min_check_level == CheckLevel::Names {
log::Level::Info
} else {
log::warn!("{op} {main} and {other}: {error}");
}
log::Level::Warn
};

log::log!(target: target, level, "{op} {main} and {other}: {error}");
}

if had_breaking_error {
Expand Down Expand Up @@ -391,3 +401,7 @@ where
pub(crate) fn get_true() -> bool {
true
}

pub(crate) fn layout() -> CheckLevel {
CheckLevel::Layout
}
37 changes: 30 additions & 7 deletions src/transform/make_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};

use super::common::*;
use crate::ir::*;
use crate::transform::merge_blocks::block_compat;

#[derive(Debug, Serialize, Deserialize)]
pub struct MakeBlock {
Expand All @@ -13,34 +14,38 @@ pub struct MakeBlock {
pub to_inner: String,
#[serde(default)]
pub array_on_outer: bool,
#[serde(default = "layout")]
pub check: CheckLevel,
}

impl MakeBlock {
pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> {
let mut had_breaking_error = false;

for id in match_all(ir.blocks.keys().cloned(), &self.blocks) {
let b = ir.blocks.get_mut(&id).unwrap();

// Mapping of new item function to existing item functions
let groups = match_groups(
b.items.iter().map(|f| f.name.clone()),
&self.from,
&self.to_outer,
);

for (to, group) in groups {
let b = ir.blocks.get_mut(&id).unwrap();
info!("blockifizing to {}", to);

// Grab all items into a vec
let mut items = Vec::new();
for i in b.items.iter().filter(|i| group.contains(&i.name)) {
items.push(i);
}
let mut items: Vec<_> =
b.items.iter().filter(|i| group.contains(&i.name)).collect();

// Sort by offs
items.sort_by_key(|i| i.byte_offset);
for i in &items {
info!(" {}", i.name);
}

// todo check they're mergeable
// todo check they're not arrays (arrays of arrays not supported)

let byte_offset = items[0].byte_offset;
Expand All @@ -63,9 +68,22 @@ impl MakeBlock {
.collect(),
};

// TODO if destination block exists, check mergeable
let dest = self.to_block.clone(); // todo regex
ir.blocks.insert(dest.clone(), b2);
if let Some(prev) = ir.blocks.insert(dest.clone(), b2.clone()) {
let errors: Vec<_> = block_compat(ir, &prev, &b2)
.into_iter()
.map(|v| (dest.clone(), dest.clone(), v))
.collect();

had_breaking_error |= self
.check
.check(
module_path!(),
&format!("making block {dest} from {group:?}"),
&errors,
)
.is_err();
}

// Remove all items
let b = ir.blocks.get_mut(&id).unwrap();
Expand All @@ -85,6 +103,11 @@ impl MakeBlock {
});
}
}

if had_breaking_error {
anyhow::bail!("Failed to make block")
}

Ok(())
}
}
23 changes: 21 additions & 2 deletions src/transform/make_field_array.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use anyhow::bail;
use anyhow::{bail, Context};
use log::*;
use serde::{Deserialize, Serialize};

use super::common::*;
use crate::ir::*;
use crate::transform::merge_fieldsets::field_compat;

#[derive(Debug, Serialize, Deserialize)]
pub struct MakeFieldArray {
Expand All @@ -12,10 +13,14 @@ pub struct MakeFieldArray {
pub to: String,
#[serde(default)]
pub mode: ArrayMode,
#[serde(default = "layout")]
pub check: CheckLevel,
}

impl MakeFieldArray {
pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> {
let mut errors = Vec::new();

for id in match_all(ir.fieldsets.keys().cloned(), &self.fieldsets) {
let b = ir.fieldsets.get_mut(&id).unwrap();
let groups = match_groups(
Expand All @@ -32,7 +37,16 @@ impl MakeFieldArray {
items.push(i);
}

// todo check they're mergeable
let mut iter = items.iter();
let main = iter.next().unwrap();

for other in iter {
errors.extend(
field_compat(main, other)
.into_iter()
.map(|v| (main.name.clone(), other.name.clone(), v)),
);
}

// one array shouldn't contain both regular and cursed bit_offset type
{
Expand Down Expand Up @@ -74,6 +88,11 @@ impl MakeFieldArray {
b.fields.push(item);
}
}

self.check
.check(module_path!(), "making field arrays", &errors)
.context("failed to make field array")?;

Ok(())
}
}
22 changes: 11 additions & 11 deletions src/transform/make_register_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ pub struct MakeRegisterArray {
pub check: CheckLevel,
}

fn layout() -> CheckLevel {
CheckLevel::Layout
}

impl MakeRegisterArray {
pub fn run(&self, ir: &mut IR) -> anyhow::Result<()> {
let mut errors = Vec::new();

for id in match_all(ir.blocks.keys().cloned(), &self.blocks) {
let b = ir.blocks.get_mut(&id).unwrap();
let mut b = ir.blocks.get(&id).unwrap().clone();
let groups = match_groups(b.items.iter().map(|f| f.name.clone()), &self.from, &self.to);
for (to, group) in groups {
info!("arrayizing to {}", to);
Expand All @@ -36,22 +34,17 @@ impl MakeRegisterArray {
items.push(i);
}

let mut errors = Vec::new();
let mut iter = items.iter();
let main = iter.next().unwrap();

for other in iter {
errors.extend(
block_item_compat(main, other)
block_item_compat(ir, main, other)
.into_iter()
.map(|v| (main.name.clone(), other.name.clone(), v)),
);
}

self.check
.check("making register arrays", &errors)
.context("failed to make register array")?;

// todo check they're not arrays (arrays of arrays not supported)

// Sort by offs
Expand All @@ -74,7 +67,14 @@ impl MakeRegisterArray {
item.byte_offset = offset;
b.items.push(item);
}

ir.blocks.insert(id.clone(), b);
}

self.check
.check(module_path!(), "making/merging register arrays", &errors)
.context("failed to make register array")?;

Ok(())
}
}
Loading