added {} and [] notations, added new function of -> operator and retired element()

This commit is contained in:
gnembon committed 2020-06-28 23:04:14 -03:00
1 parent 391c7b976e
commit b9daf50236
5 files changed
+126 -63

No files matched your search

+36 -23
View File
@@ -117,26 +117,31 @@ tag = nbt('{a:[{lvl:[1,2,3]},{lvl:[3,2,1]},{lvl:[4,5,6]}]}'); put(tag, 'a[].lvl[
## List operations
### `l(values ...), l(iterator)`
### `[value, ...?]`,`[iterator]`,`l(value, ...?)`, `l(iterator)`
Creates a list of values of the expressions passed as parameters. It can be used as an L-value and if all
elements are variables, you coujld use it to return multiple results from one function call, if that
function returns a list of results with the same size as the `l` call uses. In case there is only one
function returns a list of results with the same size as the `[]` call uses. In case there is only one
argument and it is an iterator (vanilla expression specification has `range`, but Minecraft API implements
a bunch of them, like `diamond`), it will convert it to a proper list. Iterators can only be used in high order
functions, and are treated as empty lists, unless unrolled with `l`
functions, and are treated as empty lists, unless unrolled with `[]`.
Internally, `[elem, ...]`(list syntax) and `l(elem, ...)`(function syntax) are equivalent. `[]` is simply translated to
`l()` in the scarpet preprocessing stage. This means that internally the code has always expression syntax despite `[]`
not using different kinds of brackets and not being proper operators. This means that `l(]` and `[)` are also valid
although not recommended as they will make your code far less readable.
<pre>
l(1,2,'foo') => [1, 2, foo]
l() => [] (empty list)
l(range(10)) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l(1, 2) = l(3, 4) => Error: l is not a variable
l(foo, bar) = l(3,4); foo==3 && bar==4 => 1
l(foo, bar, baz) = l(2, 4, 6); l(min(foo, bar), baz) = l(3, 5); l(foo, bar, baz) => [3, 4, 5]
l(1,2,'foo') <=> [1, 2, 'foo']
l() <=> [] (empty list)
[range(10)] => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2] = [3, 4] => Error: l is not a variable
[foo, bar] = [3, 4]; foo==3 && bar==4 => 1
[foo, bar, baz] = [2, 4, 6]; [min(foo, bar), baz] = [3, 5]; [foo, bar, baz] => [3, 4, 5]
</pre>
In the last example `l(min(foo, bar), baz)` creates a valid L-value, as min(foo, bar) finds the lower of the
variables (in this case `foo`) creating a valid assignable L-list of [foo, baz], and these values
In the last example `[min(foo, bar), baz]` creates a valid L-value, as `min(foo, bar)` finds the lower of the
variables (in this case `foo`) creating a valid assignable L-list of `[foo, baz]`, and these values
will be assigned new values
### `join(delim, list), join(delim, values ...)`
@@ -210,29 +215,37 @@ range(5,10) => [5, 6, 7, 8, 9]
range(20, 10, -2) => [20, 18, 16, 14, 12]
</pre>
### `element(list, index)(deprecated)`
Legacy support for older method that worked only on lists. Please use `get(...)` for equivalent support, or `.`
operator. Also previous unique behaviours with `put` on lists has been removed to support all type of
container types.
## Map operations
Scarpet supports map structures, aka hashmaps, dicts etc. Map structure can also be used, with `null` values as sets.
Apart from container access functions, (`. , get, put, has, delete`), the following functions:
### `m(values ...), m(iterator), m(key_value_pairs)`
### `{values, ...}`,`{iterator}`,`{key -> value, ...}`,`m(values, ...)`, `m(iterator)`, `m(l(key, value), ...))`
creates and initializes a map with supplied keys, and values. If the arguments contains a flat list, these are all
treated as keys with no value, same goes with the iterator - creates a map that behaves like a set. If the
arguments is a list of lists, they have to have two elements each, and then first is a key, and second, a value
In map creation context (directly inside `{}` or `m{}` call), `->` operator acts like a pair constructor for simpler
syntax providing key value pairs, so the invocation to `{foo -> bar, baz -> quux}` is equivalent to
`{l(foo, bar), l(baz, quux)}`, which is equivalent to somewhat older, but more traditional functional form of
`m(l(foo, bar),l(baz, quuz))`.
Internally, `{?}`(list syntax) and `m(?)`(function syntax) are equivalent. `{}` is simply translated to
`m()` in the scarpet preprocessing stage. This means that internally the code has always expression syntax despite `{}`
not using different kinds of brackets and not being proper operators. This means that `m(}` and `{)` are also valid
although not recommended as they will make your code far less readable.
When converting map value to string, `':'` is used as a key-value separator due to tentative compatibility with NBT
notation, meaning in simpler cases maps can be converted to NBT parsable string by calling `str()`. This however
does not guarantee a parsable output. To properly convert to NBT value, use `encode_nbt()`.
<pre>
m(1,2,'foo') => {1: null, 2: null, foo: null}
m() => {} (empty map)
m(range(10)) => {0: null, 1: null, 2: null, 3: null, 4: null, 5: null, 6: null, 7: null, 8: null, 9: null}
m(l(1, 2), l(3, 4)) => {1: 2, 3: 4}
reduce(range(10), put(_a, _, _*_); _a, m())
{1, 2, 'foo'} => {1: null, 2: null, foo: null}
m() <=> {} (empty map)
{range(10)} => {0: null, 1: null, 2: null, 3: null, 4: null, 5: null, 6: null, 7: null, 8: null, 9: null}
m(l(1, 2), l(3, 4)) <=> {1 -> 2, 3 -> 4} => {1: 2, 3: 4}
reduce(range(10), put(_a, _, _*_); _a, {})
=> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
</pre>