表达式语法
约 1975 字大约 7 分钟
2025-01-26
WorldEdit 表达式解析器的工作方式类似于 Java 及相关语言,但有一些微妙的区别:
- 在大多数情况下,可以省略最终的分号。
- 序列中的最后一个值始终会被返回,即使没有 return 语句。
- 二元中缀运算符
^
是幂运算符而不是异或运算符,并且具有相应的优先级。 - 有一个后缀阶乘运算符 (
!
)。 - 有一个二元中缀近似运算符 (
~=
)。 - 不支持对象
操作符
表达式解析器使用 Java 的优先级规则,但有以下例外和补充:
- 二元幂运算符 (
^
) 的优先级在 2 和 3 之间 - 后缀阶乘运算符 (
!
) 的优先级为 2 - 近似运算符 (
~=
) 的优先级为 7
二元中缀
这些运算符位于两个操作数之间。
算术运算
运算符 | 说明 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
^ | 幂运算 |
位运算
这些运算符将操作数解释为 32 位整数并对其位进行操作。
运算符 | 说明 |
---|---|
<< | 左移 |
>> | 右移 |
逻辑运算
这些运算符将大于零的值解释为 true,其他值解释为 false。它们返回 1 表示 true,返回 0 表示 false。
运算符 | 说明 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
比较运算
这些运算符比较其操作数,返回 1 表示 true,返回 0 表示 false。
运算符 | 说明 |
---|---|
< | 小于 |
> | 大于 |
<= | 小于或等于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
~= | 近似 |
赋值运算
这些运算符需要左侧为变量。使用简单赋值运算符 (=
) 将值赋给不存在的变量时会创建一个临时变量。
运算符 | 说明 |
---|---|
= | 简单赋值 |
+= | 加法赋值 |
-= | 减法赋值 |
*= | 乘法赋值 |
/= | 除法赋值 |
%= | 取余赋值 |
^= | 幂赋值 |
前缀
这些运算符位于其应用的表达式之前。
前缀运算符
运算符 | 说明 |
---|---|
-x | 负值 |
~x | 按位取反 (参见位运算符) |
!x | 逻辑取反 (参见逻辑运算符) |
++x | 前置递增 |
--x | 前置递减 |
后缀
这些运算符位于其应用的表达式之后。
后缀运算符
运算符 | 说明 |
---|---|
x! | 阶乘 |
x++ | 后置递增 |
x-- | 后置递减 |
三元中缀
三元运算符用于以紧凑的方式表示条件表达式:
<condition> ? <true-branch> : <false-branch>
它的工作方式与 if/else 语句完全相同,只不过分支只能是单一表达式。
函数
数学函数
表达式解析器提供以下来自 Java Math 库的函数:
函数 | 说明 |
---|---|
abs | 返回一个数的绝对值 |
acos | 返回值的反余弦值,返回的角度范围为 0.0 到 pi |
asin | 返回值的反正弦值,返回的角度范围为 -pi/2 到 pi/2 |
atan2 | 返回从直角坐标 (x, y) 转换为极坐标 (r, θ) 的角度 θ |
atan | 返回值的反正切值,返回的角度范围为 -pi/2 到 pi/2 |
cbrt | 返回值的立方根 |
ceil | 返回大于或等于参数且最接近负无穷大的整数值 |
cos | 返回角度的三角余弦值 |
cosh | 返回值的双曲余弦值 |
exp | 返回欧拉数 e 的值的次幂 |
floor | 返回小于或等于参数且最接近正无穷大的整数值 |
ln | 返回值的自然对数 (以 e 为底) |
log | 返回值的自然对数 (以 e 为底) |
log10 | 返回值的 10 为底的对数 |
max | 返回值中的最大值(支持 2 和 3 个参数) |
min | 返回值中的最小值(支持 2 和 3 个参数) |
rint | 返回最接近参数的值并等于一个数学整数 |
round | 返回最接近参数的值 |
sin | 返回角度的三角正弦值 |
sinh | 返回值的双曲正弦值 |
sqrt | 返回值的正确舍入正平方根 |
tan | 返回角度的三角正切值 |
tanh | 返回值的双曲正切值 |
其他函数
此外,还提供以下函数:
函数 | 说明 |
---|---|
rotate(x, y, angle) | 按给定角度(以弧度为单位)旋转给定坐标对 |
swap(x, y) | 交换两个给定变量的内容 |
random() | 返回一个小于 1.0 的随机正数 |
randint(max) | 返回一个小于 max 的随机正整数 |
perlin(seed, x, y, z, frequency, octaves, persisence) | 使用给定参数生成柏林噪声 |
voronoi(seed, x, y, z, frequency) | 使用给定参数生成沃罗诺伊噪声 |
ridgedmulti(seed, x, y, z, frequency, octaves) | 使用给定参数生成嶙峋的多重分形噪声 |
方块查询函数
以下函数可用于在编辑环境中查询世界中的方块。注意它们仍然使用旧版的 ID 和数据,因此对新(1.13 及以上)方块可能会有未定义的行为。
函数 | 说明 |
---|---|
query(x, y, z, type, data) | 如果给定坐标处的方块具有给定的旧 ID 和数据值,则返回 true。如果 type 或 data 是变量,则方块的 ID 和数据会分配给该变量 |
queryRel(dx, dy, dz, type, data) | 类似于 query,但使用相对于当前评估的方块坐标的偏移量 |
queryAbs(xp, yp, zp, type, data) | 类似于 query,但使用绝对世界坐标 |
缓冲区函数
这些函数提供对数据缓冲区(本质上是数组)的访问。提供两个缓冲区,一个是全局共享缓冲区,一个是表达式本地缓冲区。带有 g
前缀的函数访问全局缓冲区,不带 g
前缀的函数访问本地
缓冲区。
函数 | 说明 |
---|---|
(g)megabuf(index) | 返回缓冲区在给定索引处的值 |
(g)megabuf(index, value) | 设置缓冲区在给定索引处的值 |
(g)closest(x, y, z, index, count, stride) | 在count次迭代和每次迭代之间stride的空间内,从给定的索引值开始,找到最接近的 x,y,z 值的索引 |
常量
常量
以下常量始终可用,且不能被赋值。
常量 | 值 | 说明 |
---|---|---|
e | 2.7182818284590452354 | 自然对数的底数 |
pi | 3.14159265358979323846 | 圆的周长与直径之比 |
true | 1 | 布尔操作中表示真 |
false | 0 | 布尔操作中表示假 |
代码块语句
代码块语句是用大括号括起来的一组语句:
{ x=5; y=6; }
它们主要用于控制结构。
控制结构
if/else
if (<condition>) <true-branch>
if (<condition>) <true-branch> else <false-branch>
<condition>
被评估以决定执行哪个分支。- 大于零的值解释为 true,其他值解释为 false。
<true-code>
和<false-code>
可以是用分号分隔的单个语句或代码块语句。
注意: else 关键字总是与最后一个 if 关联。这允许像这样构造 elseif:
if (<condition 1>) <true-code 1> else if (<condition 2>) <true-code 2> else <false-code>
循环
循环最多可以循环 256 次。
while
while (<condition>) <body>
do <body> while (<condition>);
<condition>
被评估以决定是否继续循环。<body>
可以是用分号分隔的单个语句或代码块语句。- do-while 在执行主体后检查条件。
Java/C 风格的 for
for (<init>; <condition>; <increment>) <body>
<init>
、<condition>
和<increment>
是单个表达式。<body>
可以是用分号分隔的单个语句或代码块语句。
执行步骤
首先,<init>
只会评估一次,然后每次迭代按以下步骤进行:
- 如果
<condition>
的评估结果小于或等于零(即为 false),则循环终止。 - 执行
<body>
。 - 执行
<increment>
。
简单 for
for (<counter> = <first>, <last>) <body>
<counter>
是一个用于计数迭代的变量。<first>
和<last>
是单个表达式。<body>
可以是用分号分隔的单个语句或代码块语句。
执行步骤
首先,内部计数器被设置为 <first>
。然后,每次迭代按以下步骤进行:
- 如果内部计数器超过
<last>
,则循环终止。 <counter>
被设置为内部计数器。- 执行
<body>
。 - 内部计数器增加 1.0。
<first>
和 <last>
仅评估一次。