Skip to content

Commit

Permalink
添加match和重复块, 并且修改参数机制
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Dec 31, 2023
1 parent e69fe68 commit 3452ecf
Show file tree
Hide file tree
Showing 16 changed files with 1,451 additions and 124 deletions.
10 changes: 5 additions & 5 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.13.9"
version = "0.14.0"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
> [`quick_dexp_take.mdtlbl`](./quick_dexp_take.mdtlbl)<br/>
> [`value_bind.mdtlbl`](./value_bind.mdtlbl)<br/>
> [`caller.mdtlbl`](./caller.mdtlbl)<br/>
> [`match.mdtlbl`](./match.mdtlbl)<br/>
如果没有列出那请在看完上述后自行观看, 顺序可以参考文件创建顺序.

Expand Down
261 changes: 261 additions & 0 deletions examples/match.mdtlbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
#**
* 这是0.14.0增加的新功能, 此功能及其强大, 将编译期能力进行了极大的扩展,
* 借此你甚至可以基于值编写一门LL(k)文法语言的parser与一定的代码生成
*
* 简单概述为凭借对句柄的模式匹配完成分支条件编译
*
* 同时还增加了重复块, 可以对参数进行重复
*
* 修改了参数方式, 由构建期展开为编号参数改为编译期展开特定语句
*
* ---
*
* 内部语句SetArgs, 它将设置参数, 其作用范围为Expand和重复块
*
* 扩展Other, Match和Print的参数,
* 增加展开符`@`, 展开符将会展开为全部参数, 参数来源于SetArgs
*
* 可以使用重复块, 它将在一个内联块中重复给定块, 并且每次重复迭代指定个参数,
* 此数字未指定则为1, 它不能为0, 它是构建期被指定的
*
* match语句
* ===
* 改语句由参数输入, 并在之后的块中编写多个分支.
* 每个分支编写零至多个句柄模式, 和一个分支代码体
*
* 句柄模式由两部分组成: 绑定值 和 模式
*
* 绑定值和模式都是可选的, 模式是由方括号括起的多个值, 顺序匹配其中任意一值
*
* 执行到match语句时, 会先将输入参数take,
* 然后使用得到的多个句柄, 向下对每个分支进行匹配.
*
* 开始匹配一个分支时, 会将该分支中所有模式中的值进行take,
* 然后使用其句柄集合与参数进行完全匹配.
*
* 如果在其中使用`@`符号, 那么将会匹配零个以上参数, 并将匹配到重新设定到参数
*
* 成功完全匹配后, 终止向下探查分支, 并将匹配成功分支的代码体直接编译
*
* 如果没有匹配到任何句柄模式, 那么将不会编译任何代码体,
* 但是参数和每个分支的模式仍被take, 所以需要注意这件事
*#

match a b c d e { @ {} } # 利用match没有作用域来人为的设置参数
print @;
match { @ {} }
#* >>>
print a
print b
print c
print d
print e
*#


# 块作用域
{
match a b c d e { @ {} }
print @;
}
print "xxx";
print @;
#* >>>
print a
print b
print c
print d
print e
print "xxx"
*#


# 重复块的作用域
{
match a b c d e { @ {} }
inline@{
print @;
}
print "xxx";
print @;
}
#* >>>
print a
print b
print c
print d
print e
print "xxx"
print a
print b
print c
print d
print e
*#
# 可以看到, 重复块中最后一次设置的参数并没有影响重复块外的参数


# 重复块迭代数
{
match a b c d e { @ {} }
inline 2@{
print @;
print "---";
}
}
#* >>>
print a
print b
print "---"
print c
print d
print "---"
print e
print "---"
*#


# 利用match完成递归展开
const Foo = (
match @ {
[end] {}
[endl] { print "\n"; }
X @ {
print X;
take Foo[@];
}
}
);
take Foo["Hello" "World!" endl];
take Foo["hi" end];
#* >>>
print "Hello"
print "World!"
print "\n"
print "hi"
*#


# 利用match比较句柄相等
const Eq = (
match @ {
A B { match B {
[A] { print "equal" A B; }
__ { print "notEqual" A B; }
}}
}
);
take Eq[a a];
take Eq[a b];
#* >>>
print "equal"
print a
print a
print "notEqual"
print a
print b
*#


# 利用编译时运算完成计数
const PrintId = (
take N = 0;
inline@{
print N":"@"\n";
take N = ($ = N+1;);
}
);
take PrintId[a b c d];
printflush message1;
#* >>>
print 0
print ":"
print a
print "\n"
print 1
print ":"
print b
print "\n"
print 2
print ":"
print c
print "\n"
print 3
print ":"
print d
print "\n"
printflush message1
*#
# 这里利用了循环块没有作用域来完成


const PrintId = (
match @ {
[begin] @ {
take PrintId[0 @];
}
N Arg @ {
print N":"Arg"\n";
take PrintId[($ = N+1;) @];
}
}
);
take PrintId[begin a b c d];
printflush message1;
#* >>>
print 0
print ":"
print a
print "\n"
print 1
print ":"
print b
print "\n"
print 2
print ":"
print c
print "\n"
print 3
print ":"
print d
print "\n"
printflush message1
*#
# 这里利用了递归展开和嵌套的子作用域来完成


# 句柄匹配的或运算
const GetNum = (
match @ {
[one] {
setres 1;
}
[two] {
setres 2;
}
[three four] {
setres 3.5;
}
}
);
print GetNum[one];
print GetNum[two];
print GetNum[three];
print GetNum[four];
#* >>>
print 1
print 2
print 3.5
print 3.5
*#
# 写在同一个匹配里的多个值即为或运算


# 记住, 它们被take
const YES = yes;
match yes {
[YES] { print "ok"; }
}
#* >>>
print "ok"
*#
5 changes: 5 additions & 0 deletions syntax/vim/mdtlbl.snippets
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,8 @@ endsnippet
snippet sensor "sensor" w
sensor ${1:result} ${2:block1} ${3:@${4:copper}};$0
endsnippet
snippet match "match args... { (pattern body)... }" w
match $1 {
$0
}
endsnippet
4 changes: 3 additions & 1 deletion syntax/vim/mdtlbl.vim
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ syn case match
" 一些关键字 {{{1
syn keyword mdtlblKeyword
\ while gwhile do skip goto if elif else switch case break continue
\ const take setres select
\ const take setres select match
\ inline
\ op set noop print

Expand All @@ -39,6 +39,7 @@ syn keyword mdtlblOpFunKeyword
\ asin acos atan lnot

syn match mdtlblCmpTreeOper /&&\|||\|!/
syn match mdtlblArgsExpand /@/

" 注释 {{{1
syn region mdtlblComment start=/#[^*]\=/ end=/$/ oneline
Expand Down Expand Up @@ -141,4 +142,5 @@ hi def link mdtlblDefineResultHandle Identifier
hi def link mdtlblIdentLabel Label
hi def link mdtlblArgsBracket Macro
hi def link mdtlblQuickDExpTakeIdent Macro
hi def link mdtlblArgsExpand Structure
" }}}1
2 changes: 1 addition & 1 deletion tools/display_source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "display_source"
version = "0.3.2"
version = "0.3.3"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
Loading

0 comments on commit 3452ecf

Please sign in to comment.