true and false represent now proper boolean values, not just 0 and 1. All other previous arithmetic holds.
This commit is contained in:
1 parent
8f592735ca
commit
1ae358909b
9 files changed
+137
-74
No files matched your search
@@ -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`.
|
||||
|
||||
<pre>
|
||||
get(l(range(10)), 5) => 5
|
||||
get(l(range(10)), -1) => 9
|
||||
get(l(range(10)), 10) => 0
|
||||
l(range(10)):93 => 3
|
||||
get([range(10)], 5) => 5
|
||||
get([range(10)], -1) => 9
|
||||
get([range(10)], 10) => 0
|
||||
[range(10)]:93 => 3
|
||||
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>
|
||||
|
||||
### `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
|
||||
|
||||
<pre>
|
||||
a = l(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 = l(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 = l(1, 2, 3); put(a, 1, l(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 = m(1,2,3,4); put(a, 5, null); a => {1: null, 2: null, 3: null, 4: null, 5: null}
|
||||
a = [1, 2, 3]; put(a, 1, 4); a => [1, 4, 3]
|
||||
a = [1, 2, 3]; put(a, null, 4); a => [1, 2, 3, 4]
|
||||
a = [1, 2, 3]; put(a, 1, 4, 'insert'); a => [1, 4, 2, 3]
|
||||
a = [1, 2, 3]; put(a, null, [4, 5, 6], 'extend'); a => [1, 2, 3, 4, 5, 6]
|
||||
a = [1, 2, 3]; put(a, 1, [4, 5, 6], 'extend'); a => [1, 4, 5, 6, 2, 3]
|
||||
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 = {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('{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
|
||||
@@ -225,7 +225,7 @@ Primarily to be used in higher order functions
|
||||
|
||||
<pre>
|
||||
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]
|
||||
reduce(range(10),_a+_, 0) => 45
|
||||
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.
|
||||
|
||||
<pre>
|
||||
all([1,2,3], check_prime(_)) => 1
|
||||
all(neighbours(x,y,z), _=='stone') => 1 // 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(_) )
|
||||
all([1,2,3], check_prime(_)) => true
|
||||
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), [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]]
|
||||
// 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),
|
||||
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
|
||||
|
||||
@@ -16,7 +16,7 @@ in [User Defined Functions and Program Control Flow](docs/scarpet/language/Funct
|
||||
1357-5 => 1352
|
||||
1357-'5' => 137
|
||||
3*'foo'-'o' => 'fff'
|
||||
l(1,3,5)+7 => l(8,10,12)
|
||||
[1,3,5]+7 => [8,10,12]
|
||||
</pre>
|
||||
|
||||
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.
|
||||
|
||||
<pre>
|
||||
l(1,2,3) ~ 2 => 1
|
||||
l(1,2,3) ~ 4 => null
|
||||
[1,2,3] ~ 2 => 1
|
||||
[1,2,3] ~ 4 => null
|
||||
|
||||
'foobar' ~ 'baz' => null
|
||||
'foobar' ~ '.b' => 'ob'
|
||||
@@ -103,10 +103,10 @@ Or an example to find if a player has specific enchantment on a held axe (either
|
||||
|
||||
<pre>
|
||||
global_get_enchantment(p, ench) -> (
|
||||
$ for(l('main','offhand'),
|
||||
$ for(['main','offhand'],
|
||||
$ holds = query(p, 'holds', _);
|
||||
$ if( holds,
|
||||
$ l(what, count, nbt) = holds;
|
||||
$ [what, count, nbt] = holds;
|
||||
$ if( what ~ '_axe' && nbt ~ ench,
|
||||
$ lvl = max(lvl, number(nbt ~ '(?<=lvl:)\\d') )
|
||||
$ )
|
||||
@@ -143,8 +143,8 @@ Examples:
|
||||
'foo'*3 => 'foofoofoo'
|
||||
'foofoofoo' / 3 => 'foo'
|
||||
'foofoofoo'-'o' => 'fff'
|
||||
l(1,2,3)+1 => l(2,3,4)
|
||||
b = l(100,63,100); b+l(10,0,10) => l(110,63,110)
|
||||
[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>
|
||||
|
||||
@@ -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 (`&&`).
|
||||
|
||||
<pre>
|
||||
true || false => 1
|
||||
null || false => 0
|
||||
null != false || run('kill gnembon') => 1 // gnembon survives
|
||||
null != false && run('kill gnembon') => 0 // when cheats not allowed
|
||||
null != false && run('kill gnembon') => 1 // gnembon dies, cheats allowed
|
||||
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>
|
||||
|
||||
### `Assignment Operators = <> +=`
|
||||
@@ -204,11 +205,11 @@ require rewriting of the array anyways.
|
||||
|
||||
<pre>
|
||||
a = 5 => a == 5
|
||||
l(a,b,c) = l(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)
|
||||
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 = l(1,2,3); a += 4 => [1,2,3,4]
|
||||
a = l(1,2,3,4); a = filter(a,_!=2) => [1,3,4]
|
||||
[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>
|
||||
|
||||
### `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`
|
||||
|
||||
<pre>
|
||||
!true => 0
|
||||
!false => 1
|
||||
!null => 1
|
||||
!5 => 0
|
||||
!l() => 1
|
||||
!l(null) => 0
|
||||
!true => false
|
||||
!false => true
|
||||
!null => true
|
||||
!5 => false
|
||||
!l() => true
|
||||
!l(null) => false
|
||||
</pre>
|
||||
@@ -14,30 +14,31 @@ as well as minecraft related concepts like `block`, `entity`, `nbt`, `text`.
|
||||
|
||||
### `bool(expr)`
|
||||
|
||||
Returns a boolean context of the expression. Note that there are no true/false values in scarpet. `true` is
|
||||
alias of 1, and `false` is 0\. Bool is also interpreting string values as boolean, which is different from other
|
||||
Returns a boolean context of the expression.
|
||||
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
|
||||
represent binary values
|
||||
represent binary values.
|
||||
|
||||
<pre>
|
||||
bool(pi) => 1
|
||||
bool(false) => 0
|
||||
bool('') => 0
|
||||
bool(l()) => 0
|
||||
bool(l('')) => 1
|
||||
bool('foo') => 1
|
||||
bool('false') => 0
|
||||
bool('nulL') => 0
|
||||
if('false',1,0) => 1
|
||||
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)`
|
||||
|
||||
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>
|
||||
number(null) => null
|
||||
number(null) => 0
|
||||
number(false) => 0
|
||||
number(true) => 1
|
||||
number('') => null
|
||||
number('3.14') => 3.14
|
||||
number(l()) => 0
|
||||
@@ -65,15 +66,15 @@ Supported types (with `"%<?>"` syntax):
|
||||
* `%%`: '%' character
|
||||
|
||||
<pre>
|
||||
str(null) => null
|
||||
str(false) => 0
|
||||
str('') => null
|
||||
str('3.14') => 3.14
|
||||
str(l()) => 0
|
||||
str(l('')) => 1
|
||||
str('foo') => null
|
||||
str('3bar') => null
|
||||
str(2)+str(2) => 22
|
||||
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>
|
||||
@@ -234,7 +235,7 @@ same random object. Scarpet keeps track of up to 1024 custom random number gener
|
||||
|
||||
<pre>
|
||||
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]
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
`scarpet` provides a number of constants that can be used literally in scripts
|
||||
|
||||
* `null`: nothing, zilch, not even false
|
||||
* `true`: pure true, or just 1 (one)
|
||||
* `false`: false truth, or true falsth, 0 (zero) actually
|
||||
* `true`: pure true, can act as `1`
|
||||
* `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
|
||||
* `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;
|
||||
}
|
||||
}
|
||||
Value retval = new NumericValue(v.getBoolean());
|
||||
Value retval = v.getBoolean()?Value.TRUE:Value.FALSE;
|
||||
return (cc, tt) -> retval;
|
||||
});
|
||||
|
||||
@@ -56,7 +56,9 @@ public class Sys {
|
||||
{
|
||||
if (v instanceof NumericValue)
|
||||
{
|
||||
return v;
|
||||
NumericValue num = (NumericValue)v;
|
||||
if (num.isInteger()) return new NumericValue(num.getLong());
|
||||
return new NumericValue(num.getDouble());
|
||||
}
|
||||
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 static final NullValue NULL = new NullValue();
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
@@ -32,7 +33,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
{
|
||||
return new NullValue();
|
||||
}
|
||||
public NullValue() {super(0.0D);}
|
||||
private NullValue() {super(false);}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
|
||||
@@ -15,12 +15,12 @@ import java.util.stream.Collectors;
|
||||
|
||||
public abstract class Value implements Comparable<Value>, Cloneable
|
||||
{
|
||||
public static NumericValue FALSE = new NumericValue(0);
|
||||
public static NumericValue TRUE = new NumericValue(1);
|
||||
public static NumericValue ZERO = FALSE;
|
||||
public static NumericValue ONE = TRUE;
|
||||
public static NumericValue FALSE = BooleanValue.FALSE;
|
||||
public static NumericValue TRUE = BooleanValue.TRUE;
|
||||
public static NumericValue ZERO = new NumericValue(0);
|
||||
public static NumericValue ONE = new NumericValue(1);
|
||||
|
||||
public static NullValue NULL = new NullValue();
|
||||
public static NullValue NULL = NullValue.NULL;
|
||||
|
||||
public String boundVariable;
|
||||
|
||||
|
||||
Reference in new issue
Block a user