From 94d6a1d11625bd08c4eab99442f5961a532d8ecc Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 22 Aug 2024 09:55:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=A4=E4=B8=AAtake?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E8=AF=AD=E6=B3=95=E7=B3=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 6 ++-- Cargo.toml | 2 +- examples/op_expr.mdtlbl | 6 ++++ examples/take.mdtlbl | 6 ++++ syntax/vim/mdtlbl.vim | 3 +- tools/parser/Cargo.toml | 2 +- tools/parser/src/parser.lalrpop | 54 +++++++++++++++++++++++++-------- tools/parser/tests/Cargo.toml | 2 +- tools/parser/tests/src/lib.rs | 25 +++++++++++++++ 9 files changed, 86 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51d0350..e0b9d40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,7 +301,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.16.21" +version = "0.16.22" dependencies = [ "display_source", "logic_lint", @@ -347,7 +347,7 @@ dependencies = [ [[package]] name = "parser" -version = "0.3.19" +version = "0.3.20" dependencies = [ "lalrpop", "lalrpop-util", @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.33" +version = "0.1.34" dependencies = [ "parser", "syntax", diff --git a/Cargo.toml b/Cargo.toml index 9e33593..7eae31f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.16.21" +version = "0.16.22" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/op_expr.mdtlbl b/examples/op_expr.mdtlbl index 86192e6..e8f4bf1 100644 --- a/examples/op_expr.mdtlbl +++ b/examples/op_expr.mdtlbl @@ -235,3 +235,9 @@ i++; j--; op ___1 ___1 - `1`; } *# + + +# 在0.16.22版本为了使take配合op-expr更加简洁, 添加了一个语法糖 +take*A, B = x+y, i++; +# 相当于 +take A=(*x+y) B=(*i++); diff --git a/examples/take.mdtlbl b/examples/take.mdtlbl index b503dee..83ddbab 100644 --- a/examples/take.mdtlbl +++ b/examples/take.mdtlbl @@ -25,3 +25,9 @@ print __1 # 可以看到, 我们可以对常量的值计算一次但是多次使用结果 # 如果直接`print F;`, 将会每次都进行计算 + + +# 可以直接take一个空的DExp, 利用其自动分配匿名返回句柄的行为声明一个匿名量 +take X = (); +# 在0.16.22版本有一个语法糖, 可以更简短的完成这个例子 +take+X; diff --git a/syntax/vim/mdtlbl.vim b/syntax/vim/mdtlbl.vim index 5db8596..ab29a74 100644 --- a/syntax/vim/mdtlbl.vim +++ b/syntax/vim/mdtlbl.vim @@ -27,11 +27,12 @@ syn case match " 一些关键字 {{{1 syn keyword mdtlblKeyword \ while gwhile do skip if elif else switch gswitch break continue - \ const take setres select match + \ const setres select match \ inline \ op noop print syn keyword mdtlblKeyword goto nextgroup=mdtlblIdentLabelRest syn keyword mdtlblKeyword case nextgroup=mdtlblStar skipwhite +syn keyword mdtlblKeyword take nextgroup=mdtlblStar skipwhite syn match mdtlblStar /\*/ contained syn keyword mdtlblOpFunKeyword diff --git a/tools/parser/Cargo.toml b/tools/parser/Cargo.toml index 31b6601..eafbb54 100644 --- a/tools/parser/Cargo.toml +++ b/tools/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser" -version = "0.3.19" +version = "0.3.20" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/parser/src/parser.lalrpop b/tools/parser/src/parser.lalrpop index 95920f2..22779e1 100644 --- a/tools/parser/src/parser.lalrpop +++ b/tools/parser/src/parser.lalrpop @@ -921,25 +921,53 @@ pub BuiltinCommand: LogicLine = { ) }, - "take" - "=")?> )+> - LEnd => { - if takes.len() == 1 { - let (res, value) = takes.pop().unwrap(); - let res = res.unwrap_or_else(|| meta.unnamed_var().into()); - return Take(res, value).into(); + "take" LEnd => { + if lines.len() == 1 { + lines.into_iter().next().unwrap() + } else { + InlineBlock(lines).into() } - let mut lines = Vec::with_capacity(takes.len()); - for (res, value) in takes.into_iter() { - let res = res.unwrap_or_else(|| meta.unnamed_var().into()); - let take = Take(res, value); - lines.push(take.into()) + }, + + "take" "*" LEnd => { + let (keys, vals) = inner; + assert_eq!(keys.len(), vals.len()); + + let lines = keys.into_iter() + .rev() + .zip(vals) + .map(|(key, val)| { + Take(key, val).into() + }) + .collect::>(); + + if lines.len() == 1 { + lines.into_iter().next().unwrap() + } else { + InlineBlock(lines).into() } - InlineBlock(lines).into() }, "setres" LEnd => LogicLine::SetResultHandle(<>), } +TakeOpExprMultInner: (Vec, Vec) = { + "=" => (vec![key], vec![val]), + "," "," => { + inner.0.push(key); + inner.1.push(val); + inner + }, +} +#[inline] +TakeAtom: LogicLine = { + "+" => { + Take(key, DExp::new_nores(vec![].into()).into()).into() + }, + "=")?> => { + let key = key.unwrap_or_else(|| meta.unnamed_var().into()); + Take(key, val).into() + }, +} BlockExpand: Expand = MBlock => <>; pub Block: LogicLine = BlockExpand => <>.into(); diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index d48d9b7..f133f98 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.33" +version = "0.1.34" 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 01f47c2..bff7219 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -883,6 +883,20 @@ fn take_test() { "print 2", "print 2", ]); + + assert_eq!( + parse!(parser, r#" + take+A+B+C+D; + "#).unwrap(), + parse!(parser, r#" + inline { + take A = (); + take B = (); + take C = (); + take D = (); + } + "#).unwrap(), + ); } #[test] @@ -2647,6 +2661,17 @@ fn op_expr_test() { print (__: setres i; $ = $ + `1`;); "#).unwrap(), ); + + assert_eq!( + parse!(parser, r#" + take*A, B = x+y, i++; + take*C = j--; + "#).unwrap(), + parse!(parser, r#" + take A = (*x+y) B = (*i++); + take C = (*j--); + "#).unwrap(), + ); } #[test]