1 个不稳定版本

0.0.1 2023年11月17日

23#bedrock

MIT 许可证

26KB
448

mcfn - 一个 mcfunction 预处理器

[!注意] 此预处理器主要针对基岩版,可能不适用于Java版,因为它们的命令语法不同。

概述

理念

不同于为Java版发明一个全新的编程语言,如 mcscriptmcfn 通过扩展 mcfunction 格式以更易读的方式保存重复性任务。

mcfn 利用 executescoreboard 命令在 Minecraft 中模拟运行时环境。这允许使用多个宏进行动态条件编程。

安装

Cargo

cargo install -f mcfn

使用方法

要转换 functions 目录下所有的 *.mcfn 文件,可以使用以下命令。

mcfn functions/**/*.mcfn

参考

缩进

在构建文件中,程序中每行的前导空格将被删除。这允许在代码块中嵌套代码,以获得更好的视觉效果。

#!proc greet
say Hello
say World
#!end

#!! can be written like below as well

#!proc greet
  say Hello
  say World
#!end

注释

有两种不同类型的注释。一种注释以一个井号(#)开头,如通常一样,但不能跟一个感叹号(!)。它们包含在构建文件中,可以在可以使用完整命令的任何地方使用。事实上,它们可以在命令的末尾使用。另一种注释以一个井号和两个感叹号(#!!)开头。它们必须作为整个行使用,这意味着它们不能附加到宏或命令。

with

with 宏在代码块的每一行前添加其参数。

#!with execute as @a
  say Hello
  say World
#!end

#!! same as

executa as @a say Hello
execute as @a say World

proccall

proc 宏创建一个过程。它的内容可以在程序的稍后位置通过使用 call 宏多次调用。

#!proc greet
  say Hello
  say World
#!end

#!call greet
#!call greet

与大多数编程语言不同,过程总是全局的,这意味着可以在不同的过程中定义一个过程,只要调用在过程定义之后存在,就可以从外部调用该过程。

#!call foo
#^^^^^^^^^ error

#!proc foo
  #!proc bar
    say Hello
    say World
  #!end
#!end

#!call bar

过程不能有参数。然而,你可以实现如下所示的行为

scoreboard objectes add _internal dummy

#!proc fizzbuzz
  #!if scores @s _arg_a matches 3
  #!then
    say Hi
  #!else
    say Hello
  #!end
#!end

scoreboard players set @s _arg_a 3
#!call fizzbuzz
scoreboard players reset @s _arg_a

scoreboard players set @s _arg_a 20
#!call fizzbuzz
scoreboard players reset @s _arg_a

log

log 宏在它被到达时将在编译时将它的值打印到控制台。这可能对调试很有用。

#!log hi

ififnelse

你可以使用 if 来验证条件是否满足,并使用 ifn 来验证相反的情况。如果有多个 ififn 宏链式调用,则当 其中一个 条件满足时执行该块。

#!if score @s foo matches 3
#!ifn score @s bar matches 5
#!then
  say Hello
  say World
#!end

你还可以添加一个 else 块,如果没有任何条件满足,则将运行该块。

#!if score @s foo matches 3
#!ifn score @s bar matches 5
#!then
  say Hello
  say World
#!else
  say Bye
  say World
#!end

include

你可以使用 include 宏相对于当前文件包含另一个文件。

#!include path/to/file.in

请注意,包含 mcfn 文件将不会被渲染,因此你只能与不最初需要编译的 mcfunction 程序一起使用(如果该步骤在包含文件之后发生)。

此宏也可以用来包含某种类型的标题,例如通过创建仅由注释组成的 mcfunction 程序来实现。

declaredelete

通过使用 declare 宏可以快速创建分数。使用 delete 宏可以删除分数。

#!declare x
#!delete x

结果将是

scoreboard objectives add x dummy
scoreboard objectives remove x

whenelse

如果你以前使用过像 C 或 Rust 这样的编程语言,你可能熟悉条件编译。条件编译允许你根据配置设置或操作系统等构建可变程序。

if cfg!(any(target_os = "windows", target_os = "linux")) {
    // do performant stuff
} else if cfg!(any(target_os = "android", target_os = "macos")) {
    // do less performant stuff
}

这也可以通过使用 when 宏在 mcfn 中实现。

#!when MCFN_TARGET windows
#!when MCFN_TARGET linux
#!then
  say Hello
#!else
  say Hi
#!end

这些条件将指定的环境变量(如 MCFN_TARGET)与字符串(如 windows)进行比较。当条件满足时渲染该块,否则忽略(如果环境变量未定义也是如此)。其结构与 正常条件 相匹配,只是使用 when 而不是 if,并且不存在取反的 when 宏。请注意,when 分支仍然会运行 loginclude 宏并验证块。在编译步骤中,将忽略 已渲染 的块。

然后你可以通过使用例如以下语法通过 bash 控制编译

MCFN_TARGET="windows" mcfn script.mcfn

需要了解的知识

高亮显示

预处理语言被设计为与 mcfunction 高亮显示器一起看起来很好,因此你可以在你的存储库中使用它。因此,.mcfn.mcfn.mcfunction 都支持作为文件扩展名。

魔法变量

分数 __mcfn_internal_n(其中 n 可以是任何自然数)和“假玩家”名称 __mcfn_internalmcfn 使用,不应在程序中使用,否则可能会导致意外的行为。

在 Allay 中的使用

将以下 ruby 脚本添加到你的脚本目录,并在 allay.toml 中引用它。

# TODO

依赖项

~1.3–1.9MB
~35K SLoC