Skip to content

Commit

Permalink
添加给label重命名的编译模式, 方便进行一些操作
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Sep 16, 2024
1 parent be07c59 commit fe83cf4
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 42 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.17.1"
version = "0.17.2"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
10 changes: 10 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ enum CompileMode {
MdtTagCodeToMdtLogic,
LintLogic,
IndentLogic,
RenameLabel,
BangToMdtLabel,
}
impl CompileMode {
Expand Down Expand Up @@ -163,6 +164,13 @@ impl CompileMode {
logic_lines.index_label_popup();
format!("{logic_lines:#}")
},
Self::RenameLabel => {
let mut logic_lines = logic_parse(&src);
logic_lines.for_each_inner_label_mut(|mut lab| {
lab.to_mut().push_str("_RENAME");
});
format!("{logic_lines:#}")
},
Self::BangToMdtLabel => {
let ast = build_ast(&src);
let mut meta = compile_ast(ast, src.clone());
Expand Down Expand Up @@ -221,6 +229,7 @@ pub const HELP_MSG: &str = concat_lines! {
"\t", "C: compile MdtTagCode to MdtLogicCode";
"\t", "l: lint MdtLogicCode";
"\t", "i: indent MdtLogicCode";
"\t", "n: rename MdtLogicCode";
"\t", "L: compile MdtBangLang to MdtLabelCode";
;
"input from stdin";
Expand All @@ -243,6 +252,7 @@ impl TryFrom<char> for CompileMode {
'C' => Self::MdtTagCodeToMdtLogic,
'l' => Self::LintLogic,
'i' => Self::IndentLogic,
'n' => Self::RenameLabel,
'L' => Self::BangToMdtLabel,
mode => return Err(mode),
})
Expand Down
2 changes: 1 addition & 1 deletion tools/tag_code/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tag_code"
version = "0.2.1"
version = "0.2.2"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
14 changes: 6 additions & 8 deletions tools/tag_code/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,9 @@ impl<'a> TryFrom<ParseLines<'a>> for TagCodes {
.try_for_each(|label|
{
if lab2idx.insert(*label, lab2idx.len()).is_some() {
return Err(label.as_ref().map(|_| {
ParseTagCodesError::RepeatLabel(
label.to_string()
)
}));
return Err(label.new_value(ParseTagCodesError::RepeatLabel(
label.to_string()
)));
}
Ok(())
})?;
Expand All @@ -501,7 +499,7 @@ impl<'a> TryFrom<ParseLines<'a>> for TagCodes {
lab2idx.get(*lab)
.copied()
.ok_or_else(|| {
lab.as_ref().map(|_| ParseTagCodesError::MissedLabel(
lab.new_value(ParseTagCodesError::MissedLabel(
lab.to_string()
))
})
Expand All @@ -510,11 +508,11 @@ impl<'a> TryFrom<ParseLines<'a>> for TagCodes {
let lines = codes.iter().map(|line| {
match *line.as_ref() {
ParseLine::Label(lab) => {
let tag = get(line.as_ref().map(|_| lab.as_ref()))?;
let tag = get(line.new_value(lab.as_ref()))?;
Ok(TagLine::TagDown(tag))
},
ParseLine::Jump(tgt, args) => {
let tag = get(line.as_ref().map(|_| tgt.as_ref()))?;
let tag = get(line.new_value(tgt.as_ref()))?;
Ok(TagLine::Jump(Jump(tag, args.join(" ")).into()))
},
ParseLine::Args(args) => {
Expand Down
90 changes: 60 additions & 30 deletions tools/tag_code/src/logic_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,22 @@ impl<'a> ParseLine<'a> {
None
}
}

pub fn as_inner_label(&self) -> Option<&str> {
match self {
ParseLine::Label(lab) => Some(lab),
ParseLine::Jump(lab, _) => Some(lab),
ParseLine::Args(_) => None,
}
}

pub fn as_inner_label_mut(&mut self) -> Option<&mut Cow<'a, str>> {
match self {
ParseLine::Label(lab) => Some(lab),
ParseLine::Jump(lab, _) => Some(lab),
ParseLine::Args(_) => None,
}
}
}
impl<'a> TryFrom<Vec<Var>> for ParseLine<'a> {
type Error = <Args<'a> as TryFrom<Vec<Var>>>::Error;
Expand Down Expand Up @@ -414,6 +430,10 @@ impl<T> IdxBox<T> {
let Self { index, value } = self;
Some(IdxBox { index, value: f(value)? })
}

pub fn new_value<U>(&self, new_value: U) -> IdxBox<U> {
self.as_ref().map(|&_| new_value)
}
}
impl<T> Deref for IdxBox<T> {
type Target = T;
Expand Down Expand Up @@ -489,37 +509,47 @@ impl<'a> ParseLines<'a> {
&mut self.lines
}

pub fn index_label_popup(&mut self) {
let mut lines = mem::take(self.lines_mut());
let poped: HashSet<usize> = lines.iter()
.filter_map(|x| x.as_label())
.filter_map(|x| x.parse().ok())
.collect();
let indexs: HashSet<usize> = lines.iter()
.filter_map(|x| x.as_jump_idx())
.collect();
let pop_idxs = &indexs - &poped;
while Some(true) == lines.last()
.map(|x| x.is_label()) // move last label to first
pub fn index_label_popup(&mut self) {
let mut lines = mem::take(self.lines_mut());
let poped: HashSet<usize> = lines.iter()
.filter_map(|x| x.as_label())
.filter_map(|x| x.parse().ok())
.collect();
let indexs: HashSet<usize> = lines.iter()
.filter_map(|x| x.as_jump_idx())
.collect();
let pop_idxs = &indexs - &poped;
while Some(true) == lines.last()
.map(|x| x.is_label()) // move last label to first
{
self.lines.push(lines.pop().unwrap());
}
self.lines.extend(lines.into_iter()
.scan(0, |i, line| {
Some((line.is_solid().then(|| i!(*i++)), line))
})
.flat_map(|(i, line)| {
i.and_then(|i| {
pop_idxs.contains(&i).then(|| {
IdxBox::new(
line.index,
ParseLine::Label(i.to_string().into()),
)
})
}).into_iter().chain(once(line))
})
);
}

pub fn for_each_inner_label_mut<'b, F>(&'b mut self, f: F)
where F: FnMut(IdxBox<&'b mut Cow<'a, str>>),
{
self.lines.push(lines.pop().unwrap());
}
self.lines.extend(lines.into_iter()
.scan(0, |i, line| {
Some((line.is_solid().then(|| i!(*i++)), line))
})
.flat_map(|(i, line)| {
i.and_then(|i| {
pop_idxs.contains(&i).then(|| {
IdxBox::new(
line.index,
ParseLine::Label(i.to_string().into()),
)
})
}).into_iter().chain(once(line))
})
);
}
self.iter_mut()
.filter_map(|line| {
line.as_mut().and_then(ParseLine::as_inner_label_mut)
})
.for_each(f)
}
}
impl<'a> From<Vec<IdxBox<ParseLine<'a>>>> for ParseLines<'a> {
fn from(lines: Vec<IdxBox<ParseLine<'a>>>) -> Self {
Expand Down

0 comments on commit fe83cf4

Please sign in to comment.