Skip to content

Commit

Permalink
参数表增加求值语法, 且支持无限长
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Jan 13, 2025
1 parent 9adf2e6 commit 6e4e677
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 24 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.17.12"
version = "0.17.13"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
2 changes: 1 addition & 1 deletion README-en_US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ printflush message1
# 项目构建
构建这个项目将会比较慢, 原因如下:
1. 使用`rustc`进行编译, 而它略慢, 相对于`gcc` `clang`
2. 使用了大型语法分析框架`lalrpop`, 它会生成近六十万行代码, 再叠加上`rustc`编译更慢
2. 使用了大型语法分析框架`lalrpop`, 它会生成六十多万行代码, 再叠加上`rustc`编译更慢

你可以先翻一翻Releases, 看一看有没有已构建的程序, 如果没有或无法使用再尝试自己构建.

Expand Down
2 changes: 2 additions & 0 deletions examples/value_bind_ref.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* 还有一个语法糖, `Value->[...]` 应等价 `Value[...]->$`
*
* 返回绑定者的值只会进行常量追溯而不是进行take
*
* 在0.17.13版本添加了参数表求值语法, 例如`F[*X]`大致等价`F[X->$]`
*#

const bind.Fun = (
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
46 changes: 30 additions & 16 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ NonConstRangeValue: Value = {
ConstKey => <>.into(),
"`" <Var> "`" => ReprVar(<>), // 原始值
"$" => ResultHandle,
<value:NonConstRangeValue> <args:MList<Args?>> => {
<value:NonConstRangeValue> <args:MList<ParamArgs>> => {
// QuickDExpTake
DExp::new(meta.unnamed_var(), vec![
LogicLine::SetArgs(args.unwrap_or_default()),
LogicLine::SetArgs(args),
LogicLine::SetResultHandle(value),
].into()).into()
},
Expand All @@ -184,10 +184,10 @@ NonConstRangeValue: Value = {
<NonConstRangeValue> "->" "$" => {
ValueBindRef::new(<>.into(), ValueBindRefTarget::ResultHandle).into()
},
<value:NonConstRangeValue> "->" <args:MList<Args?>> => {
<value:NonConstRangeValue> "->" <args:MList<ParamArgs>> => {
// Refed QuickDExpTake
let value = DExp::new(meta.unnamed_var(), vec![
LogicLine::SetArgs(args.unwrap_or_default()),
LogicLine::SetArgs(args),
LogicLine::SetResultHandle(value),
].into()).into();

Expand Down Expand Up @@ -257,10 +257,10 @@ AlwaysJumpCmp: CmpTree = JumpCmp? => <>.unwrap_or(JumpCmp::Always.into());
CmpTree1: CmpTree = {
<deps:MBlock<LogicLine*>> "=>" <cmp:CmpTree1>
=> CmpTree::Deps(deps.into(), cmp.into()),
<deps:MBlock<LogicLine*>?> "=>" <args:MList<Args?>> <cmp:CmpTree1> => {
<deps:MBlock<LogicLine*>?> "=>" <args:MList<ParamArgs>> <cmp:CmpTree1> => {
CmpTree::Deps(vec![
InlineBlock::from(deps.unwrap_or_default()).into(),
LogicLine::SetArgs(args.unwrap_or_default()),
LogicLine::SetArgs(args),
].into(), cmp.into())
},
CmpTree2,
Expand Down Expand Up @@ -372,19 +372,19 @@ pub LogicLine: LogicLine = {
}

#[inline]
QuickTake: LogicLine = <value:NonConstRangeValue> "!" <args:Args?> LEnd => {
QuickTake: LogicLine = <value:NonConstRangeValue> "!" <args:ParamArgs> 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" <args:Args?> <cases:MBlock<(
"match" <args:ParamArgs> <cases:MBlock<(
<MatchPat*> <("@" <MatchPat*>)?> <MBlock<LogicLine*>>
)*>> => {
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)
Expand All @@ -395,10 +395,10 @@ Match: Match = {
.collect()
)
},
"match" <args:Args?> "=>" <case:(
"match" <args:ParamArgs> "=>" <case:(
<MatchPat*> <("@" <MatchPat*>)?> <MBlock<LogicLine*>>
)> => {
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)
Expand All @@ -418,15 +418,15 @@ MatchPat: MatchPatAtom = {
}

ConstMatch: ConstMatch = {
"const" "match" <args:Args?> <cases:MBlock<(
"const" "match" <args:ParamArgs> <cases:MBlock<(
ConstMatchPat NoPrefixInlineBlock
)*>> => {
ConstMatch::new(args.unwrap_or_default(), cases)
ConstMatch::new(args, cases)
},
"const" "match" <args:Args?> "=>" <case:(
"const" "match" <args:ParamArgs> "=>" <case:(
ConstMatchPat NoPrefixInlineBlock
)> => {
ConstMatch::new(args.unwrap_or_default(), vec![case])
ConstMatch::new(args, vec![case])
},
}

Expand Down Expand Up @@ -498,6 +498,20 @@ Args: Args = {
args.into()
},
}
ParamArgsAtom: Value = {
"*" <Value> => {
ValueBindRef::new(<>.into(), ValueBindRefTarget::ResultHandle).into()
},
Value,
};
ParamArgs: Args = {
<prefix:ParamArgsAtom*> "@" <suffix:ParamArgsAtom*> => {
Args::Expanded(prefix, suffix)
},
<args:ParamArgsAtom*> => {
args.into()
},
}
ArgsRepeatBlock: ArgsRepeat = {
<l:@L><chunk:LiteralUInt?><r:@R>
"@" <block:NoPrefixInlineBlock> =>? {
Expand Down
2 changes: 1 addition & 1 deletion tools/parser/tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
150 changes: 150 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"#,
],
);
}

0 comments on commit 6e4e677

Please sign in to comment.