Skip to content

Commit

Permalink
增加三个语法糖, 使take类似命令, 简化match单分支
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Oct 22, 2024
1 parent 56a6e35 commit a642364
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 41 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.6"
version = "0.17.7"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
7 changes: 7 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@
如果没有列出那请在看完上述后自行观看, 顺序可以参考文件创建顺序.

同时也有一篇[参考手册](./reference.md), 可以共同观看.

> [!WARNING]
> 上述提到的[参考手册]编写版本已经是完全过时的, 初学或许可用,
> 进阶完全不能构成语言参考来使用
>
> 且上述提到的教程目录是由远古版本一步步迭代而来, 风格非常不适合学习,
> 如果有什么疑问建议直接在讨论中询问
13 changes: 13 additions & 0 deletions examples/const_match.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
# 在只有一个分支时可以减少一层括号, 用于快速接收参数等情况非常舒适
13 changes: 13 additions & 0 deletions examples/match.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,16 @@ inline 3@{
}
*#
# 由上述展开可以看到它的运作方式, 很容易理解


# 在0.17.7版本添加了一个方便的语法糖, 在单分支时可用减少嵌套, 例如
match @ => N {
print "num: "N;
}
# 相当于如下代码
match @ {
N {
print "num: "N;
}
}
# 在只有一个分支时可以减少一层括号, 用于快速接收参数等情况非常舒适
22 changes: 11 additions & 11 deletions examples/pascals_triangle.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
11 changes: 11 additions & 0 deletions examples/quick_dexp_take.mdtlbl
Original file line number Diff line number Diff line change
Expand Up @@ -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的出现
6 changes: 5 additions & 1 deletion syntax/MT-Manager/MindustryLogicBangLang.mtsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
6 changes: 6 additions & 0 deletions syntax/vim/mdtlbl.snippets
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions syntax/vim/mdtlbl.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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
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.21"
version = "0.3.22"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
70 changes: 50 additions & 20 deletions tools/parser/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -365,40 +365,70 @@ pub LogicLine: LogicLine = {
OpExpr,
Print,
<Args> LEnd => LogicLine::Other(<>),
QuickTake,
"inline" <ArgsRepeatBlock> => <>.into(),
Match => <>.into(),
ConstMatch => <>.into(),
}

Match: Match = "match" <args:Args?> <cases:MBlock<(
<MatchPat*> <("@" <MatchPat*>)?> <MBlock<LogicLine*>>
)*>> => {
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 = <value:NonConstRangeValue> "!" <args:Args?> 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" <args:Args?> <cases:MBlock<(
<MatchPat*> <("@" <MatchPat*>)?> <MBlock<LogicLine*>>
)*>> => {
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" <args:Args?> "=>" <case:(
<MatchPat*> <("@" <MatchPat*>)?> <MBlock<LogicLine*>>
)> => {
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<Args1> => MatchPatAtom::new_unamed(<>),
Var => MatchPatAtom::new(<>, vec![]),
<name:Var> ":" <pat:MList<Args1>> => MatchPatAtom::new(name, pat),
}

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

ConstMatchPat: ConstMatchPat = {
ConstMatchPatAtom* => ConstMatchPat::Normal(<>),
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.36"
version = "0.1.37"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
54 changes: 54 additions & 0 deletions tools/parser/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit a642364

Please sign in to comment.