From cf45c5c6552103afcc9a1e134c86f26b993655a1 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Sat, 28 Oct 2023 00:32:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86control-block,=20?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E7=AE=80=E5=8D=95=E7=9A=84=E6=8E=A7=E5=88=B6?= =?UTF-8?q?break=E5=92=8Ccontinue=E7=9A=84=E7=9B=AE=E6=A0=87=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- examples/README.md | 1 + examples/control_block.mdtlbl | 31 ++++++ src/syntax/def.lalrpop | 36 +++++++ src/syntax/mod.rs | 27 ++++- src/syntax/tests.rs | 194 ++++++++++++++++++++++++++++++++++ 7 files changed, 286 insertions(+), 7 deletions(-) create mode 100644 examples/control_block.mdtlbl diff --git a/Cargo.lock b/Cargo.lock index eee135a..5ebfcc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,7 +288,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.12.7" +version = "0.12.8" dependencies = [ "display_source", "lalrpop", diff --git a/Cargo.toml b/Cargo.toml index 21b4bb7..9c7c1ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.12.7" +version = "0.12.8" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/README.md b/examples/README.md index 20d9469..19970e9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,6 +12,7 @@ > [`op_expr.mdtlbl`](./op_expr.mdtlbl)
> [`control.mdtlbl`](./control.mdtlbl)
> [`control_plus.mdtlbl`](./control_plus.mdtlbl)
+> [`control_block.mdtlbl`](./control_block.mdtlbl)
> [`cmps.mdtlbl`](./cmps.mdtlbl)
> [`insert_sort.mdtlbl`](./insert_sort.mdtlbl)
> [`switch.mdtlbl`](./switch.mdtlbl)
diff --git a/examples/control_block.mdtlbl b/examples/control_block.mdtlbl new file mode 100644 index 0000000..a5ab620 --- /dev/null +++ b/examples/control_block.mdtlbl @@ -0,0 +1,31 @@ +#** +* 这是0.12.8加入的功能, 可以自定义break和continue的跳出点. +* 语法为(("break" | "continue") "!"?)+ Block +* 其中编写break就是表示捕获break至块末尾, +* 编写continue就是表示捕获continue至块末尾. +* +* 当break或者continue后方加上了叹号时, 将反转其跳转点, +* 例如`break! { ... }`内部使用break会跳转到块首部, +* 也就是应该continue跳转到的位置. +*# + +i = 0; +while i < 10 { + continue! { + getlink block i; + continue !(sensor $ block @enabled;); + } + op i i + 1; +} +#* >>> +set i 0 +jump 0 greaterThanEq i 10 +getlink block i +sensor __0 block @enabled +jump 5 equal __0 false +op add i i 1 +jump 2 lessThan i 10 +*# +# 可以看到, 控制块中的continue被导向了i自加处, +# 这样就可以在循环等结构中简单的定义break和continue的导向处了 +# 合理使用可以增加一些可读性等 diff --git a/src/syntax/def.lalrpop b/src/syntax/def.lalrpop index b53571b..b966d5d 100644 --- a/src/syntax/def.lalrpop +++ b/src/syntax/def.lalrpop @@ -70,7 +70,12 @@ OOCArgs: Vec = { } Span = @L T @R; +CtrlBreakStart: () = () => meta.add_control_break_level(None); +CtrlContinueStart: () = () => meta.add_control_continue_level(None); CtrlStart: () = () => meta.add_control_level(None, None); + +CtrlBreakStop: Option = () => meta.pop_control_break_level(); +CtrlContinueStop: Option = () => meta.pop_control_continue_level(); CtrlStop: (Option, Option) = () => meta.pop_control_level(); pub TopLevel: Expand = CtrlStart => { @@ -594,6 +599,35 @@ SwitchCatchFlag: SwitchCatch = { MTuple => SwitchCatch::UserDefine(<>), } +ControlBlock: Expand = { + "break" + CtrlBreakStart > + => { + let mut res = Vec::with_capacity(2); + if bang.is_none() { + res.push(lines.into()); + meta.push_some_label_to(&mut res, ctrl); + } else { + meta.push_some_label_to(&mut res, ctrl); + res.push(lines.into()); + } + res.into() + }, + "continue" + CtrlContinueStart > + => { + let mut res = Vec::with_capacity(2); + if bang.is_none() { + meta.push_some_label_to(&mut res, ctrl); + res.push(lines.into()); + } else { + res.push(lines.into()); + meta.push_some_label_to(&mut res, ctrl); + } + res.into() + }, +} + pub Control: LogicLine = { "goto"