Sacrpet文档不完整翻译V0.1 P1

文件由机器翻译+人工校对

格式是。医学博士

中的字符是代码

没有翻译,直接复制原文 以后会发在 github和 gitee

Scarpet API文档

#scarpet编程语言的基本组成部分。

 

Scarpet是一种编程语言

旨在提供编写自定义程序以在Minecraft中运行的能力

与世界互动。

 

本规范分为两部分:这一部分对任何人都是不可知的

与布雷艇相关的特征和功能,以及

用于特定的雷击程序和世界操纵功能。

 

#概要

 

<pre>

script run print(‘Hello World!’)

</pre>

 

或者一个过于复杂的例子:

 

<pre>

/script run

    block_check(x1, y1, z1, x2, y2, z2, block_to_check) ->

    (

        l(minx, maxx) = sort(l(x1, x2));

        l(miny, maxy) = sort(l(y1, y2));

        l(minz, maxz) = sort(l(z1, z2));

        ‘Need to compute the size of the area of course’;

        ‘Cause this language doesn\’t support comments in the command mode’;

        xsize = maxx – minx + 1;

        ysize = maxy – miny + 1;

        zsize = maxz – minz + 1;

        total_count = 0;

        loop(xsize,

            xx = minx + _ ;

            loop(ysize,

                yy = miny + _ ;

                loop(zsize,

                    zz = minz + _ ;

                    if ( block(xx,yy,zz) == block_to_check,

                        total_count += ceil(rand(1))

                    )

                )

            )

        );

        total_count

    );

    check_area_around_closest_player_for_block(block_to_check) ->

    (

        closest_player = player();

        l(posx, posy, posz) = query(closest_player, ‘pos’);

        total_count = block_check( posx-8,1,posz-8, posx+8,17,posz+8, block_to_check);

        print(‘There is ‘+total_count+’ of ‘+block_to_check+’ around you’)

    )

/script invoke check_area_around_closest_player_for_block ‘diamond_ore’

</pre>

 

或者只是

 

<pre>

/script run print(‘There is ‘+for(rect(x,9,z,8,8,8), _ == ‘diamond_ore’)+’ diamond ore around you’)

</pre>

 

检查更高级别的`scarpet`函数必须提供哪些功能是值得的。

 

#程序

 

你可以把程序想象成一个数学表达式,比如`2.4*sin(45)/(2-4)“或者`sin(y)>0&max(z,3)>3“。

写一个程序,就像写一个`2+3`,只是长一点。

 

##基本语言组件

 

程序由常量组成,如`2`,`3.14`,`pi`,或`foo`,运算符,如`+`,`/`,`->`,这些变量

可以定义,比如`foo`或将为您定义的特殊对象,比如`x`或`x`,我为每个

内置函数,以及具有名称的函数,参数形式为`f(a,b,c)`,其中`f`是函数名,

和`a,b,c`是可以是任何其他表达式的参数。这就是语言的全部,也是全部

总之-听起来很简单。

 

##代码流

 

像任何其他合适的编程语言一样,`scarpet`需要括号,基本上用来标识东西的开始和结束

结束的地方。在使用更复杂结构的语言中,比如Java,它们倾向于使用各种类型的

它们,圆的表示函数调用,花的表示代码段,正方形表示访问列表,尖的表示

泛型类型等。。。我的意思是-没有etc,因为他们已经用尽了所有的括号选项。。。

 

