diff --git a/Cargo.lock b/Cargo.lock index 445b8ad..a949188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,7 +284,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mindustry_logic_bang_lang" -version = "0.17.12" +version = "0.17.13" dependencies = [ "display_source", "logic_lint", @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "parser" -version = "0.3.23" +version = "0.3.24" dependencies = [ "lalrpop", "lalrpop-util", @@ -341,7 +341,7 @@ dependencies = [ [[package]] name = "parser-tests" -version = "0.1.40" +version = "0.1.41" dependencies = [ "either", "parser", diff --git a/Cargo.toml b/Cargo.toml index 82918d9..950b39a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.17.12" +version = "0.17.13" edition = "2021" authors = ["A4-Tacks "] diff --git a/README-en_US.md b/README-en_US.md index 1c68c4a..4d1f4da 100644 --- a/README-en_US.md +++ b/README-en_US.md @@ -179,7 +179,7 @@ printflush message1 # Project Build Building this project will be relatively slow due to the following reasons: 1. Compile using `rustc`, which is slightly slower compared to `gcc` and `clang` -2. Using the large syntax analysis framework 'lalrpop', generated nearly 600000 lines of code and works together with 'rustc' to make compilation very slower +2. Using the large syntax analysis framework 'lalrpop', generated over 600000 lines of code and works together with 'rustc' to make compilation very slower You can first check the Releases to see if there is a built program, and if it does not exist or cannot be used, try building it yourself diff --git a/README.md b/README.md index 514c418..a05fa5f 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ printflush message1 # 项目构建 构建这个项目将会比较慢, 原因如下: 1. 使用`rustc`进行编译, 而它略慢, 相对于`gcc` `clang` -2. 使用了大型语法分析框架`lalrpop`, 它会生成近六十万行代码, 再叠加上`rustc`编译更慢 +2. 使用了大型语法分析框架`lalrpop`, 它会生成六十多万行代码, 再叠加上`rustc`编译更慢 你可以先翻一翻Releases, 看一看有没有已构建的程序, 如果没有或无法使用再尝试自己构建. diff --git a/examples/value_bind_ref.mdtlbl b/examples/value_bind_ref.mdtlbl index 206b7af..9d4670a 100644 --- a/examples/value_bind_ref.mdtlbl +++ b/examples/value_bind_ref.mdtlbl @@ -8,6 +8,8 @@ * 还有一个语法糖, `Value->[...]` 应等价 `Value[...]->$` * * 返回绑定者的值只会进行常量追溯而不是进行take +* +* 在0.17.13版本添加了参数表求值语法, 例如`F[*X]`大致等价`F[X->$]` *# const bind.Fun = ( diff --git a/tools/parser/Cargo.toml b/tools/parser/Cargo.toml index ab37314..b6dc4c3 100644 --- a/tools/parser/Cargo.toml +++ b/tools/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser" -version = "0.3.23" +version = "0.3.24" 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 4cb6b0d..096d8de 100644 --- a/tools/parser/src/parser.lalrpop +++ b/tools/parser/src/parser.lalrpop @@ -161,10 +161,10 @@ NonConstRangeValue: Value = { ConstKey => <>.into(), "`" "`" => ReprVar(<>), // 原始值 "$" => ResultHandle, - > => { + > => { // QuickDExpTake DExp::new(meta.unnamed_var(), vec![ - LogicLine::SetArgs(args.unwrap_or_default()), + LogicLine::SetArgs(args), LogicLine::SetResultHandle(value), ].into()).into() }, @@ -184,10 +184,10 @@ NonConstRangeValue: Value = { "->" "$" => { ValueBindRef::new(<>.into(), ValueBindRefTarget::ResultHandle).into() }, - "->" > => { + "->" > => { // Refed QuickDExpTake let value = DExp::new(meta.unnamed_var(), vec![ - LogicLine::SetArgs(args.unwrap_or_default()), + LogicLine::SetArgs(args), LogicLine::SetResultHandle(value), ].into()).into(); @@ -257,10 +257,10 @@ AlwaysJumpCmp: CmpTree = JumpCmp? => <>.unwrap_or(JumpCmp::Always.into()); CmpTree1: CmpTree = { > "=>" => CmpTree::Deps(deps.into(), cmp.into()), - ?> "=>" > => { + ?> "=>" > => { CmpTree::Deps(vec![ InlineBlock::from(deps.unwrap_or_default()).into(), - LogicLine::SetArgs(args.unwrap_or_default()), + LogicLine::SetArgs(args), ].into(), cmp.into()) }, CmpTree2, @@ -372,19 +372,19 @@ pub LogicLine: LogicLine = { } #[inline] -QuickTake: LogicLine = "!" LEnd => { +QuickTake: LogicLine = "!" LEnd => { let dexp = DExp::new(meta.unnamed_var(), vec![ - LogicLine::SetArgs(args.unwrap_or_default()), + LogicLine::SetArgs(args), LogicLine::SetResultHandle(value), ].into()); Take(meta.unnamed_var().into(), dexp.into()).into() }; Match: Match = { - "match" <("@" )?> > )*>> => { - Match::new(args.unwrap_or_default(), cases.into_iter() + Match::new(args, cases.into_iter() .map(|(prep, sufp, body)| { (if let Some(sufp) = sufp { MatchPat::Expanded(prep, sufp) @@ -395,10 +395,10 @@ Match: Match = { .collect() ) }, - "match" "=>" "=>" <("@" )?> > )> => { - Match::new(args.unwrap_or_default(), vec![case].into_iter() + Match::new(args, vec![case].into_iter() .map(|(prep, sufp, body)| { (if let Some(sufp) = sufp { MatchPat::Expanded(prep, sufp) @@ -418,15 +418,15 @@ MatchPat: MatchPatAtom = { } ConstMatch: ConstMatch = { - "const" "match" > => { - ConstMatch::new(args.unwrap_or_default(), cases) + ConstMatch::new(args, cases) }, - "const" "match" "=>" "=>" => { - ConstMatch::new(args.unwrap_or_default(), vec![case]) + ConstMatch::new(args, vec![case]) }, } @@ -498,6 +498,20 @@ Args: Args = { args.into() }, } +ParamArgsAtom: Value = { + "*" => { + ValueBindRef::new(<>.into(), ValueBindRefTarget::ResultHandle).into() + }, + Value, +}; +ParamArgs: Args = { + "@" => { + Args::Expanded(prefix, suffix) + }, + => { + args.into() + }, +} ArgsRepeatBlock: ArgsRepeat = { "@" =>? { diff --git a/tools/parser/tests/Cargo.toml b/tools/parser/tests/Cargo.toml index 5326da4..2935853 100644 --- a/tools/parser/tests/Cargo.toml +++ b/tools/parser/tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "parser-tests" -version = "0.1.40" +version = "0.1.41" 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 6bb00e9..99001dd 100644 --- a/tools/parser/tests/src/lib.rs +++ b/tools/parser/tests/src/lib.rs @@ -7534,3 +7534,153 @@ fn closure_catch_args_test() { ], ); } + +#[test] +fn param_deref_test() { + let parser = TopLevelParser::new(); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + const F = ( + const N = 2; + print @; + ); + const N = 1; + take F[(setres N;)]; + take F[*(setres N;)]; + "#).unwrap()).compile().unwrap(), + vec![ + r#"print 2"#, + r#"print 1"#, + ], + ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + const F = ( + const N = 2; + print @; + ); + const match (setres N;) => @ {} + const N = 1; + take F[(setres N;) @]; + take F[*(setres N;) @]; + "#).unwrap()).compile().unwrap(), + vec![ + r#"print 2"#, + r#"print 2"#, + r#"print 1"#, + r#"print 2"#, + ], + ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + const F = ( + const N = 2; + print @; + ); + const match (setres N;) => @ {} + const N = 1; + take F[(setres N;) @]; + match @ => @ {} + take F[*(setres N;) @]; + "#).unwrap()).compile().unwrap(), + vec![ + r#"print 2"#, + r#"print 2"#, + r#"print 1"#, + r#"print 1"#, + ], + ); +} + +#[test] +fn param_inf_len_test() { + let parser = TopLevelParser::new(); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + const F = ( + print @; + ); + F! 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31; + "#).unwrap()).compile().unwrap(), + vec![ + r#"print 0"#, + r#"print 1"#, + r#"print 2"#, + r#"print 3"#, + r#"print 4"#, + r#"print 5"#, + r#"print 6"#, + r#"print 7"#, + r#"print 8"#, + r#"print 9"#, + r#"print 10"#, + r#"print 11"#, + r#"print 12"#, + r#"print 13"#, + r#"print 14"#, + r#"print 15"#, + r#"print 16"#, + r#"print 17"#, + r#"print 18"#, + r#"print 19"#, + r#"print 20"#, + r#"print 21"#, + r#"print 22"#, + r#"print 23"#, + r#"print 24"#, + r#"print 25"#, + r#"print 26"#, + r#"print 27"#, + r#"print 28"#, + r#"print 29"#, + r#"print 30"#, + r#"print 31"#, + ], + ); + + assert_eq!( + CompileMeta::new().compile(parse!(parser, r#" + (%print @;%)! 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31; + "#).unwrap()).compile().unwrap(), + vec![ + r#"print 0"#, + r#"print 1"#, + r#"print 2"#, + r#"print 3"#, + r#"print 4"#, + r#"print 5"#, + r#"print 6"#, + r#"print 7"#, + r#"print 8"#, + r#"print 9"#, + r#"print 10"#, + r#"print 11"#, + r#"print 12"#, + r#"print 13"#, + r#"print 14"#, + r#"print 15"#, + r#"print 16"#, + r#"print 17"#, + r#"print 18"#, + r#"print 19"#, + r#"print 20"#, + r#"print 21"#, + r#"print 22"#, + r#"print 23"#, + r#"print 24"#, + r#"print 25"#, + r#"print 26"#, + r#"print 27"#, + r#"print 28"#, + r#"print 29"#, + r#"print 30"#, + r#"print 31"#, + ], + ); +}