Merge branch 'master' into 1.17

This commit is contained in:
gnembon committed 2021-03-02 23:34:14 -04:00
commit bdc521294f
9 files changed
+137 -74

No files matched your search

+13 -13
View File
@@ -23,12 +23,12 @@ In case to simplify the access with nested objects, you can add chain of address
than calling it multiple times. `get(get(foo,a),b)` is equivalent to `get(foo, a, b)`, or `foo:a:b`. than calling it multiple times. `get(get(foo,a),b)` is equivalent to `get(foo, a, b)`, or `foo:a:b`.
<pre> <pre>
get(l(range(10)), 5) => 5 get([range(10)], 5) => 5
get(l(range(10)), -1) => 9 get([range(10)], -1) => 9
get(l(range(10)), 10) => 0 get([range(10)], 10) => 0
l(range(10)):93 => 3 [range(10)]:93 => 3
get(player() ~ 'nbt', 'Health') => 20 // inefficient way to get player health, use player() ~ 'health' instead get(player() ~ 'nbt', 'Health') => 20 // inefficient way to get player health, use player() ~ 'health' instead
get(m( l('foo',2), l('bar',3), l('baz',4) ), 'bar') => 3 get({ 'foo' -> 2, 'bar' -> 3, 'baz' -> 4 }, 'bar') => 3
</pre> </pre>
### `has(container, address, ...), has(lvalue)` ### `has(container, address, ...), has(lvalue)`
@@ -100,13 +100,13 @@ of the existing elements. Use `replace` to remove and replace existing element.
and merges keys from `value` with the compound tag under the path and merges keys from `value` with the compound tag under the path
<pre> <pre>
a = l(1, 2, 3); put(a, 1, 4); a => [1, 4, 3] a = [1, 2, 3]; put(a, 1, 4); a => [1, 4, 3]
a = l(1, 2, 3); put(a, null, 4); a => [1, 2, 3, 4] a = [1, 2, 3]; put(a, null, 4); a => [1, 2, 3, 4]
a = l(1, 2, 3); put(a, 1, 4, 'insert'); a => [1, 4, 2, 3] a = [1, 2, 3]; put(a, 1, 4, 'insert'); a => [1, 4, 2, 3]
a = l(1, 2, 3); put(a, null, l(4, 5, 6), 'extend'); a => [1, 2, 3, 4, 5, 6] a = [1, 2, 3]; put(a, null, [4, 5, 6], 'extend'); a => [1, 2, 3, 4, 5, 6]
a = l(1, 2, 3); put(a, 1, l(4, 5, 6), 'extend'); a => [1, 4, 5, 6, 2, 3] a = [1, 2, 3]; put(a, 1, [4, 5, 6], 'extend'); a => [1, 4, 5, 6, 2, 3]
a = l(l(0,0,0),l(0,0,0),l(0,0,0)); put(a.1, 1, 1); a => [[0, 0, 0], [0, 1, 0], [0, 0, 0]] a = [[0,0,0],[0,0,0],[0,0,0]]; put(a:1, 1, 1); a => [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
a = m(1,2,3,4); put(a, 5, null); a => {1: null, 2: null, 3: null, 4: null, 5: null} a = {1,2,3,4}; put(a, 5, null); a => {1: null, 2: null, 3: null, 4: null, 5: null}
tag = nbt('{}'); put(tag, 'BlockData.Properties', '[1,2,3,4]'); tag => {BlockData:{Properties:[1,2,3,4]}} tag = nbt('{}'); put(tag, 'BlockData.Properties', '[1,2,3,4]'); tag => {BlockData:{Properties:[1,2,3,4]}}
tag = nbt('{a:[{lvl:3},{lvl:5},{lvl:2}]}'); put(tag, 'a[].lvl', 1); tag => {a:[{lvl:1},{lvl:1},{lvl:1}]} tag = nbt('{a:[{lvl:3},{lvl:5},{lvl:2}]}'); put(tag, 'a[].lvl', 1); tag => {a:[{lvl:1},{lvl:1},{lvl:1}]}
tag = nbt('{a:[{lvl:[1,2,3]},{lvl:[3,2,1]},{lvl:[4,5,6]}]}'); put(tag, 'a[].lvl', 1, 2); tag tag = nbt('{a:[{lvl:[1,2,3]},{lvl:[3,2,1]},{lvl:[4,5,6]}]}'); put(tag, 'a[].lvl', 1, 2); tag
@@ -225,7 +225,7 @@ Primarily to be used in higher order functions
<pre> <pre>
range(10) => [...] range(10) => [...]
l(range(10)) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [range(10)] => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
map(range(10),_*_) => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] map(range(10),_*_) => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce(range(10),_a+_, 0) => 45 reduce(range(10),_a+_, 0) => 45
range(5,10) => [5, 6, 7, 8, 9] range(5,10) => [5, 6, 7, 8, 9]
@@ -124,12 +124,12 @@ to `all(list,expr) <=> for(list,expr)==length(list)`. `expr` also receives bound
and `continue` have no sense and cannot be used inside of `expr` body. and `continue` have no sense and cannot be used inside of `expr` body.
<pre> <pre>
all([1,2,3], check_prime(_)) => 1 all([1,2,3], check_prime(_)) => true
all(neighbours(x,y,z), _=='stone') => 1 // if all neighbours of [x, y, z] are stone all(neighbours(x,y,z), _=='stone') => true // if all neighbours of [x, y, z] are stone
map(filter(rect(0,4,0,1000,0,1000), l(x,y,z)=pos(_); all(rect(x,y,z,1,0,1),_=='bedrock') ), pos(_) ) map(filter(rect(0,4,0,1000,0,1000), [x,y,z]=pos(_); all(rect(x,y,z,1,0,1),_=='bedrock') ), pos(_) )
=> [[-298, 4, -703], [-287, 4, -156], [-269, 4, 104], [242, 4, 250], [-159, 4, 335], [-208, 4, 416], [-510, 4, 546], [376, 4, 806]] => [[-298, 4, -703], [-287, 4, -156], [-269, 4, 104], [242, 4, 250], [-159, 4, 335], [-208, 4, 416], [-510, 4, 546], [376, 4, 806]]
// find all 3x3 bedrock structures in the top bedrock layer // find all 3x3 bedrock structures in the top bedrock layer
map( filter( rect(0,4,0,1000,1,1000,1000,0,1000), l(x,y,z)=pos(_); map( filter( rect(0,4,0,1000,1,1000,1000,0,1000), [x,y,z]=pos(_);
all(rect(x,y,z,1,0,1),_=='bedrock') && for(rect(x,y-1,z,1,1,1,1,0,1),_=='bedrock')<8), all(rect(x,y,z,1,0,1),_=='bedrock') && for(rect(x,y-1,z,1,1,1,1,0,1),_=='bedrock')<8),
pos(_) ) => [[343, 3, -642], [153, 3, -285], [674, 3, 167], [-710, 3, 398]] pos(_) ) => [[343, 3, -642], [153, 3, -285], [674, 3, 167], [-710, 3, 398]]
// ditto, but requiring at most 7 bedrock block in the 18 blocks below them // ditto, but requiring at most 7 bedrock block in the 18 blocks below them
+24 -23
View File
@@ -16,7 +16,7 @@ in [User Defined Functions and Program Control Flow](docs/scarpet/language/Funct
1357-5 => 1352 1357-5 => 1352
1357-'5' => 137 1357-'5' => 137
3*'foo'-'o' => 'fff' 3*'foo'-'o' => 'fff'
l(1,3,5)+7 => l(8,10,12) [1,3,5]+7 => [8,10,12]
</pre> </pre>
As you can see, values can behave differently when mixed with other types in the same expression. As you can see, values can behave differently when mixed with other types in the same expression.
@@ -76,8 +76,8 @@ In Minecraft API portion `entity ~ feature` is a shortcode for `query(entity,fea
any extra arguments. any extra arguments.
<pre> <pre>
l(1,2,3) ~ 2 => 1 [1,2,3] ~ 2 => 1
l(1,2,3) ~ 4 => null [1,2,3] ~ 4 => null
'foobar' ~ 'baz' => null 'foobar' ~ 'baz' => null
'foobar' ~ '.b' => 'ob' 'foobar' ~ '.b' => 'ob'
@@ -103,10 +103,10 @@ Or an example to find if a player has specific enchantment on a held axe (either
<pre> <pre>
global_get_enchantment(p, ench) -> ( global_get_enchantment(p, ench) -> (
$ for(l('main','offhand'), $ for(['main','offhand'],
$ holds = query(p, 'holds', _); $ holds = query(p, 'holds', _);
$ if( holds, $ if( holds,
$ l(what, count, nbt) = holds; $ [what, count, nbt] = holds;
$ if( what ~ '_axe' && nbt ~ ench, $ if( what ~ '_axe' && nbt ~ ench,
$ lvl = max(lvl, number(nbt ~ '(?<=lvl:)\\d') ) $ lvl = max(lvl, number(nbt ~ '(?<=lvl:)\\d') )
$ ) $ )
@@ -143,8 +143,8 @@ Examples:
'foo'*3 => 'foofoofoo' 'foo'*3 => 'foofoofoo'
'foofoofoo' / 3 => 'foo' 'foofoofoo' / 3 => 'foo'
'foofoofoo'-'o' => 'fff' 'foofoofoo'-'o' => 'fff'
l(1,2,3)+1 => l(2,3,4) [1,2,3]+1 => [2,3,4]
b = l(100,63,100); b+l(10,0,10) => l(110,63,110) b = [100,63,100]; b+[10,0,10] => [110,63,110]
{'a' -> 1} + {'b' -> 2} => {'a' -> 1, 'b' -> 2} {'a' -> 1} + {'b' -> 2} => {'a' -> 1, 'b' -> 2}
</pre> </pre>
@@ -186,11 +186,12 @@ second operand is not necessary, it won't be evaluated, which means one can use
case of success returns first positive operand (`||`) or last one (`&&`). case of success returns first positive operand (`||`) or last one (`&&`).
<pre> <pre>
true || false => 1 true || false => true
null || false => 0 null || false => false
null != false || run('kill gnembon') => 1 // gnembon survives false || null => null
null != false && run('kill gnembon') => 0 // when cheats not allowed null != false || run('kill gnembon') // gnembon survives
null != false && run('kill gnembon') => 1 // gnembon dies, cheats allowed null != false && run('kill gnembon') // when cheats not allowed
null != false && run('kill gnembon') // gnembon dies, cheats allowed
</pre> </pre>
### `Assignment Operators = <> +=` ### `Assignment Operators = <> +=`
@@ -204,11 +205,11 @@ require rewriting of the array anyways.
<pre> <pre>
a = 5 => a == 5 a = 5 => a == 5
l(a,b,c) = l(3,4,5) => a==3, b==4, c==5 [a,b,c] = [3,4,5] => a==3, b==4, c==5
l(minx,maxx) = sort(xi,xj); // minx assumes min(xi, xj) and maxx, max(xi, xj) [minx,maxx] = sort(xi,xj); // minx assumes min(xi, xj) and maxx, max(xi, xj)
l(a,b,c,d,e,f) = l(range(6)); l(a,b,c) <> l(d,e,f); l(a,b,c,d,e,f) => [3,4,5,0,1,2] [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 = l(1,2,3); a += 4 => [1,2,3,4] a = [1,2,3]; a += 4 => [1,2,3,4]
a = l(1,2,3,4); a = filter(a,_!=2) => [1,3,4] a = [1,2,3,4]; a = filter(a,_!=2) => [1,3,4]
</pre> </pre>
### `Unary Operators - +` ### `Unary Operators - +`
@@ -226,10 +227,10 @@ Require a number, flips the sign. One way to assert it's a number is by crashing
flips boolean condition of the expression. Equivalent of `bool(expr)==false` flips boolean condition of the expression. Equivalent of `bool(expr)==false`
<pre> <pre>
!true => 0 !true => false
!false => 1 !false => true
!null => 1 !null => true
!5 => 0 !5 => false
!l() => 1 !l() => true
!l(null) => 0 !l(null) => false
</pre> </pre>
+25 -24
View File
@@ -14,30 +14,31 @@ as well as minecraft related concepts like `block`, `entity`, `nbt`, `text`.
### `bool(expr)` ### `bool(expr)`
Returns a boolean context of the expression. Note that there are no true/false values in scarpet. `true` is Returns a boolean context of the expression.
alias of 1, and `false` is 0\. Bool is also interpreting string values as boolean, which is different from other Bool is also interpreting string values as boolean, which is different from other
places where boolean context can be used. This can be used in places where API functions return string values to places where boolean context can be used. This can be used in places where API functions return string values to
represent binary values represent binary values.
<pre> <pre>
bool(pi) => 1 bool(pi) => true
bool(false) => 0 bool(false) => false
bool('') => 0 bool('') => false
bool(l()) => 0 bool(l()) => false
bool(l('')) => 1 bool(l('')) => true
bool('foo') => 1 bool('foo') => true
bool('false') => 0 bool('false') => false
bool('nulL') => 0 bool('nulL') => false
if('false',1,0) => 1 if('false',1,0) => true
</pre> </pre>
### `number(expr)` ### `number(expr)`
Returns a numeric context of the expression. Can be used to read numbers from strings Returns a numeric context of the expression. Can be used to read numbers from strings, or other types
<pre> <pre>
number(null) => null number(null) => 0
number(false) => 0 number(false) => 0
number(true) => 1
number('') => null number('') => null
number('3.14') => 3.14 number('3.14') => 3.14
number(l()) => 0 number(l()) => 0
@@ -65,15 +66,15 @@ Supported types (with `"%<?>"` syntax):
* `%%`: '%' character * `%%`: '%' character
<pre> <pre>
str(null) => null str(null) => 'null'
str(false) => 0 str(false) => 'false'
str('') => null str('') => ''
str('3.14') => 3.14 str('3.14') => '3.14'
str(l()) => 0 str([]) => '[]'
str(l('')) => 1 str(['']) => '[]'
str('foo') => null str('foo') => 'foo'
str('3bar') => null str('3bar') => '3bar'
str(2)+str(2) => 22 str(2)+str(2) => '22'
str('pi: %.2f',pi) => 'pi: 3.14' str('pi: %.2f',pi) => 'pi: 3.14'
str('player at: %d %d %d',pos(player())) => 'player at: 567, -2423, 124' str('player at: %d %d %d',pos(player())) => 'player at: 567, -2423, 124'
</pre> </pre>
@@ -234,7 +235,7 @@ same random object. Scarpet keeps track of up to 1024 custom random number gener
<pre> <pre>
map(range(10), floor(rand(10))) => [5, 8, 0, 6, 9, 3, 9, 9, 1, 8] map(range(10), floor(rand(10))) => [5, 8, 0, 6, 9, 3, 9, 9, 1, 8]
map(range(10), bool(rand(2))) => [1, 1, 1, 0, 0, 1, 1, 0, 0, 0] map(range(10), bool(rand(2))) => [false, false, true, false, false, false, true, false, true, false]
map(range(10), str('%.1f',rand(_))) => [0.0, 0.4, 0.6, 1.9, 2.8, 3.8, 5.3, 2.2, 1.6, 5.6] map(range(10), str('%.1f',rand(_))) => [0.0, 0.4, 0.6, 1.9, 2.8, 3.8, 5.3, 2.2, 1.6, 5.6]
</pre> </pre>
@@ -3,8 +3,8 @@
`scarpet` provides a number of constants that can be used literally in scripts `scarpet` provides a number of constants that can be used literally in scripts
* `null`: nothing, zilch, not even false * `null`: nothing, zilch, not even false
* `true`: pure true, or just 1 (one) * `true`: pure true, can act as `1`
* `false`: false truth, or true falsth, 0 (zero) actually * `false`: false truth, or true falsth, equals to `0`
* `pi`: for the fans of perimeters, its a perimeter of an apple pi of diameter 1\. About 3.14 * `pi`: for the fans of perimeters, its a perimeter of an apple pi of diameter 1\. About 3.14
* `euler`: clever guy. Derivative of its exponent is goto 1\. About 2.72 * `euler`: clever guy. Derivative of its exponent is goto 1\. About 2.72
@@ -48,7 +48,7 @@ public class Sys {
return (cc, tt) -> Value.FALSE; return (cc, tt) -> Value.FALSE;
} }
} }
Value retval = new NumericValue(v.getBoolean()); Value retval = v.getBoolean()?Value.TRUE:Value.FALSE;
return (cc, tt) -> retval; return (cc, tt) -> retval;
}); });
@@ -56,7 +56,9 @@ public class Sys {
{ {
if (v instanceof NumericValue) if (v instanceof NumericValue)
{ {
return v; NumericValue num = (NumericValue)v;
if (num.isInteger()) return new NumericValue(num.getLong());
return new NumericValue(num.getDouble());
} }
try try
{ {
@@ -0,0 +1,58 @@
package carpet.script.value;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import net.minecraft.nbt.ByteTag;
import net.minecraft.nbt.Tag;
public class BooleanValue extends NumericValue
{
public static final BooleanValue FALSE = new BooleanValue(false);
public static final BooleanValue TRUE = new BooleanValue(true);
boolean boolValue;
private BooleanValue(boolean boolval) {
super(boolval);
boolValue = boolval;
}
@Override
public String getString() {
return boolValue?"true":"false";
}
@Override
public String getPrettyString() {
return getString();
}
@Override
public String getTypeString() {
return "bool";
}
@Override
public Value clone() {
return new BooleanValue(boolValue);
}
@Override
public int hashCode() {
return Boolean.hashCode(boolValue);
}
@Override
public Tag toTag(boolean force) {
return ByteTag.of(boolValue);
}
@Override
public JsonElement toJson() {
return new JsonPrimitive(boolValue);
}
@Override
public boolean isInteger() {
return true;
}
}
@@ -9,6 +9,7 @@ import net.minecraft.nbt.Tag;
public class NullValue extends NumericValue // TODO check nonsingleton code public class NullValue extends NumericValue // TODO check nonsingleton code
{ {
public static final NullValue NULL = new NullValue();
@Override @Override
public String getString() public String getString()
{ {
@@ -32,7 +33,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
{ {
return new NullValue(); return new NullValue();
} }
public NullValue() {super(0.0D);} private NullValue() {super(false);}
@Override @Override
public boolean equals(final Object o) public boolean equals(final Object o)
+5 -5
View File
@@ -15,12 +15,12 @@ import java.util.stream.Collectors;
public abstract class Value implements Comparable<Value>, Cloneable public abstract class Value implements Comparable<Value>, Cloneable
{ {
public static NumericValue FALSE = new NumericValue(0); public static NumericValue FALSE = BooleanValue.FALSE;
public static NumericValue TRUE = new NumericValue(1); public static NumericValue TRUE = BooleanValue.TRUE;
public static NumericValue ZERO = FALSE; public static NumericValue ZERO = new NumericValue(0);
public static NumericValue ONE = TRUE; public static NumericValue ONE = new NumericValue(1);
public static NullValue NULL = new NullValue(); public static NullValue NULL = NullValue.NULL;
public String boundVariable; public String boundVariable;