`Scarpet是不同的,因为它运行的一切都基于函数(虽然它本身不是函数)

语言(如lisp)只需要圆括号,一切都由程序员来组织

它的代码是可读的,因为添加更多的括号对程序的性能没有任何影响

因为它们是在执行之前编译的。请看下面的`if()`函数用法示例:

 

<pre>

if(x&lt;y+6,set(x,8+y,z,’air’);plop(x,top(‘surface’,x,z),z,’birch’),sin(query(player(),’yaw’))&gt;0.5,plop(0,0,0,’boulder’),particle(‘fire’,x,y,z))

</pre>

 

你喜欢看书吗

 

<pre>

if(   x&lt;y+6,

           set(x,8+y,z,’air’);

           plop(x,top(‘surface’,x,z),z,’birch’),

      sin(query(player(),’yaw’))>0.5,

           plop(0,0,0,’boulder’),

      particle(‘fire’,x,y,z)

)

</pre>

 

或者更确切地说:

 

<pre>

if

(   x&lt;y+6,

    (

        set(x,8+y,z,’air’);

        plop(x,top(‘surface’,x,z),z,’birch’)

    ),

    // else if

    sin(query(player(),’yaw’))>0.5,

    (

        plop(0,0,0,’boulder’)

    ),

    // else

    particle(‘fire’,x,y,z)

)

</pre>

 

不管你喜欢哪种款式都无所谓。这通常取决于形势和问题的复杂性

子组件。无论您添加多少空格和额外的方括号,代码的计算结果都将完全相同

相同的表达式,并且将运行完全相同的程序,所以请确保您的程序是好的和干净的,这样其他人就不会

有问题吗

 

##功能和范围

 

用户可以以`fun(args….)->expression`的形式定义函数,并对其进行编译和保存,以备将来使用

在这个执行过程中,还可以后续调用/script命令,添加到事件等函数

分配给变量,

作为参数传递,用`call(`fun`,args…)`函数调用,但在大多数情况下

直接打电话给他们

名称,格式为`fun(args…)`。这意味着,一旦定义了函数,就可以与世界一起保存

进一步使用。对于变量,有两种类型,全局的-在代码的任何地方共享,

这些都是以`global`开头的名字,还有局部变量,其他的都是

仅在每个函数内部可见。这也意味着函数中的所有参数都是

`按值传递`,而不是`按引用传递`。

 

##外部变量

 

通过将变量添加到函数签名包中,函数仍然可以从外部作用域`借用`变量

围绕内置函数`outer`。它将指定的值添加到函数调用堆栈中,使它们的行为完全一致

类似于在Java中捕获lambda,但与Java不同,捕获的变量不需要是final。斯卡佩特会

在函数定义时附加它们的新值,即使它们以后会更改。最有价值的是

复制但可变的值,如映射或列表,允许保留函数的`状态`,允许它们

有记忆,可以说像物体一样行动。有关详细信息,请选中`outer(var)`。

 

##代码传递,行指示符

 

请注意,这应该只适用于粘贴要用commandblock执行的代码。Scarpet建议

应用程序中的代码(扩展名为`.sc`的文件,可以放在world files中的`/scripts`文件夹中)

或者作为一个全球可用的应用程序在singleplayer中的`.minecraft/config/carpet/scripts`文件夹中加载

作为带有命令`/script load[app name]`的Scarpet应用程序。从磁盘加载的Scarpet应用程序只应

包含代码,不需要以`/script run`前缀开头。

 

以下是可以在world`/scripts`文件夹中的`foo.sc` app文件中提供的代码

 

<pre>

run_program() -> (

  loop( 10,

    // looping 10 times

    // comments are allowed in scripts located in world files

    // since we can tell where that line ends

    foo = floor(rand(10));

    check_not_zero(foo);

    print(_+’ – foo: ‘+foo);

    print(‘  reciprocal: ‘+  _/foo )

  )

);

check_not_zero(foo) -> (

  if (foo==0, foo = 1)

)

</pre>

 

我们称之为游戏中的:

 

<pre>

/script load foo

/script in foo invoke run_program

</pre>

 

但是,以下代码也可以作为命令或命令块输入。

 

由于可以输入聊天室的最大命令长度有限,因此您可能需要插入

通过将它们粘贴到命令块或从世界文件中读取来执行程序,但是粘贴到命令块将

删除一些空白并压扁新行,使代码不可读。如果您粘贴的程序

是完美的,永远不会造成错误,我向你致敬,但在大多数情况下,它很可能是你的程序

可能会在编译时(最初分析时)或执行时(突然尝试

把某物除以零。在这些情况下,您可能希望得到一条有意义的错误消息,但为此,您需要

需要为编译器指出这些新行放在哪里,因为命令块会压扁它们。为此,

放在行的开头,让编译器知道您在哪里。这使得`$`是唯一的

在程序中是非法的字符,因为它将被替换为新行。据我所知,`$`不是

在Minecraft标识符中的任何地方使用,所以这不应该妨碍你程序的能力。

 

考虑以下作为命令块命令执行的程序:

 

<pre>

/script run

run_program() -> (

loop(10,

foo=地板(rand());

check_not_zero(foo);

print(`+`-foo:`+foo`);

print(`交互:`+0/foo)

)

);

check_not_zero(foo)->(

if (foo==0,foo=1)

)

</pre>

 

假设其目的是检查条是否为零,并防止在打印时被零除,但因为

`foo`作为变量传递,它从不更改原始foo值。因为不可避免的分裂

到0,我们得到以下信息:

 

<pre>

Your math is wrong, Incorrect number format for NaN at pos 98

run_program() -> ( loop( 10, foo = floor(rand(_)); check_not_zero(foo); print(_+’ – foo: ‘+foo);

HERE>> print(‘ reciprocal: ‘+ _/foo ) ));check_not_zero(foo) -> ( if (foo==0, foo = 1))

</pre>

 

如我们所见,我们得到的问题,数学运算的结果不是一个数字

(无穷大,所以不是一个数字),但是通过将我们的程序粘贴到命令中,使它如此压缩换行符

虽然很清楚错误发生在哪里,我们仍然可以跟踪错误,但是错误的位置(98)

是不是很有帮助,也不会有用,如果该程序得到显着更长。为了解决这个问题,我们可以

在脚本的每一行前面加上美元符号`$`:

 

<pre>

/script run

$run_program() -> (

$  loop( 10,

$    foo = floor(rand(_));

$    check_not_zero(foo);

$    print(_+’ – foo: ‘+foo);

$    print(‘  reciprocal: ‘+  _/foo )

$  )

$);

$check_not_zero(foo) -> (

$   if (foo==0, foo = 1)

$)

</pre>

 

然后我们得到以下错误消息

 

<pre>

Your math is wrong, Incorrect number format for NaN at line 7, pos 2

  print(_+’ – foo: ‘+foo);

   HERE>> print(‘ reciprocal: ‘+ _/foo )

  )

</pre>

 

正如我们所注意到的,我们不仅得到了更简洁的片段,还得到了关于行号和位置的信息,

所以这意味着它更容易找到潜在的问题

 

显然这不是我们计划的工作方式。要通过函数调用修改foo,

我们要么返回结果并将其赋给新变量:

 

<pre>

foo = check_not_zero(foo);

check_not_zero(foo) -> if(foo == 0, 1, foo)

</pre>

 

.. 或者将其转换为全局变量,在本例中,不需要将其作为参数传递

 

<pre>

global_foo = floor(rand(10));

check_foo_not_zero();

check_foo_not_zero() -> if(global_foo == 0, global_foo = 1)

</pre>

 

##Scarpet预处理器

 

有几个预处理操作应用于程序的源代码,以清理它并准备

执行。其中一些会影响您的代码,因为它是通过堆栈跟踪和函数定义报告的,还有一些

仅适用于表面。

-剥离`//`注释(在文件模式下)

