Skip to content

Commit 100bae4

Browse files
committed
修复在某些情况下const内部被跳转标签重命名目标已存在, 删除未使用的语句End
1 parent 17b9a6f commit 100bae4

File tree

3 files changed

+75
-17
lines changed

3 files changed

+75
-17
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mindustry_logic_bang_lang"
3-
version = "0.4.2"
3+
version = "0.4.3"
44
edition = "2021"
55

66
authors = ["A4-Tacks <wdsjxhno1001@163.com>"]

src/syntax.rs

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ impl Value {
111111
Self::DExp(DExp { mut result, lines }) => {
112112
if result.is_empty() {
113113
result = meta.get_tmp_var(); /* init tmp_var */
114-
} else if let Some((_, _, value)) = meta.get_const_value(&result) {
114+
} else if let
115+
Some((_, _, value))
116+
= meta.get_const_value_and_add(&result) {
115117
// 对返回句柄使用常量值的处理
116118
if let Some(dexp) = value.as_dexp() {
117119
err!(
@@ -646,7 +648,6 @@ pub enum LogicLine {
646648
Other(Vec<Value>),
647649
Expand(Expand),
648650
Select(Select),
649-
End,
650651
NoOp,
651652
/// 空语句, 什么也不生成
652653
Ignore,
@@ -656,7 +657,6 @@ pub enum LogicLine {
656657
impl Compile for LogicLine {
657658
fn compile(self, meta: &mut CompileMeta) {
658659
match self {
659-
Self::End => meta.push("end".into()),
660660
Self::NoOp => meta.push("noop".into()),
661661
Self::Label(mut lab) => {
662662
// 如果在常量展开中, 尝试将这个标记替换
@@ -915,23 +915,46 @@ impl CompileMeta {
915915
self.const_var_namespace.pop().unwrap()
916916
}
917917

918-
/// 获取一个常量到值的使用次数与映射与其内部标记,
918+
/// 获取一个常量到值的使用次数与映射与其内部标记的引用,
919919
/// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
920-
pub fn get_const_value(&mut self, name: &Var) -> Option<(usize, &Vec<Var>, &Value)> {
920+
pub fn get_const_value(&self, name: &Var) -> Option<&(usize, Vec<Var>, Value)> {
921+
self.const_var_namespace
922+
.iter()
923+
.rev()
924+
.find_map(|namespace| {
925+
namespace.get(name)
926+
})
927+
}
928+
929+
/// 获取一个常量到值的使用次数与映射与其内部标记的可变引用,
930+
/// 从当前作用域往顶层作用域一层层找, 都没找到就返回空
931+
pub fn get_const_value_mut(&mut self, name: &Var)
932+
-> Option<&mut (usize, Vec<Var>, Value)> {
921933
self.const_var_namespace
922934
.iter_mut()
923935
.rev()
924936
.find_map(|namespace| {
925-
namespace
926-
.get_mut(name)
927-
.map(|(count, labels, value)| {
928-
let this_count = *count;
929-
*count += 1;
930-
(this_count, &*labels, &*value)
931-
})
937+
namespace.get_mut(name)
932938
})
933939
}
934940

941+
/// 调用[`Self::get_const_value_mut_and_add`]
942+
/// 并将返回结果转换为不可变引用
943+
pub fn get_const_value_and_add(&mut self, name: &Var)
944+
-> Option<&(usize, Vec<Var>, Value)> {
945+
self.get_const_value_mut_and_add(name)
946+
.map(|x| &*x)
947+
}
948+
949+
/// 调用[`Self::get_const_value_mut`], 但是非空情况会给使用计数加一
950+
pub fn get_const_value_mut_and_add(&mut self, name: &Var)
951+
-> Option<&mut (usize, Vec<Var>, Value)> {
952+
self.get_const_value_mut(name).map(|x| {
953+
x.0 += 1;
954+
x
955+
})
956+
}
957+
935958
/// 新增一个常量到值的映射, 如果当前作用域已有此映射则返回旧的值并插入新值
936959
pub fn add_const_value(&mut self, Const(var, value, labels): Const)
937960
-> Option<(usize, Vec<Var>, Value)> {
@@ -995,10 +1018,22 @@ impl CompileMeta {
9951018
/// 这个函数会直接调用获取函数将标记映射完毕, 然后返回其值
9961019
/// 如果不是一个宏则直接返回None, 也不会进入无需清理
9971020
pub fn const_expand_enter(&mut self, name: &Var) -> Option<Value> {
998-
let (count, labels, value) = self.get_const_value(name)?;
1021+
let label_count = self.get_const_value(name)?.1.len();
1022+
let mut tmp_tags = Vec::with_capacity(label_count);
1023+
tmp_tags.extend(repeat_with(|| self.get_tmp_tag())
1024+
.take(label_count));
1025+
1026+
let (count, labels, value)
1027+
= self.get_const_value_and_add(name).unwrap();
9991028
let mut labels_map = HashMap::with_capacity(labels.len());
1000-
for label in labels.iter().cloned() {
1001-
let maped_label = format!("__const_{}_{}_{}", &name, count, &label);
1029+
for (tmp_tag, label) in zip(tmp_tags, labels.iter().cloned()) {
1030+
let maped_label = format!(
1031+
"{}_const_{}_{}_{}",
1032+
tmp_tag,
1033+
&name,
1034+
count,
1035+
&label
1036+
);
10021037
labels_map.insert(label, maped_label);
10031038
}
10041039
let res = value.clone();
@@ -1726,4 +1761,27 @@ mod tests {
17261761
"print R",
17271762
]);
17281763
}
1764+
1765+
#[test]
1766+
fn in_const_const_label_rename_test() {
1767+
let parser = ExpandParser::new();
1768+
1769+
let ast = parse!(parser, r#"
1770+
const X = (
1771+
const X = (
1772+
i = 0;
1773+
do {
1774+
op i i + 1;
1775+
} while i < 10;
1776+
);
1777+
take __ = X;
1778+
take __ = X;
1779+
);
1780+
take __ = X;
1781+
take __ = X;
1782+
"#).unwrap();
1783+
let meta = CompileMeta::new();
1784+
let mut tag_codes = meta.compile(ast);
1785+
let _logic_lines = tag_codes.compile().unwrap();
1786+
}
17291787
}

0 commit comments

Comments
 (0)