From 25da64cc28daa871f36c6fe8adff16f8dfc656e8 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 27 Jul 2023 20:47:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BAswitch=E6=B7=BB=E5=8A=A0=E4=BA=86appen?= =?UTF-8?q?d=E8=AF=AD=E6=B3=95,=20=E8=BF=99=E5=8F=AF=E4=BB=A5=E4=BD=BF?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=9C=BA=E6=99=AF=E4=B8=8B=E4=BD=BF=E7=94=A8?= =?UTF-8?q?switch=E6=9B=B4=E8=BD=BB=E6=9D=BE,=20=E4=BE=8B=E5=A6=82?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E8=A1=A8=20=E7=A7=BB=E9=99=A4=E4=BA=86?= =?UTF-8?q?=E8=A2=AB=E6=9E=9A=E4=B8=BE=E8=AF=AD=E5=8F=A5end,=20=E5=9B=A0?= =?UTF-8?q?=E4=B8=BA=E5=AE=83=E6=B2=A1=E5=95=A5=E7=94=A8=E4=B8=94=E5=AE=B9?= =?UTF-8?q?=E6=98=93=E5=8D=A0=E7=94=A8=E4=B8=80=E4=B8=AA=E5=B8=B8=E7=94=A8?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E6=A0=87=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- examples/switch_append.mdtlbl | 31 +++++++++++++++++++++++++++++++ src/syntax.rs | 32 +++++++++++++++++++++++++------- src/syntax_def.lalrpop | 13 ++++++++++--- 5 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 examples/switch_append.mdtlbl diff --git a/Cargo.lock b/Cargo.lock index 6156342..78801ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,7 +261,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.4.0" +version = "0.4.1" dependencies = [ "lalrpop", "lalrpop-util", diff --git a/Cargo.toml b/Cargo.toml index b74246b..93ef5fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.4.0" +version = "0.4.1" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/switch_append.mdtlbl b/examples/switch_append.mdtlbl new file mode 100644 index 0000000..3c6fa09 --- /dev/null +++ b/examples/switch_append.mdtlbl @@ -0,0 +1,31 @@ +#* 这是v0.4.1添加的新语法, 是switch语法扩展 + * 被写在switch所有case前 + * 作用是写在这里的一条语句会被追加到每个case后方 + * 你可以写一个块来写多条语句 + * 当然, 这是简单复制, 并没有进行标签的处理, + * 所以你往里面写跳转目标会有重复的标记 + * 解决也很简单, 你可以写到一个const-DExp, 那条语句去take这个const +*# + +switch 1 { + goto :end _; +case 0: print 0; +case 1: print 1; +case 2: print 2; +} :end +end; + +#* 以上代码会被编译为 +op mul __0 1 2 +op add @counter @counter __0 +print 0 +jump 8 always 0 0 +print 1 +jump 8 always 0 0 +print 2 +jump 8 always 0 0 +end +*# + +# 从以上代码可以看到, goto到end呗加入到了每一行的后面 +# 这是一个实用的功能 diff --git a/src/syntax.rs b/src/syntax.rs index da57794..9e3df0a 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -1238,6 +1238,7 @@ mod tests { #[test] fn switch_test() { let parser = LogicLineParser::new(); + let ast = parse!(parser, r#" switch 2 { case 1: @@ -1296,7 +1297,30 @@ mod tests { "print 5", "noop", ]); - //println!("{}", lines.join("\n")); + + let ast = parse!(parser, r#" + switch 1 { + print end; + case 0: print 0; + case 1: print 1; + } + "#).unwrap(); + assert_eq!( + ast, + Select( + "1".into(), + Expand(vec![ + Expand(vec![ + LogicLine::Other(vec!["print".into(), "0".into()]), + LogicLine::Other(vec!["print".into(), "end".into()]), + ]).into(), + Expand(vec![ + LogicLine::Other(vec!["print".into(), "1".into()]), + LogicLine::Other(vec!["print".into(), "end".into()]), + ]).into(), + ]) + ).into() + ); } #[test] @@ -1344,16 +1368,10 @@ mod tests { } print (op $ y + 3;); "#; - //dbg!(&src); let ast = parse!(parser, src).unwrap(); - //dbg!(&ast); let meta = CompileMeta::new(); - //dbg!(&meta); let mut tag_codes = meta.compile(ast); - //dbg!(&tag_codes); let logic_lines = tag_codes.compile().unwrap(); - //dbg!(&logic_lines); - //println!("{}", logic_lines.join("\n")); assert_eq!(logic_lines, [ r#"op add x 1 2"#, r#"op add __0 x 3"#, diff --git a/src/syntax_def.lalrpop b/src/syntax_def.lalrpop index 5b16a08..32d7146 100644 --- a/src/syntax_def.lalrpop +++ b/src/syntax_def.lalrpop @@ -172,7 +172,6 @@ pub LogicLine: LogicLine = { Label => LogicLine::new_label(<>, meta), "op" LEnd => <>.into(), "noop" LEnd => LogicLine::NoOp, - "end" LEnd => LogicLine::End, "set" LEnd => LogicLine::Other(vec!["set".into(), var.into(), value]), "=" LEnd => LogicLine::Other(vec!["set".into(), var.into(), value]), "read" LEnd @@ -315,8 +314,13 @@ pub Control: LogicLine = { }, "switch" - ":" )+>> + // append line + <("case" ":" )+> + )>> => { + let (append, cases) = cases; + let case_num_max = cases .iter() .map( @@ -328,7 +332,10 @@ pub Control: LogicLine = { .max() .unwrap(); let mut cases_res = Vec::with_capacity(case_num_max); - for (nums, expand) in cases { + for (nums, mut expand) in cases { + if let Some(append) = &append { + expand.push(append.clone()) + } for num in nums { for _ in cases_res.len()..=num { cases_res.push(LogicLine::NoOp)