Skip to content

Commit

Permalink
为const-match增加快捷的对捕获进行setres
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Aug 3, 2024
1 parent 0f159bd commit bea2326
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 68 deletions.
8 changes: 4 additions & 4 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.16.20"
version = "0.16.21"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
21 changes: 21 additions & 0 deletions examples/const_match.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@ take For[0 10 (
take For[0 10 2 (
print "b: "_0;
)];


# 在0.16.21版本, 增加了快捷的类似setres的表示方法,
# 使用上类似匹配成功后对匹配到的额外编译一次setres
const Read = (const match @ {
$*Res Addr {
read Res cell1 Addr;
}
});
# 产生的结果类似如下
const Read = (const match @ {
*Res Addr {
setres Res;
read Res cell1 Addr;
}
});

# 注意, 在捕获之后take的话, 除非真的需要,
# 否则尽量避免编写如 `$Res`, 也就是未添加`*`的情况
# 不然按以上的展开示例, 会在setres和之后使用时产生对原始值多次take,
# 这通常不是预期的
2 changes: 1 addition & 1 deletion tools/display_source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "display_source"
version = "0.3.22"
version = "0.3.23"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
13 changes: 13 additions & 0 deletions tools/display_source/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,9 @@ impl DisplaySource for ConstMatchPatAtom {
.map(|pats| !pats.is_empty())
.unwrap_or_default()
|| self.pattern().is_right();
if self.set_res() {
meta.push("$")
}
if self.do_take() {
meta.push("*")
}
Expand Down Expand Up @@ -1131,6 +1134,11 @@ fn display_source_test() {
X @ Y {}
@ Z {}
@ {}
$_ {}
$M {}
$*M {}
$M:[2] {}
$[2] {}
}
"#)
.unwrap()
Expand All @@ -1141,6 +1149,11 @@ fn display_source_test() {
\x20 X @ Y {}\n\
\x20 @ Z {}\n\
\x20 @ {}\n\
\x20 $_ {}\n\
\x20 $M {}\n\
\x20 $*M {}\n\
\x20 $M:[2] {}\n\
\x20 $[2] {}\n\
}\
"
);
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parser"
version = "0.3.18"
version = "0.3.19"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
66 changes: 36 additions & 30 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -405,50 +405,56 @@ ConstMatchPat: ConstMatchPat = {
}

ConstMatchPatAtom: ConstMatchPatAtom = {
<dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<Args1>> => {
ConstMatchPatAtom::new(dotake, name.unwrap_or_default(), pat)
<sr:Opt<"$">> <dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<Args1>> => {
ConstMatchPatAtom::new(dotake, name.unwrap_or_default(), pat, sr)
},
<dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<("?" <OpExprBody>)>> => {
<sr:Opt<"$">> <dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<("?" <OpExprBody>)>> => {
ConstMatchPatAtom::new_guard(
dotake,
name.unwrap_or_default(),
pat.into_value(meta),
sr,
)
},
<dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<("*" <Args0>)>> => {
<sr:Opt<"$">> <dotake:Opt<"*">> <name:(<Var> ":")?> <pat:MList<("*" <Args0>)>> => {
let dexp = DExp::new(meta.unnamed_var(), vec![
LogicLine::from(Match::new(
Args::GLOB_ONLY,
vec![
(
vec![MatchPatAtom::new_unamed(pat)].into(),
vec![
LogicLine::SetResultHandle(
Value::ReprVar("1".into())
),
].into(),
),
(
vec![MatchPatAtom::default()].into(),
vec![
LogicLine::SetResultHandle(
Value::ReprVar("0".into())
),
].into(),
),
]
)),
].into());
ConstMatchPatAtom::new_guard(
dotake,
name.unwrap_or_default(),
DExp::new(meta.unnamed_var(), vec![
LogicLine::from(Match::new(
Args::GLOB_ONLY,
vec![
(
vec![MatchPatAtom::new_unamed(pat)].into(),
vec![
LogicLine::SetResultHandle(
Value::ReprVar("1".into())
),
].into(),
),
(
vec![MatchPatAtom::default()].into(),
vec![
LogicLine::SetResultHandle(
Value::ReprVar("0".into())
),
].into(),
),
]
)),
].into()).into()
dexp.into(),
sr,
)
},
<dotake:Opt<"*">> <name:Var> => {
ConstMatchPatAtom::new(dotake, name, vec![])
<sr:Opt<"$">> <dotake:Opt<"*">> <name:Var> => {
ConstMatchPatAtom::new(dotake, name, vec![], sr)
},
"$" "_" => {
ConstMatchPatAtom::new(false, Default::default(), vec![], true)
},
<dotake:Opt<"*">> "_" => {
ConstMatchPatAtom::new(dotake, Default::default(), vec![])
ConstMatchPatAtom::new(dotake, Default::default(), vec![], false)
},
}

Expand Down
2 changes: 1 addition & 1 deletion tools/parser/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "parser-tests"
version = "0.1.32"
version = "0.1.33"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
118 changes: 118 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5441,6 +5441,124 @@ fn const_match_test() {
"print yes",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$_ {
print body;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print body",
"foo h",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$*M {
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print body",
"print h",
"foo h",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$*M {
setres M;
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print body",
"print h",
"foo h",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$*M:[h] {
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"foo __0",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$*M:[*h] {
setres M;
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print taked",
"print body",
"print h",
"foo h",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$M:[*h] {
setres M;
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print taked",
"print taked",
"print body",
"print taked",
"print h",
"foo h",
],
);

assert_eq!(
CompileMeta::new().compile(parse!(parser, r#"
foo (const match (h: print taked;) {
$M {
setres M;
print body M;
}
});
"#).unwrap()).compile().unwrap(),
vec![
"print taked",
"print taked",
"print body",
"print taked",
"print h",
"foo h",
],
);
}

#[test]
Expand Down
Loading

0 comments on commit bea2326

Please sign in to comment.