Merge branch 'master' into 1.17

This commit is contained in:
gnembon committed 2021-05-05 01:31:00 -03:00
commit 820c9b6489
31 files changed
+1188 -211

No files matched your search

+66 -7
View File
@@ -356,11 +356,12 @@ Here is the complete list of operators in `scarpet` including control flow opera
are not technically operators, but part of the language, even if they look like them:
* Match, Get `~ :`
* Unary `+ - !`
* Unary `+ - ! ...`
* Exponent `^`
* Multiplication `* / %`
* Addition `+ -`
* Comparison `== != > >= <= <`
* Comparison `> >= <= <`
* Equality `== !=`
* Logical And`&&`
* Logical Or `||`
* Assignment `= += <>`
@@ -561,6 +562,45 @@ flips boolean condition of the expression. Equivalent of `bool(expr)==false`
!l() => true
!l(null) => false
</pre>
### `Unpacking Operator ...`
Unpacks elements of a list of an iterator into a sequence of arguments in a function making so that `fun(...[1, 2, 3])` is
identical with `fun(1, 2, 3)`. For maps, it unpacks them to a list of key-value pairs.
In function signatures it identifies a vararg parameter.
<pre>
fun(a, b, ... rest) -> [a, b, rest]; fun(1, 2, 3, 4) => [1, 2, [3, 4]]
</pre>
Effects of `...` can be surprisingly lasting. It is kept through the use of variables and function calls.
<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>
Unpacking mechanics can be used for list and map constriction, not just for function calls.
<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>
Fine print: unpacking of argument lists happens just before functions are evaluated.
This means that in some situations, for instance
when an expression is expected (`map(list, expr)`), or a function should not evaluate some (most!) of its arguments (`if(...)`),
unpacking cannot be used, and will be ignored, leaving `... list` identical to `list`.
Functions that don't honor unpacking mechanics, should have no use for it at the first place
(i.e. have one, or very well-defined, and very specific parameters),
so some caution (prior testing) is advised. Some of these multi-argument built-in functions are
`if`, `try`, `sort_key`, `system_variable_get`, `synchronize`, `sleep`, `in_dimension`,
all container functions (`get`, `has`, `put`, `delete`),
and all loop functions (`while`, `loop`, `map`, `filter`, `first`, `all`, `c_for`, `for` and`reduce`).
# Arithmetic operations
## Basic Arithmetic Functions
@@ -772,7 +812,7 @@ are not thread safe and require the execution to park on the server thread, wher
the off-tick time in between ticks that didn't take all 50ms. There are however benefits of running things in parallel,
like fine time control not relying on the tick clock, or running things independent on each other. You can still run
your actions on tick-by-tick basis, either taking control of the execution using `game_tick()` API function
(nasty solution), or scheduling tick using `schedule()` function (preffered solution), but threading gives much more control
(nasty solution), or scheduling tick using `schedule()` function (preferred solution), but threading gives much more control
on the timings without impacting the main game and is the only solution to solve problems in parallel
(see [scarpet camera](/src/main/resources/assets/carpet/scripts/camera.sc)).
@@ -786,7 +826,10 @@ effectively parallelized.
If the app is shutting down, creating new tasks via `task` will not succeed. Instead the new task will do nothing and return
`null`, so most threaded application should handle closing apps naturally. Keep in mind in case you rely on task return values,
that they will return `null` regardless of anything in these situations.
that they will return `null` regardless of anything in these situations. When app handles `__on_close()` event, new tasks cannot
be submitted at this point, but current tasks are not terminated. Apps can use that opportunity to gracefully shutdown their tasks.
Regardless if the app handles `__on_close()` event, or does anything with their tasks in it, all tasks will be terminated exceptionally
within the next 1.5 seconds.
### `task(function, ... args)`, `task_thread(executor, function, ... args)`
@@ -1030,6 +1073,15 @@ This will give you a date:
It is currently `hrs`:`mins` and `secs` seconds on the `date`th of `month`, `year`
### `encode_b64(string)`, `decode_b64(string)`
Encode or decode a string from b64, throwing a `b64_error` exception if it's invalid
### `encode_json(value)`, `decode_json(string)`
Encodes a value as a json string, and decodes a json string as a valid value, throwing a `json_error` exception if it
doesn't parse properly
### `profile_expr(expression)`
Returns number of times given expression can be run in 50ms time. Useful to profile and optimize your code.
@@ -1247,6 +1299,7 @@ it will be used from now on as a new value for the accumulator.
reduce([1,2,3,4],_a+_,0) => 10
reduce([1,2,3,4],_a*_,1) => 24
</pre>
# User-defined functions and program control flow
## Writing programs with more than 1 line
@@ -1516,6 +1569,7 @@ but like everywhere else, doing that sounds like a bad idea.
- `io_exception`: This is the parent for any exception that occurs due to an error handling external data.
- `nbt_error`: Incorrect input/output NBT file.
- `json_error`: Incorrect input/output JSON data.
- `b64_error`: Incorrect input/output b64 (base 64) string
- `user_exception`: Exception thrown by default with `throw` function.
Synopsis:
@@ -3448,6 +3502,10 @@ Numbers related to player's xp. `xp` is the overall xp player has, `xp_level` is
Number indicating remaining entity health, or `null` if not applicable.
### `query(e, 'language')`
Returns `null` for any non-player entity, if not returns the player's language as a string.
### `query(e, 'holds', slot?)`
Returns triple of short name, stack count, and NBT of item held in `slot`, or `null` if nothing or not applicable. Available options for `slot` are:
@@ -4723,7 +4781,8 @@ per shape and last whatever they typically last in the game.
Shapes can be send one by one, using either of the first three invocations, or batched as a list of shape descriptors.
Batching has this benefit that they will be send possibly as one packet, limiting network overhead of
sending many small packets to draw several shapes at once.
sending many small packets to draw several shapes at once. The drawback of sending shapes is batches is that they need to address
the same list of players, i.e. if multiple players from the list target different players, all shapes will be sent to all of them.
Shapes will fail to draw and raise a runtime error if not all its required parameters
are specified and all available shapes have some parameters that are required, so make sure to have them in place:
@@ -4736,8 +4795,8 @@ or simply refresh the shapes periodically in more dynamic applications.
Optional shared shape attributes:
* `color` - integer value indicating the main color of the shape in the form of red, green, blue and alpha components
in the form of `0xRRGGBBAA`, with the default of `-1`, so white opaque, or `0xFFFFFFFF`.
* `player` - name or player entity to send the shape to. If specified, the shapes will appear only for the specified
player, otherwise it will be send to all players in the dimension.
* `player` - name or player entity to send the shape to, or a list of players. If specified, the shapes will appear only for the specified
players (regardless where they are), otherwise it will be send to all players in the current dimension.
* `line` - (Deprecated) line thickness, defaults to 2.0pt. Not supported in 1.17's 3.2 core GL renderer.
* `fill` - color for the faces, defaults to no fill. Use `color` attribute format
* `follow` - entity, or player name. Shape will follow an entity instead of being static.
+13 -1
View File
@@ -1,7 +1,19 @@
# Minecraft specific API and `scarpet` language add-ons and commands
Here is the gist of the Minecraft related functions. Otherwise the CarpetScript could live without Minecraft.
Here is the gist of the Minecraft related functions. Otherwise the scarpet could live without Minecraft.
## Global scarpet options
These options affect directly how scarpet functions and can be triggered via `/carpet` command.
- `commandScript`: disables `/script` command making it impossible to control apps in game. Apps will still load and run
when loaded with the world (i.e. present in the world/scripts folder)
- `scriptsAutoload`: when set to `false` will prevent apps loaded with the world to load automatically. You can still
load them on demand via `/script load` command
- `commandScriptACE`: command permission level that is used to trigger commands from scarpet scripts (regardless who triggeres
the code that calls the command). Defaults to `ops`, could be customized to any level via a numerical value (0, 1, 2, 3 or 4)
- `scriptsOptimization`: when disabled, disables default app compile time optimizations. If your app behaves differently with
and without optimizations, please file a bug report on the bug tracker and disable code optimizations
- `scriptsDebugging`: Puts detailed information about apps loading, performance and runtime in system log.
## App structure
@@ -2,7 +2,7 @@
## Writing programs with more than 1 line
### `Operator ;`
### Operator `;`, `then(...)`
To effectively write programs that have more than one line, a programmer needs way to specify a sequence of commands
that execute one after another. In `scarpet` this can be achieved with `;`. Its an operator, and by separating
@@ -22,7 +22,7 @@ in `scarpet`, and not barely an instruction delimiter, terminating the code with
be valid. Having said that, since many programming languages don't care about the number of op terminators
programmers use, carpet preprocessor will remove all unnecessary semicolons from scripts when compiled.
In general `expr; expr; expr; expr` is equivalent to `(((expr ; expr) ; expr) ; expr)`.
In general `expr; expr; expr; expr` is equivalent to `(((expr ; expr) ; expr) ; expr)` or `then(expr, expr, expr, expr)`.
Result of the evaluated expression is the same as the result of the second expression, but first expression
is also evaluated for side-effects
@@ -132,15 +132,16 @@ foo(... x) -> ... # all arguments for foo are included in the list
</pre>
### `import(module_name, symbols ...)`
### `import(module_name, ? symbols ...)`
Imports symbols from other apps and libraries into the current one: global variables or functions, allowing to use
them in the current app. This includes other symbols imported by these modules. Scarpet supports circular dependencies,
but if symbols are used directly in the module body rather than functions, it may not be able to retrieve them.
Returns full list of available symbols that could be imported from this module, which can be used to debug import
issues, and list contents of libraries.
### `call(function, args.....)`
### `call(function, ? args ...)`
calls a user defined function with specified arguments. It is equivalent to calling `function(args...)` directly
except you can use it with function value, or name instead. This means you can pass functions to other user defined
+20 -6
View File
@@ -6,6 +6,12 @@ as `2+(2*2)`, not `(2+2)*2`, otherwise they are applied from left to right, i.e.
as `(2+4)-3`, which in case of numbers doesn't matter, but since `scarpet` allows for mixing all value types
the associativity would matter, and may lead to unintended effects:
Operators can be unary - with one argument prefixed by the operator (like `-`, `!`, `...`), "practically binary" (that
clearly have left and right operands, like assignment `=` operator), and "technically binary" (all binary operators have left and
right hand, but can be frequently chained together, like `1+2+3`). All "technically binary" operators (where chaining makes sense)
have their functional counterparts, e.g. `1+2+3` is equivalent to `sum(1, 2, 3)`. Functional and operatoral forms are directly
equivalent - they actually will result in the same code as scarpet will optimize long operator chains into their optimized functional forms.
Important operator is function definition `->` operator. It will be covered
in [User Defined Functions and Program Control Flow](docs/scarpet/language/FunctionsAndControlFlow.md)
@@ -118,7 +124,7 @@ $);
/script run global_get_enchantment(player(), 'sharpness')
</pre>
### `Basic Arithmetic Operators + - * /`
### Basic Arithmetic Operators `+`, `sum(...)`, `-`, `difference(...)`, `*`, `product(...)`, `/`, `quotient(...)`
Allows to add the results of two expressions. If the operands resolve to numbers, the result is arithmetic operation.
In case of strings, adding or subtracting from a string results in string concatenation and removal of substrings
@@ -134,6 +140,9 @@ Addition with maps (`{}` or `m()`) results in a new map with keys from both maps
adding elements of the right argument to the keys, of left map, or just adding the right value as a new key
in the output map.
Functional forms of `-` and `/` have less intuitive multi-nary interpretation, but they might be useful in some situations.
`x-y-z` resolves to `difference(x, y, z)`.
Examples:
<pre>
@@ -149,7 +158,7 @@ b = [100,63,100]; b+[10,0,10] => [110,63,110]
{'a' -> 1} + {'b' -> 2} => {'a' -> 1, 'b' -> 2}
</pre>
### `Just Operators % ^`
### Just Operators `%`, `^`
The modulo and exponent (power) operators work only if both operands are numbers
@@ -160,11 +169,11 @@ The modulo and exponent (power) operators work only if both operands are numbers
-3 ^ pi => // Error
</pre>
### `Comparison Operators == != < > <= >=`
### Comparison Operators `==`, `equal()`, `!=`, `unique()`, `<`, `increasing()`, `>`, `decreasing()`, `<=`, `nondecreasing()`, `>=`, `nonincreasing()`
Allows to compare the results of two expressions. For numbers it is considers arithmetic order of numbers, for
Allows to compare the results of two expressions. For numbers, it considers arithmetic order of numbers, for
strings - lexicographical, nulls are always 'less' than everything else, and lists check their elements -
if the sizes are different, the size matters, otherwise, pairwise comparisons for each elements are performed.
if the sizes are different, the size matters, otherwise, pairwise comparisons for each element are performed.
The same order rules than with all these operators are used with the default sortographical order as used by `sort`
function. All of these are true:
@@ -180,7 +189,12 @@ null < -1000
3 == 3.0
</pre>
### `Logical Operators && ||`
Functional variants of these operators allow to assert certain paradigms on multiple arguments at once. This means that
due to formal equivalence `x < y < z` is equivalent to `x < y & y < z` because of direct mapping to `increasing(x, y, z)`. This translates through
the parentheses, so `((x < y) < z)` is the same as `increasing(x, y, z)`. To achieve the same effect as you would see in other
languages (not python), you would need to cast the first pair to boolean value, i.e. `bool(x < y) < z`.
### Logical Operators `&&`, `and(...)`, `||`, `or(...)`
These operator compute respective boolean operation on the operands. What it important is that if calculating of the
second operand is not necessary, it won't be evaluated, which means one can use them as conditional statements. In
+13
View File
@@ -3,6 +3,7 @@ acos
acosh
acot
all
and
asin
asinh
atan
@@ -21,8 +22,11 @@ cot
coth
csc
csch
decreasing
deg
delete
difference
equal
exit
fact
filter
@@ -34,6 +38,7 @@ has
hash_code
if
import
increasing
join
keys
l
@@ -48,14 +53,19 @@ mandelbrot
map
max
min
nondecreasing
nonincreasing
not
number
or
outer
pairs
perlin
print
product
profile_expr
put
quotient
rad
rand
range
@@ -75,6 +85,7 @@ sleep
slice
sort
sort_key
sum
synchronize
system_variable_get
system_variable_set
@@ -90,12 +101,14 @@ task_dock
task_join
task_thread
task_value
then
throw
time
title
try
type
undef
unique
upper
values
var
@@ -31,6 +31,7 @@
log log10 log1p
sqrt
max min abs round floor ceil
then sum difference product quotient equal unique increasing decreasing nonincreasing nondecreasing or and
mandelbrot relu
perlin simplex