-用换行符替换`$`(在命令模式下,修改提交的代码)

-删除不跟在`;`后面的分号用作二进制运算符,允许轻松使用分号

-将`{`翻译成`m(`,`[`翻译成`l(`,`]`和`}`翻译成`)`

 

当前没有对代码应用进一步的优化。

 

##提到

 

LR1解析器,标记器和几个内置函数都是基于EvalEx项目构建的。

EvalEx是一个方便的Java表达式计算器,它允许

简单的数学和布尔表达式。EvalEx是在麻省理工学院许可下发行的。

#变量和常量

 

`scarpet `提供了许多可以在脚本中直接使用的常量

 

*`null`:没什么,zilch,甚至不假

*`true`:纯true,可以充当`1“

*`假`:假真或真假等于 `0` `

*‘pi’:对于周长的扇子来说,它是直径为1的苹果pi的周长。约3.14

*欧拉:聪明的家伙。其指数的导数为1\。约2.72

 

除此之外,还有一堆系统变量,以“开头,由“scarpet`内置设置,

像“`,通常是循环中的每个连续值,“i`表示迭代,或者“a`像累加器

用于`reduce`函数。对Minecraft特定调用的某些调用也会设置` x`,` y`,` z`,表示

封锁阵地。所有以“开头的变量都是只读的,不能在客户机代码中声明和修改。

 

##文字

 

`scarpet`接受数字和字符串常量。数字看起来像`1,2.5,-3e-7,0xff,`并且是内部的

主要表示为Java的`double`,但是`scarpet`会尽可能地修剪尾随的零,所以如果

需要将它们用作整数甚至长-你可以。长值也不会失去它们的长精度,

减法,求反和乘法,但是不能保证返回长值的任何其他运算

(如除法)在一个数字上,即使它可以适当地

表示为long,将使它们转换为double。

 

字符串使用单引号有多种原因,但主要是为了允许

在双引号命令参数中更容易使用字符串(将脚本作为`/script fill`的参数传递时)

例如),或者在scarpet中输入json(例如反馈到`/data merge`命令中)。

