diff --git a/Cargo.lock b/Cargo.lock index 51b65a1..71d6239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -307,7 +307,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.17.6" +version = "0.17.7" dependencies = [ "display_source", "logic_lint", @@ -353,7 +353,7 @@ dependencies = [ [[package]] name = "parser" -version = "0.3.21" +version = "0.3.22" dependencies = [ "lalrpop", "lalrpop-util", @@ -364,7 +364,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.36" +version = "0.1.37" dependencies = [ "either", "parser", diff --git a/Cargo.toml b/Cargo.toml index fb72224..2603257 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.17.6" +version = "0.17.7" edition = "2021" authors = ["A4-Tacks "] diff --git a/examples/README.md b/examples/README.md index 5d01eaf..0236910 100644 --- a/examples/README.md +++ b/examples/README.md @@ -45,3 +45,10 @@ 如果没有列出那请在看完上述后自行观看, 顺序可以参考文件创建顺序. 同时也有一篇[参考手册](./reference.md), 可以共同观看. + +> [!WARNING] +> 上述提到的[参考手册]编写版本已经是完全过时的, 初学或许可用, +> 进阶完全不能构成语言参考来使用 +> +> 且上述提到的教程目录是由远古版本一步步迭代而来, 风格非常不适合学习, +> 如果有什么疑问建议直接在讨论中询问 diff --git a/examples/const_match.mdtlbl b/examples/const_match.mdtlbl index f44ab4d..72aca76 100644 --- a/examples/const_match.mdtlbl +++ b/examples/const_match.mdtlbl @@ -71,3 +71,16 @@ const Read = (const match @ { # 否则尽量避免编写如 `$Res`, 也就是未添加`*`的情况 # 不然按以上的展开示例, 会在setres和之后使用时产生对原始值多次take, # 这通常不是预期的 + + +# 在0.17.7版本添加了一个方便的语法糖, 在单分支时可用减少嵌套, 例如 +const match @ => N { + print "num: "N; +} +# 相当于如下代码 +const match @ { + N { + print "num: "N; + } +} +# 在只有一个分支时可以减少一层括号, 用于快速接收参数等情况非常舒适 diff --git a/examples/match.mdtlbl b/examples/match.mdtlbl index 95a49c7..8ac3f0e 100644 --- a/examples/match.mdtlbl +++ b/examples/match.mdtlbl @@ -380,3 +380,16 @@ inline 3@{ } *# # 由上述展开可以看到它的运作方式, 很容易理解 + + +# 在0.17.7版本添加了一个方便的语法糖, 在单分支时可用减少嵌套, 例如 +match @ => N { + print "num: "N; +} +# 相当于如下代码 +match @ { + N { + print "num: "N; + } +} +# 在只有一个分支时可以减少一层括号, 用于快速接收参数等情况非常舒适 diff --git a/examples/pascals_triangle.mdtlbl b/examples/pascals_triangle.mdtlbl index 852c9fd..26de25a 100644 --- a/examples/pascals_triangle.mdtlbl +++ b/examples/pascals_triangle.mdtlbl @@ -84,24 +84,24 @@ print"\ lastSize = 2; -take PrevLine[0 1 1]; # like `PrevLine[0, 1] = 1` +PrevLine! 0 1 1; # like `PrevLine[0, 1] = 1` -take ForD[3 (%(*TriangleSize+1))->$ const(match @ { I { - take CurLine[0 1]; +ForD! 3 (%(*TriangleSize+1))->$ const(match @ => I { + CurLine! 0 1; - take ForD[1 lastSize const(match @ { J { - take CurLine[J (*PrevLine[(*J- 1)] + PrevLine[J])]; - }})]; - take CurLine[lastSize 1]; + ForD! 1 lastSize (match @ => J { + CurLine! J (*PrevLine[(*J- 1)] + PrevLine[J]); + }); + CurLine! lastSize 1; lastSize++; - take ForD[lastSize const(match @ { C { + ForD! lastSize (match @ => C { print CurLine[].Read[cur_c C]; - take PrevLine[C cur_c]; + PrevLine! C cur_c; if C < (*lastSize- 1) { print " "; } - }})]; + }); print "\n"; -}})]; +}); printflush message1; diff --git a/examples/quick_dexp_take.mdtlbl b/examples/quick_dexp_take.mdtlbl index 1567da5..6c51ad6 100644 --- a/examples/quick_dexp_take.mdtlbl +++ b/examples/quick_dexp_take.mdtlbl @@ -82,3 +82,14 @@ print "stop" # 而在方案1中, 我们在进行Do之前先手动对它进行了求值, 所以求值发生在"start"前 # 例如这种需要的值并没有在头部进行计算完毕的场景, 这便可能是一个坑, # 所以你需要谨记它是一个DExp + + +# 在0.17.7版本增加了对常用的一种形式的一个语法糖, 例如: +take Cmd[1 2 3 ( + print "x"; +)]; +# 可以等价于 +Cmd! 1 2 3 ( + print "x"; +); +# 这种语法糖可以显著减少嵌套和大量take的出现 diff --git a/syntax/MT-Manager/MindustryLogicBangLang.mtsx b/syntax/MT-Manager/MindustryLogicBangLang.mtsx index 935ed6c..b7da4e5 100644 --- a/syntax/MT-Manager/MindustryLogicBangLang.mtsx +++ b/syntax/MT-Manager/MindustryLogicBangLang.mtsx @@ -94,8 +94,12 @@ 0: "label" } { // quick dexp take - match: /(?:(?:[a-zA-Z_][a-zA-Z0-9_\-]*)?/+include("ws")+/\[|\])/ + match: /(?:(?:[a-zA-Z_][a-zA-Z0-9_\-]*)[\[!]|[\[\]])/ 0: "variable" } + { // control operator + match: /&&|\|\||!/ + 0: "keyword" + } ] } diff --git a/syntax/vim/mdtlbl.snippets b/syntax/vim/mdtlbl.snippets index fe30ffe..8e593bb 100644 --- a/syntax/vim/mdtlbl.snippets +++ b/syntax/vim/mdtlbl.snippets @@ -47,6 +47,12 @@ endsnippet snippet take "take" w take ${1:${2:Res} = ${3:\$}};$0 endsnippet +snippet take "take" w +take ${1:${2:Res} = ${3:\$}};$0 +endsnippet +snippet ctake "command like take" w +$1! $2; +endsnippet snippet argt "take arg" w take ${1:Arg} = _${2:0};$0 endsnippet diff --git a/syntax/vim/mdtlbl.vim b/syntax/vim/mdtlbl.vim index 13f4bc6..ee6d8da 100644 --- a/syntax/vim/mdtlbl.vim +++ b/syntax/vim/mdtlbl.vim @@ -83,9 +83,9 @@ syn match mdtlblDefineResultHandle /\v%(\([%?]=)@2<=(`=)0%(x-=_@![0-9a-fA-F_]+|b syn match mdtlblDefineResultHandle /\v%(\([%?]=)@2<=(`=)%(\I\i*|\@\I\i*%(-\i*)*|'[^' \t]+')\1:/ contains=mdtlblStringColor syn match mdtlblDefineResultHandle /\v%(\([%?]=)@2<=(`=)"[^"]*"\1:/ contains=@mdtlblStringContains -syn match mdtlblQuickDExpTakeIdent /\v\@\I\i*%(-\i*)*%(%(-\>)=\[)@=/ -syn match mdtlblQuickDExpTakeIdent /\v\I\i*%(%(-\>)=\[)@=/ -syn match mdtlblQuickDExpTakeIdent /\v'[^' \t]+'%(%(-\>)=\[)@=/ +syn match mdtlblQuickDExpTakeIdent /\v\@\I\i*%(-\i*)*%(%(-\>)=[[!])@=/ +syn match mdtlblQuickDExpTakeIdent /\v\I\i*%(%(-\>)=[[!])@=/ +syn match mdtlblQuickDExpTakeIdent /\v'[^' \t]+'%(%(-\>)=[[!])@=/ syn match mdtlblQuickDExpTakeIdent /->/ syn match mdtlblIdentLabel /\v%(^|\W@1<=):%(\I\i*|\@\I\i*%(-\i*)*|'[^' \t]+')/ nextgroup=mdtlblIdentLabelRest contains=mdtlblStringColor diff --git a/tools/parser/Cargo.toml b/tools/parser/Cargo.toml index 6fd7f3d..45865ed 100644 --- a/tools/parser/Cargo.toml +++ b/tools/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser" -version = "0.3.21" +version = "0.3.22" 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 f3c8fbb..c52ed7a 100644 --- a/tools/parser/src/parser.lalrpop +++ b/tools/parser/src/parser.lalrpop @@ -365,40 +365,70 @@ pub LogicLine: LogicLine = { OpExpr, Print, LEnd => LogicLine::Other(<>), + QuickTake, "inline" => <>.into(), Match => <>.into(), ConstMatch => <>.into(), } -Match: Match = "match" <("@" )?> > -)*>> => { - Match::new(args.unwrap_or_default(), cases.into_iter() - .map(|(prep, sufp, body)| { - (if let Some(sufp) = sufp { - MatchPat::Expanded(prep, sufp) - } else { - MatchPat::Normal(prep) - }, body.into()) - }) - .collect() - ) +#[inline] +QuickTake: LogicLine = "!" LEnd => { + let dexp = DExp::new(meta.unnamed_var(), vec![ + LogicLine::SetArgs(args.unwrap_or_default()), + LogicLine::SetResultHandle(value), + ].into()); + Take(meta.unnamed_var().into(), dexp.into()).into() }; +Match: Match = { + "match" <("@" )?> > + )*>> => { + Match::new(args.unwrap_or_default(), cases.into_iter() + .map(|(prep, sufp, body)| { + (if let Some(sufp) = sufp { + MatchPat::Expanded(prep, sufp) + } else { + MatchPat::Normal(prep) + }, body.into()) + }) + .collect() + ) + }, + "match" "=>" <("@" )?> > + )> => { + Match::new(args.unwrap_or_default(), vec![case].into_iter() + .map(|(prep, sufp, body)| { + (if let Some(sufp) = sufp { + MatchPat::Expanded(prep, sufp) + } else { + MatchPat::Normal(prep) + }, body.into()) + }) + .collect() + ) + }, +} + MatchPat: MatchPatAtom = { MList => MatchPatAtom::new_unamed(<>), Var => MatchPatAtom::new(<>, vec![]), ":" > => MatchPatAtom::new(name, pat), } -ConstMatch: ConstMatch - = "const" "match" - > -=> { - ConstMatch::new(args.unwrap_or_default(), cases) -}; + )*>> => { + ConstMatch::new(args.unwrap_or_default(), cases) + }, + "const" "match" "=>" => { + ConstMatch::new(args.unwrap_or_default(), vec![case]) + }, +} ConstMatchPat: ConstMatchPat = { ConstMatchPatAtom* => ConstMatchPat::Normal(<>), diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index b538fe9..1316e5a 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.36" +version = "0.1.37" 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 01948df..828b7dc 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -2214,6 +2214,15 @@ fn quick_dexp_take_test() { "#).unwrap(), ); + assert_eq!( + parse!(parser, r#" + Foo! a b c @ d; + "#).unwrap(), + parse!(parser, r#" + take Foo[a b c @ d]; + "#).unwrap(), + ); + } #[test] @@ -5180,6 +5189,51 @@ fn match_test() { } "#).unwrap(), ); + + assert_eq!( + parse!(parser, r#" + match x @ y => a @ b { + body; + } + "#).unwrap(), + parse!(parser, r#" + match x @ y { + a @ b { + body; + } + } + "#).unwrap(), + ); + + assert_eq!( + parse!(parser, r#" + const match x @ y => a @ b { + body; + } + "#).unwrap(), + parse!(parser, r#" + const match x @ y { + a @ b { + body; + } + } + "#).unwrap(), + ); + + assert_eq!( + parse!(parser, r#" + const match x @ y => *a @ [b] { + body; + } + "#).unwrap(), + parse!(parser, r#" + const match x @ y { + *a @ [b] { + body; + } + } + "#).unwrap(), + ); } #[test]