diff --git a/docs/scarpet/language/Containers.md b/docs/scarpet/language/Containers.md index 882f4f7f..66c8ff17 100644 --- a/docs/scarpet/language/Containers.md +++ b/docs/scarpet/language/Containers.md @@ -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`.
-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
### `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
-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
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]
diff --git a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md
index fa3ab931..95d018ed 100644
--- a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md
+++ b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md
@@ -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.
-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
diff --git a/docs/scarpet/language/Operators.md b/docs/scarpet/language/Operators.md
index 262f4cc2..4780124d 100644
--- a/docs/scarpet/language/Operators.md
+++ b/docs/scarpet/language/Operators.md
@@ -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]
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.
-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
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}
@@ -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 (`&&`).
-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
### `Assignment Operators = <> +=`
@@ -204,11 +205,11 @@ require rewriting of the array anyways.
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]
### `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`
-!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
diff --git a/docs/scarpet/language/SystemFunctions.md b/docs/scarpet/language/SystemFunctions.md
index 1f3768e6..bdc17d72 100644
--- a/docs/scarpet/language/SystemFunctions.md
+++ b/docs/scarpet/language/SystemFunctions.md
@@ -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.
-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
### `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
-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
-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'
@@ -234,7 +235,7 @@ same random object. Scarpet keeps track of up to 1024 custom random number gener
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]
diff --git a/docs/scarpet/language/VariablesAndConstants.md b/docs/scarpet/language/VariablesAndConstants.md
index 2afb874d..a7657f4d 100644
--- a/docs/scarpet/language/VariablesAndConstants.md
+++ b/docs/scarpet/language/VariablesAndConstants.md
@@ -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
diff --git a/src/main/java/carpet/script/language/Sys.java b/src/main/java/carpet/script/language/Sys.java
index 2f21cb4e..4655f9d6 100644
--- a/src/main/java/carpet/script/language/Sys.java
+++ b/src/main/java/carpet/script/language/Sys.java
@@ -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
{
diff --git a/src/main/java/carpet/script/value/BooleanValue.java b/src/main/java/carpet/script/value/BooleanValue.java
new file mode 100644
index 00000000..ea67f11b
--- /dev/null
+++ b/src/main/java/carpet/script/value/BooleanValue.java
@@ -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;
+ }
+}
diff --git a/src/main/java/carpet/script/value/NullValue.java b/src/main/java/carpet/script/value/NullValue.java
index 7dcec512..1e5f08a0 100644
--- a/src/main/java/carpet/script/value/NullValue.java
+++ b/src/main/java/carpet/script/value/NullValue.java
@@ -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)
diff --git a/src/main/java/carpet/script/value/Value.java b/src/main/java/carpet/script/value/Value.java
index 5548d83f..573ed02c 100644
--- a/src/main/java/carpet/script/value/Value.java
+++ b/src/main/java/carpet/script/value/Value.java
@@ -15,12 +15,12 @@ import java.util.stream.Collectors;
public abstract class Value implements Comparable, 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;