在普通字符串和正则表达式中,字符串还使用反斜杠`\`来引用特殊字符

 

<pre>

‘foo’

print(‘This doesn\’t work’)

nbt ~ ‘\\.foo’   // matching ‘.’ as a ‘.’, not ‘any character match’

</pre>

#操作员

 

在表达式中可以使用许多运算符。这些可以被视为泛型类型运算符

适用于大多数数据类型。它们还遵循标准运算符优先级,即理解`2+2*2`

作为`2+(2*2)`,而不是`(2+2)*2`,否则从左到右应用,即解释`2+4-3`

作为`(2+4)-3`,这在数字的情况下并不重要,但是因为“scarpet`允许混合所有值类型

关联性很重要,可能会导致意外的影响:

 

重要的运算符是函数定义`->`运算符。它将被覆盖

在[用户定义函数和程序控制流](docs/scarpet/language/Functions和controlflow.md)中

 

<pre>

‘123’+4-2 => (‘123’+4)-2 => ‘1234’-2 => ‘134’

‘123’+(4-2) => ‘123’+2 => ‘1232’

3*’foo’ => ‘foofoofoo’

1357-5 => 1352

1357-‘5’ => 137

3*’foo’-‘o’ => ‘fff’

[1,3,5]+7 => [8,10,12]

</pre>

 

如您所见,在同一表达式中与其他类型混合时,值的行为可能不同。

如果值的类型相同,结果往往很明显,但`Scarpet`试图理解任何东西

它必须处理

 

##运算符优先级

 

下面是`scarpet`中操作符的完整列表,包括控制流操作符。注意,逗号和括号

从技术上讲,它们不是运算符,而是语言的一部分,即使它们看起来像:

 

*匹配,获取`~:`

*一元`+-`

*指数`^`

*乘法`*/%`

*加法`+-`

*比较`>>=<=<`

*平等`===`

*逻辑与`&&`

*逻辑或`||`

*作业`=+=<>`

*定义`->`

*下一个语句“

*逗号“

*括号`()`

 

### `Get,访问器运算符:`

 

`get(…)`函数的运算符版本,用于访问列表,映射和其他容器的元素

(即NBTs)。区分`~`运算符很重要,它是一个匹配运算符,期望

执行一些额外的计算来检索结果,而`:`应该是直接的,即时的,并且

源对象的行为应类似于容器,并支持完整容器API,

表示`get(…)“,`put(…)“,`delete(…)“和`has(…)`函数`

 

对于某些运算符和函数(get,put,delete,has,=,+=),对象可以使用`:`注释字段作为l值,

意构式`foo:0 = 5`,类似于`put(foo,0,5)`,而不是`get(foo,0)=5`,

这会导致一个错误。

 

TODO:添加有关l值行为的更多信息。

 

### `匹配运算符~`

 

此运算符应理解为`matches`,`contains`,`is in`或`find me something about something`。

对于字符串,它将右操作数作为正则表达式匹配到左操作数,返回:

-如果不匹配,则返回`null`

-匹配短语(如果未应用分组)

-匹配元素(如果应用了一个组)

-如果应用了多个分组,则列出匹配项

 

这可用于以更复杂的方式从未分析的nbt中提取信息(使用`get(…)`for

更合适的方法)。对于列表,它检查元素是否在列表中,并返回

该元素的索引,如果找不到此类元素,则为`null`,特别是使用`first(…)`

函数不会返回索引。目前它对数字没有任何特殊的行为-它检查

左操作数相对于上正则表达式的字符串表示中的字符的存在性

右手边。

 

在Minecraft API中,`entity~feature`部分是`query(entity,feature)`的快捷码,用于不接受

任何额外的参数。

 

<pre>

[1,2,3] ~ 2  => 1

[1,2,3] ~ 4  => null

‘foobar’ ~ ‘baz’  => null

‘foobar’ ~ ‘.b’  => ‘ob’

‘foobar’ ~ ‘(.)b’  => ‘o’

‘foobar’ ~ ‘((.)b)’  => [‘ob’, ‘o’]

‘foobar’ ~ ‘((.)(b))’  => [‘ob’, ‘o’, ‘b’]

‘foobar’ ~ ‘(?:(.)(?:b))’  => ‘o’

player(‘*’) ~ ‘gnembon’  // null unless player gnembon is logged in (better to use player(‘gnembon’) instead

p ~ ‘sneaking’ // if p is an entity returns whether p is sneaking

</pre>

 

或者是一个寻找鱿鱼的无效方法的较长的例子

 

<pre>

entities = entities_area(‘all’,x,y,z,100,10,100);

