From fb0fd28cbe57981d9938cb715fe95e1c9a61e949 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 28 Oct 2024 19:12:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=AF=94=E8=BE=83=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E6=B2=A1=E6=9C=89=E5=B0=81=E9=97=AD=E5=8F=82=E6=95=B0?= =?UTF-8?q?,=20=E7=BB=9F=E4=B8=80match=E8=AE=BE=E7=BD=AE=E5=8E=9F=E5=A7=8B?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 设置原始参数不包括重复块 --- Cargo.lock | 6 +-- Cargo.toml | 2 +- examples/builtin_functions.mdtlbl | 3 +- examples/match.mdtlbl | 8 +++- tools/parser/tests/Cargo.toml | 2 +- tools/parser/tests/src/lib.rs | 62 +++++++++++++++++++++++++++++++ tools/syntax/Cargo.toml | 2 +- tools/syntax/src/lib.rs | 37 +++++++++++++----- 8 files changed, 103 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 513963b..32435aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,7 +284,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mindustry_logic_bang_lang" -version = "0.17.8" +version = "0.17.9" dependencies = [ "display_source", "logic_lint", @@ -341,7 +341,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.37" +version = "0.1.38" dependencies = [ "either", "parser", @@ -530,7 +530,7 @@ dependencies = [ [[package]] name = "syntax" -version = "0.2.42" +version = "0.2.43" dependencies = [ "either", "itermaps", diff --git a/Cargo.toml b/Cargo.toml index 0c742ac..a35202a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.17.8" +version = "0.17.9" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/builtin_functions.mdtlbl b/examples/builtin_functions.mdtlbl index 3ba4bef..edd36bc 100644 --- a/examples/builtin_functions.mdtlbl +++ b/examples/builtin_functions.mdtlbl @@ -10,7 +10,8 @@ * * `Info[var]`: 以info级日志形式将传入Var输出 * * `Err[var]`: 以err级日志形式将传入Var输出 * * `Unbind[var]`: 传入一个值绑定, 返回绑定者 -* * `Const[name value]`: 动态目标的进行一个const, 并泄露到上层 +* * `Const[name value]`: 动态目标的进行一个const, 并泄露到上层, +* 调用者需要保证被泄漏的expand不会展开次数不同, 比如直接位于重复块中操作重复块外 * * `Binder[name value]`: 传入一个值绑定, 将其被绑定值const给给定名称 * * `BindHandle[value]`: 直接获取值绑定的句柄, 但是不进行最后一层全局常量域追踪 * * `BindHandle2[value name]`: 直接获取值绑定的句柄, 但是不进行最后一层全局常量域追踪. diff --git a/examples/match.mdtlbl b/examples/match.mdtlbl index 8ac3f0e..c14101f 100644 --- a/examples/match.mdtlbl +++ b/examples/match.mdtlbl @@ -13,12 +13,16 @@ * * 修改了参数方式, 由构建期展开为编号参数改为编译期展开特定语句 * +* 重复块在重复时会将匹配到的参数设置环境参数 +* HINT: 只会设置`@`这种形式的使用, 并不包括_0这种 +* * --- * -* 内部语句SetArgs, 它将设置参数, 其作用范围为Expand和重复块 +* 内部语句SetArgs, 它将设置参数(包括_0 _1 这种旧形式), +* 其作用范围为Expand * * 扩展Other, Match和Print的参数, -* 增加展开符`@`, 展开符将会展开为全部参数, 参数来源于SetArgs +* 增加展开符`@`, 展开符将会展开为全部参数, 参数来源于SetArgs设置的环境参数 * * 可以使用重复块, 它将在一个内联块中重复给定块, 并且每次重复迭代指定个参数, * 此数字未指定则为1, 它不能为0, 它是构建期被指定的 diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index 1316e5a..f4a1a55 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.37" +version = "0.1.38" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/tests/src/lib.rs b/tools/parser/tests/src/lib.rs index 828b7dc..e60f269 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -4171,6 +4171,28 @@ fn cmper_test() { print __; "#).unwrap()).compile().unwrap(), ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + break ({match 1 2 3 => @ {}} => _); + print _0 @; + "#).unwrap()).compile().unwrap(), + vec![ + "jump 0 always 0 0", + "print _0", + ] + ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + break (=>[1 2 3] _); + print _0 @; + "#).unwrap()).compile().unwrap(), + vec![ + "jump 0 always 0 0", + "print _0", + ] + ); } #[test] @@ -5234,6 +5256,44 @@ fn match_test() { } "#).unwrap(), ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + match 1 2 => @ { + print _0 _1 @; + } + print _0 _1 @; + "#).unwrap()).compile().unwrap(), + vec![ + "print 1", + "print 2", + "print 1", + "print 2", + "print 1", + "print 2", + "print 1", + "print 2", + ], + ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + const match 1 2 => @ { + print _0 _1 @; + } + print _0 _1 @; + "#).unwrap()).compile().unwrap(), + vec![ + "print 1", + "print 2", + "print 1", + "print 2", + "print 1", + "print 2", + "print 1", + "print 2", + ], + ); } #[test] @@ -6099,6 +6159,7 @@ fn builtin_func_test() { const Value = (i:); match Name Value { @ {} } take Builtin.Const; + print Y; } print Y; } @@ -6106,6 +6167,7 @@ fn builtin_func_test() { vec![ "print h", "print i", + "print i", ], ); diff --git a/tools/syntax/Cargo.toml b/tools/syntax/Cargo.toml index fb501df..d44e15d 100644 --- a/tools/syntax/Cargo.toml +++ b/tools/syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "syntax" -version = "0.2.42" +version = "0.2.43" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/syntax/src/lib.rs b/tools/syntax/src/lib.rs index aef4cfe..135c9d2 100644 --- a/tools/syntax/src/lib.rs +++ b/tools/syntax/src/lib.rs @@ -1645,7 +1645,7 @@ impl CmpTree { match self { Deps(deps, cmp) => { - meta.with_block(|meta| { + meta.with_block_and_env_args(|meta| { deps.compile(meta); cmp.build(meta, do_tag_expanded); }); @@ -2162,12 +2162,10 @@ impl Compile for Goto { pub struct Expand(pub Vec); impl Compile for Expand { fn compile(self, meta: &mut CompileMeta) { - meta.with_block(|this| { - this.with_env_args_block(|this| { - for line in self.0 { - line.compile(this) - } - }); + meta.with_block_and_env_args(|meta| { + for line in self.0 { + line.compile(meta) + } }); } } @@ -2908,7 +2906,10 @@ impl MatchPat { for ((name, _), arg) in a.chain(b) { binds(name, arg, meta) } - meta.set_env_args(extracted) + let extracted = extracted.iter() + .map_into() + .collect::>(); + LogicLine::SetArgs(extracted.into()).compile(meta); }).is_some() }, _ => false, @@ -3102,7 +3103,10 @@ impl ConstMatchPat { for ele in right_datas { make(ele, meta); } - meta.set_env_args(&handles[mid_rng]); + let expand_args = handles[mid_rng].iter() + .map_into() + .collect::>(); + LogicLine::SetArgs(expand_args.into()).compile(meta); code.compile(meta); Ok(()) }, @@ -3305,7 +3309,7 @@ impl Compile for GSwitch { fn compile(self, meta: &mut CompileMeta) { use GSwitchCase as GSC; - meta.with_block(|meta| { + meta.with_block_and_env_args(|meta| { let mut missed_lab = self .case_lab_with_cond(GSwitchCase::is_missed, meta); let underflow_lab = self @@ -4045,6 +4049,19 @@ impl CompileMeta { block_exit(self) } + /// like `with_block(|meta| meta.with_env_args_block(f))` + pub fn with_block_and_env_args(&mut self, f: F) + -> (HashMap, Option>) + where F: FnOnce(&mut Self) + { + let mut inner_res = None; + let block_res = self.with_block(|meta| { + inner_res = Some(meta.with_env_args_block(f)) + }); + + (block_res, inner_res.unwrap()) + } + /// 添加一个需泄露的const pub fn add_const_value_leak(&mut self, name: Var) { self.expand_env