sid = entities ~ ‘Squid’;

if(sid != null, run(‘execute as ‘+query(get(entities,sid),’id’)+’ run say I am here ‘+query(get(entities,sid),’pos’) ) )

</pre>

 

或者一个例子,以找出如果一个球员有一个特定的附魔持斧(任何一只手),并获得其水平

(未通过`get(…)“使用正确的NBTs查询支持):

 

<pre>

global_get_enchantment(p, ench) -> (

$   for([‘main’,’offhand’],

$      holds = query(p, ‘holds’, _);

$      if( holds,

$         [what, count, nbt] = holds;

$         if( what ~ ‘_axe’ && nbt ~ ench,

$            lvl = max(lvl, number(nbt ~ ‘(?<=lvl:)\\d’) )

$         )

$      )

$   );

$   lvl

$);

/script run global_get_enchantment(player(), ‘sharpness’)

</pre>

 

### `基本算术运算符+-*/`

 

允许添加两个表达式的结果。如果操作数解析为数字,则结果是算术运算。

对于字符串,从字符串中加或减将导致字符串串联和删除子字符串

从那根绳子上。字符串和数字相乘的结果是将字符串重复N次并得到除法结果

在字符串的第一个第k部分,所以`str*n/n~str`

 

如果第一个操作数是一个列表,则

结果是一个新的列表,其中所有元素都被另一个操作数逐个修改,或者如果该操作数是一个列表

具有相同的项数-按元素进行加法/减法。这将优先考虑将列表视为值容器

作为向量处理的列表。

 

使用maps(`{}`或`m()`)进行加法,如果两个操作数都是maps,则会产生一个新的maps,其中两个maps的键都被添加,

将right参数的元素添加到键,left map的元素,或者只是将right值添加为新键

在输出映射中。

 

示例:

 

<pre>

2+3 => 5

‘foo’+3+2 => ‘foo32’

‘foo’+(3+2) => ‘foo5’

3+2+’bar’ => ‘5bar’

‘foo’*3 => ‘foofoofoo’

‘foofoofoo’ / 3 => ‘foo’

‘foofoofoo’-‘o’ => ‘fff’

[1,2,3]+1  => [2,3,4]

b = [100,63,100]; b+[10,0,10]  => [110,63,110]

{‘a’ -> 1} + {‘b’ -> 2} => {‘a’ -> 1, ‘b’ -> 2}

</pre>

 

### `仅运算符%^`

 

只有当两个操作数都是数字时,模和指数(幂)运算符才起作用

 

<pre>

pi^pi%euler  => 1.124….

-9 % 4  => -1

9 % -4  => 0 ¯\_(ツ)_/¯ Java

-3 ^ 2  => 9

-3 ^ pi => // Error

</pre>

 

### `比较运算符==!=<><=>=`

 

允许比较两个表达式的结果。对于数字,它考虑的是数字的算术顺序

字符串-按字典顺序排列,空值总是比其他值`少`,列表检查它们的元素-

如果大小不同,则大小很重要,否则,将对每个元素执行成对比较。

与所有这些运算符相同的顺序规则用于`sort`使用的默认排序顺序

功能。所有这些都是正确的:

 

<pre>

null == null

null != false

0 == false

1 == true

null < 0

null < -1000

1000 < ‘a’

‘bar’ < ‘foo’

3 == 3.0

</pre>

 

### `逻辑运算符&&||`

 

这些运算符分别计算操作数上的布尔运算。重要的是如果计算

第二个操作数不是必需的,它不会被计算,这意味着可以将它们用作条件语句。在

case of success返回第一个正操作数(` | `)或最后一个正操作数(`&&`)。

 

<pre>

true || false  => true

null || false => false

false || null => null

null != false || run(‘kill gnembon’)  // gnembon survives

null != false && run(‘kill gnembon’)  // when cheats not allowed

null != false && run(‘kill gnembon’)  // gnembon dies, cheats allowed

</pre>

 

### `赋值运算符=<>+=`

 

一组赋值运算符。在LHS上都需要有界变量,`<>`在LHS上需要有界参数

右边也是(有界的,意思是变量)。此外,它们还可以处理列表构造函数

使用所有有界变量,然后作为列表赋值运算符。当在列表上使用`+=`时,它会扩展

元素的列表,并返回列表(old==new)`scarpet`当前不支持删除项目。

可以通过`filter`命令删除项目,并将其重新分配给同一变量。两次行动都会

无论如何都需要重写数组。

 

<pre>

a = 5  => a == 5

[a,b,c] = [3,4,5] => a==3, b==4, c==5

[minx,maxx] = sort(xi,xj);  // minx assumes min(xi, xj) and maxx, max(xi, xj)

[a,b,c,d,e,f] = [range(6)]; [a,b,c] <> [d,e,f]; [a,b,c,d,e,f]  => [3,4,5,0,1,2]

a = [1,2,3]; a += 4  => [1,2,3,4]

a = [1,2,3,4]; a = filter(a,_!=2)  => [1,3,4]

</pre>

 

### `一元运算符-+`

 

需要一个数字,翻转标志。断言它是一个数字的一种方法是使脚本崩溃。gg。

 

<pre>

-4  => -4

+4  => 4

+’4′  // Error message

</pre>

 

### `求反运算符 !`

 

翻转表达式的布尔条件。等价于`bool(expr)==false`

 

<pre>

!true  => false

!false  => true

!null  => true

!5  => false

!l() => true

!l(null) => false

</pre>

 

### `解包运算符 …`

 

将迭代器列表中的元素解压到函数中的一系列参数中,从而生成`fun(…[1,2,3])`

与`fun(1,2,3)`相同。对于映射,它将它们解压到一个键值对列表中。

 

在函数签名中,它标识vararg参数。

 

<pre>

fun(a, b, … rest) -> [a, b, rest]; fun(1, 2, 3, 4)    => [1, 2, [3, 4]]

</pre>

 

`…`的效果可以惊人地持久。它通过使用变量和函数调用来保持。

 

<pre>

fun(a, b, … rest) -> [a, b, … rest]; fun(1, 2, 3, 4)    => [1, 2, 3, 4]

args() -> … [1, 2, 3]; sum(a, b, c) -> a+b+c; sum(args())   => 6

a = … [1, 2, 3]; sum(a, b, c) -> a+b+c; sum(a)   => 6

</pre>

 

解包机制可以用于列表和映射压缩,而不仅仅是函数调用。

 

<pre>

[…range(5), pi, …range(5,-1,-1)]   => [0, 1, 2, 3, 4, 3.14159265359, 5, 4, 3, 2, 1, 0]

{ … map(range(5),  _  -> _*_ )}   => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

{…{1 -> 2, 3 -> 4}, …{5 -> 6, 7 -> 8}}   => {1: 2, 3: 4, 5: 6, 7: 8}

</pre>

 

精细打印:参数列表的解包发生在函数求值之前。

这意味着在某些情况下,例如

当需要表达式(`map(list,expr)`)或函数不应计算某些(most!)它的参数(`if(…)`),

解包无法使用,将被忽略,留下`。。。list`与`list`相同。

不尊重解包机制的函数,一开始就不应该使用它

(即,有一个或非常明确的,非常具体的参数),

因此,建议谨慎(测试前)。其中一些多参数内置函数

`if`,`try`,`sort key`,`system variable get`,`synchronize`,`sleep`,`in dimension`,

所有容器函数(`get`,`has`,`put`,`delete`),

以及所有循环函数(`while`,`loop`,`map`,`filter`,`first`,`all`,`c_for`,`for`和`reduce`)。

 

#算术运算

 

##基本算术函数

 

他们有很多人——他们需要一个数字,然后吐出一个数字,做你希望他们做的事情。

 

### `fact(n)`

 

一个数的阶乘,又称n,只是不在`scarpet`里。变大了。。。快。。。

 

### `sqrt(n)`

 

平方根。对于其他花哨的词根,请使用`^`,数学和yo noggin。想象一下树上的平方根。。。

 

### `abs(n)`

 

绝对值。

 

### `round(n)`

 

最接近的整数值。你知道地球也是圆的吗?

 

### `floor(n)`

 

仍然不大于`n`的最大整数。在这里插入地板双关语。

 

### `ceil(n)`

 

第一个不小于`n`的幸运整数。正如你所料,天花板通常就在地板的正上方。

 

### `ln(n)`

 

n的自然对数。当然。

 

### `ln1p(n)`

 

n+1的自然对数。非常乐观。

 

### `log10(n)`

 

n的十进制对数。它的天花板和地板一样长。

 

### `log(n)`

 

n的二元对数。最后,一个合适的,不像前11个。

 

### `log1p(n)`

 

n+1的二元对数。也总是积极的。

 

### `mandelbrot(a,b,极限)`

 

为集合`a`和`b`计算mandelbrot集合的值。找出甲虫。为什么不。

 

### `min(arg,…),min(列表),max(arg,…),max(列表)`

 

假设默认排序顺序,计算提供的参数的最小值或最大值。

如果缺少argmax,只需使用a~max(a),效率稍低,但仍然很有趣。

 

有趣的位-`min`和`max`不会从参数中删除变量关联,这意味着可以用作

赋值的LHS(明显的情况),或者函数定义中的参数spec(远不那么明显)。

 

<pre>

a = 1; b = 2; min(a,b) = 3; l(a,b)  => [3, 2]

a = 1; b = 2; fun(x, min(a,b)) -> l(a,b); fun(3,5)  => [5, 0]

</pre>

 

完全不知道,后者在实践中如何有用。但既然它编译好了,就可以发货了。

 

### `relu(n)`

 

n的线性整流器。0低于0,n高于0。为什么不呢`max(0,n)`道德影响较小。

 

## 三角函数/几何函数

 

### `sin(x)`

### `cos(x)`

### `tan(x)`

### `asin(x)`

### `acos(x)`

### `atan(x)`

### `atan2(x,y)`

### `sinh(x)`

### `cosh(x)`

### `tanh(x)`

### `sec(x)`

### `csc(x)`

### `sech(x)`

### `csch(x)`

### `cot(x)`

### `acot(x)`

### `coth(x)`

### `asinh(x)`

### `acosh(x)`

### `atanh(x)`

### `rad(deg)`

### `deg(rad)`

 

随心所欲

# 系统功能

 

## 类型转换函数

 

### `copy(expr)`

 

返回表达式的深度副本。可用于复制可变对象,如地图和列表

 

### `type(expr)`

 

返回指示表达式类型的字符串值。可能的结果

是`null`,`number`,`string`,`list`,`map`,`iterator`,`function`,`task`,

以及`block`,`entity`,`nbt`,`text`等与地雷相关的概念。

 

### `bool(expr)`

 

返回表达式的布尔上下文。

Bool还将字符串值解释为boolean值,这与其他方法不同

可以使用布尔上下文的位置。这可用于API函数向其返回字符串值的地方

表示二进制值。

 

bool(pi) => true

bool(false) => false

bool(”) => false

bool(l()) => false

bool(l(”)) => true

bool(‘foo’) => true

bool(‘false’) => false

bool(‘nulL’) => false

if(‘false’,1,0) => true

</pre>

 

### `number(expr)`

 

返回表达式的数字上下文。可用于从字符串或其他类型读取数字

 

<pre>

number(null) => 0

number(false) => 0

number(true) => 1

number(”) => null

number(‘3.14’) => 3.14

number(l()) => 0

number(l(”)) => 1

number(‘foo’) => null

number(‘3bar’) => null

number(‘2’)+number(‘2’) => 4

</pre>

 

### `str(expr)`,`str(expr, params? … )`, `str(expr, param_list)`

 

如果用一个参数调用,则返回该值的字符串表示形式。

 

否则,返回表示表达式的格式化字符串。格式化的参数可以提供为

每个连续的参数,或作为一个列表,然后将是唯一的额外参数。格式化一个列表参数

,可以使用`str(list)`或`str(`foo%s`,l(list))`。

 

接受`String.format`接受的格式样式。

支持的类型(使用“%<?>“语法):

 

*   `d`, `o`, `x`: integers, octal, hex

*   `a`, `e`, `f`, `g`: floats

*   `b`: booleans

*   `s`: strings

*   `%%`: ‘%’ character

 

<pre>

str(null) => ‘null’

str(false) => ‘false’

str(”) => ”

str(‘3.14’) => ‘3.14’

str([]) => ‘[]’

str([”]) => ‘[]’

str(‘foo’) => ‘foo’

str(‘3bar’) => ‘3bar’

str(2)+str(2) => ’22’

str(‘pi: %.2f’,pi) => ‘pi: 3.14’

str(‘player at: %d %d %d’,pos(player())) => ‘player at: 567, -2423, 124’

</pre>

 

* * *

## 线程和并行执行

 

Scarpet允许与主脚本执行线程并行运行执行线程。在Minecraft中,应用程序

在主服务器线程上执行。既然雷艇本身就不是线程安全的,那就不是了

有利于并行执行,以便更快地访问世界资源。`getBlockState`和`setBlockState`

不是线程安全的,需要将执行停在服务器线程上,这些请求可以在服务器线程中执行

两次滴答之间的停止滴答的时间,并不需要全部50毫秒。但是并行运行也有好处,

像精细的时间控制不依赖滴答的时钟,或运行的东西相互独立。你还可以跑

您的操作是逐点进行的,或者使用`game tick()`API函数控制执行

(讨厌的解决方案),或者使用 `schedule()` 函数调度tick(首选解决方案),但是线程提供了更多的控制

在时间上不影响主博弈,是解决并行问题的唯一方法

(参见[scarpet camera](/src/main/resources/assets/carpet/scripts/camera.sc))。

 

由于游戏的限制,线程也有一些限制。你不能因为

实例 `join_task()` 完全来自主脚本和服务器线程,因为任何对Minecraft的使用都是特定的

需要任何世界访问的函数,将需要在主线程上驻车并连接以获得世界访问,

这意味着对该任务调用join将不可避免地导致典型的死锁。你仍然可以加入任务

因为在这种情况下,死锁的唯一可能来自

糟糕的代码,而不是内部世界访问行为。有些事情很棘手,比如玩家或实体操纵,可能是

有效地并行化。

 

如果应用程序正在关闭,则通过`task`创建新任务将不会成功。相反,新任务将什么也不做而返回

`null`,因此大多数线程化应用程序应该能够自然地处理关闭的应用程序。请记住,如果您依赖于任务返回值,

不管在这些情况下发生什么,它们都将返回`null`。当应用程序处理` on close()`事件时,新任务将无法执行

此时无法提交,但当前任务不会终止。应用程序可以利用这个机会优雅地关闭它们的任务。

无论应用程序是否处理` on close()`事件,或对其中的任务执行任何操作,所有任务都将异常终止

在接下来的1.5秒内。

 

### `task(function, … args)`, `task_thread(executor, function, … args)`

 

创建并运行并行任务,将句柄返回给任务对象。任务将返回

函数,或者在任务仍在进行时立即返回`null`,因此获取

任务对象是非阻塞的。函数可以是函数值,函数lambda或现有函数的名称

定义的函数。如果函数需要参数来调用,则应在函数之后提供参数

名称或值“task thread`中的executor`identifier`将任务放入由该值标识的特定队列中。

默认线程值是`null`线程。对于任何执行者,并行任务的数量没有限制,

因此,使用不同的队列仅用于同步目的。

 

<pre>

task( _() -> print(‘Hello Other World’) )  => Runs print command on a separate thread

foo(a, b) -> print(a+b); task(‘foo’,2,2)  => Uses existing function definition to start a task

task_thread(‘temp’, ‘foo’,3,5);  => runs function foo with a different thread executor, identified as ‘temp’

a = 3; task_thread(‘temp’, _(outer(a), b) -> foo(a,b), 5)  

    => Another example of running the same thing passing arguments using closure over anonymous function as well as passing a parameter.

</pre>

 

如果您想基于模块中未定义的函数创建任务,请阅读上的提示

`将函数引用传递给应用程序的其他模块`部分。

 

### `sleep()` `sleep(timeout)`, `sleep(timeout, close_expr)`

 

 

暂停线程(或游戏本身,如果不是作为任务的一部分运行)的执行 `expr` 毫秒。

它检查中断的执行,在这种情况下退出线程(或者整个程序,如果不是在线程上运行的话)以防应用程序

正在停止/删除。如果指定了关闭表达式,则在触发关闭信号时执行该表达式。

如果在主线程上运行(即不作为任务运行),则只有在整个游戏关闭时才能调用close表达式,因此只能调用close

对线程有意义。对于常规程序,请使用` on close()`处理程序。

 

由于`close_expr`是在应用程序关闭启动后执行的,因此您将无法在该块中创建新任务。线程

应该定期调用`sleep`,以确保所有应用程序任务在应用程序关闭时或之后立即完成,但应用程序引擎

不会强制删除正在运行的任务,因此任务本身需要正确响应关闭请求。

 

<pre>

sleep(50)  # wait for 50 milliseconds

sleep(1000, print(‘Interrupted’)) # waits for 1 second, outputs a message when thread is shut down.

</pre>

 

### `task_count(executor?)`

 

如果未提供参数,则返回此时使用scarpet并行执行的任务总数

穿线系统。如果提供了执行器,则返回该提供程序的活动任务数。使用 `task_count(null)` 

仅获取默认执行器的任务计数。

 

### `task_value(task)`

 

返回任务返回值,如果任务尚未完成,则返回 `null`。这是一个非阻塞操作。与 `join task` 不同,

可以在任何时候调用任何任务

 

资源下载: