mirror of
https://github.com/GTNewHorizons/CraftTweaker.git
synced 2026-11-12 00:07:52 +00:00
- Added MFR support for 1.6.4
- Improved API for blocks - NBT compound tags with non-identifier keys should now be output properly
This commit is contained in:
1 parent
e644398505
commit
e2b4f50dfc
97 files changed
+5307
-216
No files matched your search
@@ -52,17 +52,18 @@ public class ExpressionArray extends Expression {
|
||||
|
||||
@Override
|
||||
public void compile(boolean result, IEnvironmentMethod environment) {
|
||||
Type baseType = type.getBaseType().toASMType();
|
||||
ZenType baseType = type.getBaseType();
|
||||
Type asmBaseType = type.getBaseType().toASMType();
|
||||
|
||||
MethodOutput output = environment.getOutput();
|
||||
output.constant(contents.length);
|
||||
output.newArray(baseType);
|
||||
output.newArray(asmBaseType);
|
||||
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
output.dup();
|
||||
output.constant(i);
|
||||
contents[i].compile(result, environment);
|
||||
output.arrayStore(baseType);
|
||||
contents[i].cast(this.getPosition(), environment, baseType).compile(result, environment);
|
||||
output.arrayStore(asmBaseType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ public class ExpressionMapIndexGet extends Expression {
|
||||
internal(Map.class),
|
||||
"get",
|
||||
"(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
environment.getOutput().checkCast(type.toASMType().getInternalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import static stanhebben.zenscript.util.ZenTypeUtil.internal;
|
||||
public class ExpressionTable extends Expression {
|
||||
private final Expression[] keys;
|
||||
private final Expression[] values;
|
||||
private final ZenType type;
|
||||
private final ZenTypeAssociative type;
|
||||
|
||||
public ExpressionTable(ZenPosition position, Expression[] keys, Expression[] values) {
|
||||
super(position);
|
||||
@@ -25,7 +25,7 @@ public class ExpressionTable extends Expression {
|
||||
type = new ZenTypeAssociative(ZenTypeAny.INSTANCE, ZenTypeAny.INSTANCE);
|
||||
}
|
||||
|
||||
public ExpressionTable(ZenPosition position, Expression[] keys, Expression[] values, ZenType type) {
|
||||
public ExpressionTable(ZenPosition position, Expression[] keys, Expression[] values, ZenTypeAssociative type) {
|
||||
super(position);
|
||||
|
||||
this.keys = keys;
|
||||
@@ -42,6 +42,9 @@ public class ExpressionTable extends Expression {
|
||||
@Override
|
||||
public void compile(boolean result, IEnvironmentMethod environment) {
|
||||
if (result) {
|
||||
ZenType keyType = type.getKeyType();
|
||||
ZenType valueType = type.getValueType();
|
||||
|
||||
MethodOutput output = environment.getOutput();
|
||||
output.newObject(HashMap.class);
|
||||
output.dup();
|
||||
@@ -49,8 +52,8 @@ public class ExpressionTable extends Expression {
|
||||
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
output.dup();
|
||||
keys[i].compile(true, environment);
|
||||
values[i].compile(true, environment);
|
||||
keys[i].cast(getPosition(), environment, keyType).compile(true, environment);
|
||||
values[i].cast(getPosition(), environment, valueType).compile(true, environment);
|
||||
output.invokeInterface(internal(Map.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
output.pop();
|
||||
}
|
||||
@@ -76,7 +79,7 @@ public class ExpressionTable extends Expression {
|
||||
newValues[i] = values[i].cast(position, environment, keyType.getValueType());
|
||||
}
|
||||
|
||||
return new ExpressionTable(getPosition(), newKeys, newValues, type);
|
||||
return new ExpressionTable(getPosition(), newKeys, newValues, keyType);
|
||||
} else if (this.type.canCastImplicit(type, environment)) {
|
||||
return this.type.cast(position, environment, this, type);
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,7 @@ package stanhebben.zenscript.type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Type;
|
||||
import stanhebben.zenscript.annotations.CompareType;
|
||||
import stanhebben.zenscript.annotations.OperatorType;
|
||||
@@ -78,62 +79,152 @@ public class ZenTypeAny extends ZenType {
|
||||
CASTERS.put("string", new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asString", String.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Boolean.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asBool", boolean.class);
|
||||
output.invokeStatic(Boolean.class, "valueOf", Boolean.class, boolean.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Byte.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asByte", boolean.class);
|
||||
output.invokeStatic(Byte.class, "valueOf", Byte.class, byte.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Short.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asShort", short.class);
|
||||
output.invokeStatic(Short.class, "valueOf", Short.class, short.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Integer.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asInt", int.class);
|
||||
output.invokeStatic(Integer.class, "valueOf", Integer.class, int.class);
|
||||
}
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Long.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asLong", long.class);
|
||||
output.invokeStatic(Long.class, "valueOf", Long.class, long.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Float.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asFloat", float.class);
|
||||
output.invokeStatic(Float.class, "valueOf", Float.class, float.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(Double.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asDouble", double.class);
|
||||
output.invokeStatic(Double.class, "valueOf", Double.class, double.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
CASTERS.put(String.class.getName(), new MethodCompiler() {
|
||||
@Override
|
||||
public void compile(MethodOutput output) {
|
||||
Label lblNull = new Label();
|
||||
Label lblAfter = new Label();
|
||||
output.dup();
|
||||
output.ifNull(lblNull);
|
||||
output.invokeInterface(IAny.class, "asString", String.class);
|
||||
output.goTo(lblAfter);
|
||||
|
||||
output.label(lblNull);
|
||||
output.pop();
|
||||
output.aConstNull();
|
||||
output.label(lblAfter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ public class ZenTypeArrayBasic extends ZenTypeArray {
|
||||
methodOutput.dup();
|
||||
methodOutput.arrayLength();
|
||||
methodOutput.loadInt(index);
|
||||
methodOutput.ifICmpGE(exit);
|
||||
methodOutput.ifICmpLE(exit);
|
||||
|
||||
methodOutput.dup();
|
||||
methodOutput.loadInt(index);
|
||||
@@ -229,7 +229,7 @@ public class ZenTypeArrayBasic extends ZenTypeArray {
|
||||
methodOutput.dup();
|
||||
methodOutput.arrayLength();
|
||||
methodOutput.loadInt(locals[0]);
|
||||
methodOutput.ifICmpGE(exit);
|
||||
methodOutput.ifICmpLE(exit);
|
||||
|
||||
methodOutput.dup();
|
||||
methodOutput.loadInt(locals[0]);
|
||||
@@ -251,7 +251,7 @@ public class ZenTypeArrayBasic extends ZenTypeArray {
|
||||
|
||||
@Override
|
||||
public ZenType getType(int i) {
|
||||
return getBaseType();
|
||||
return i == 0 ? INT : getBaseType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class ZenTypeAssociative extends ZenType {
|
||||
public IPartialExpression getMember(ZenPosition position, IEnvironmentGlobal environment, IPartialExpression value, String name) {
|
||||
if (name.equals("length")) {
|
||||
return new ExpressionMapSize(position, value.eval(environment));
|
||||
} else if (ZenTypeString.INSTANCE.canCastImplicit(key, environment)) {
|
||||
} else if (STRING.canCastImplicit(key, environment)) {
|
||||
return new ExpressionMapIndexGet(
|
||||
position,
|
||||
value.eval(environment),
|
||||
|
||||
@@ -88,6 +88,14 @@ public class ZenTypeBool extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
if (right.getType().canCastImplicit(BOOL, environment)) {
|
||||
switch (operator) {
|
||||
case AND:
|
||||
@@ -510,6 +518,27 @@ public class ZenTypeBool extends ZenType {
|
||||
public void defineIteratorMulti(MethodOutput output) {
|
||||
throwUnsupportedException(output, "bool", "iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblEqual = new Label();
|
||||
output.loadObject(0);
|
||||
output.loadObject(1);
|
||||
|
||||
output.ifACmpEq(lblEqual);
|
||||
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblEqual);
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
output.invokeSpecial("java/lang/Object", "hashCode", "()I");
|
||||
}
|
||||
|
||||
private void getValue(MethodOutput output) {
|
||||
output.loadObject(0);
|
||||
|
||||
@@ -159,6 +159,14 @@ public class ZenTypeByte extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -567,6 +575,33 @@ public class ZenTypeByte extends ZenType {
|
||||
public void defineIteratorMulti(MethodOutput output) {
|
||||
throwUnsupportedException(output, "byte", "iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASBYTE);
|
||||
output.ifICmpNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
private void getValue(MethodOutput output) {
|
||||
output.loadObject(0);
|
||||
|
||||
@@ -167,6 +167,14 @@ public class ZenTypeDouble extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -562,5 +570,46 @@ public class ZenTypeDouble extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "D");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASDOUBLE);
|
||||
output.dCmp();
|
||||
output.ifNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
// long bits = Double.doubleToLongBits(value);
|
||||
// return (int) (bits ^ bits >> 32)
|
||||
int bits = output.local(Type.LONG_TYPE);
|
||||
output.invokeStatic(Double.class, "doubleToLongBits", double.class, long.class);
|
||||
output.store(Type.LONG_TYPE, bits);
|
||||
|
||||
output.load(Type.LONG_TYPE, bits);
|
||||
output.l2i();
|
||||
output.load(Type.LONG_TYPE, bits);
|
||||
output.constant(32);
|
||||
output.lShr();
|
||||
output.l2i();
|
||||
output.iXor();
|
||||
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,14 @@ public class ZenTypeFloat extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -557,5 +565,35 @@ public class ZenTypeFloat extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "F");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASFLOAT);
|
||||
output.fCmp();
|
||||
output.ifICmpNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
//return Float.floatToIntBits(value);
|
||||
getValue(output);
|
||||
output.invokeStatic(Float.class, "floatToIntBits", float.class, int.class);
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,6 +158,14 @@ public class ZenTypeInt extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -578,5 +586,32 @@ public class ZenTypeInt extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "I");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASINT);
|
||||
output.ifICmpNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,14 @@ public class ZenTypeLong extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -590,5 +598,39 @@ public class ZenTypeLong extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "J");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASLONG);
|
||||
output.lCmp();
|
||||
output.ifICmpNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.l2i();
|
||||
getValue(output);
|
||||
output.constant(32);
|
||||
output.lShr();
|
||||
output.l2i();
|
||||
output.iXor();
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,6 +164,14 @@ public class ZenTypeShort extends ZenType {
|
||||
|
||||
@Override
|
||||
public Expression binary(ZenPosition position, IEnvironmentGlobal environment, Expression left, Expression right, OperatorType operator) {
|
||||
if (operator == OperatorType.CAT) {
|
||||
return STRING.binary(
|
||||
position,
|
||||
environment,
|
||||
left.cast(position, environment, STRING),
|
||||
right.cast(position, environment, STRING), OperatorType.CAT);
|
||||
}
|
||||
|
||||
return new ExpressionArithmeticBinary(position, operator, left, right.cast(position, environment, this));
|
||||
}
|
||||
|
||||
@@ -583,5 +591,32 @@ public class ZenTypeShort extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "S");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
Label lblNope = new Label();
|
||||
|
||||
output.loadObject(1);
|
||||
output.instanceOf(IAny.NAME);
|
||||
output.ifEQ(lblNope);
|
||||
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASSHORT);
|
||||
output.ifICmpNE(lblNope);
|
||||
|
||||
output.iConst1();
|
||||
output.returnInt();
|
||||
|
||||
output.label(lblNope);
|
||||
output.iConst0();
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,12 +51,12 @@ public class ZenTypeString extends ZenType {
|
||||
|
||||
@Override
|
||||
public boolean canCastImplicit(ZenType type, IEnvironmentGlobal environment) {
|
||||
return type == this || canCastExpansion(environment, type);
|
||||
return type == this || type == ANY || canCastExpansion(environment, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCastExplicit(ZenType type, IEnvironmentGlobal environment) {
|
||||
return type == this || type == BOOL || type.getNumberType() > 0 || canCastExpansion(environment, type);
|
||||
return type == this || type == ANY || type == BOOL || type.getNumberType() > 0 || canCastExpansion(environment, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,6 +149,8 @@ public class ZenTypeString extends ZenType {
|
||||
output.invokeStatic(Double.class, "parseDouble", double.class, String.class);
|
||||
} else if (type == ZenTypeDoubleObject.INSTANCE) {
|
||||
output.invokeStatic(Double.class, "valueOf", Double.class, String.class);
|
||||
} else if (type == ANY) {
|
||||
output.invokeStatic(getAnyClassName(environment), "valueOf", "(Ljava/lang/String;)" + signature(IAny.class));
|
||||
} else if (!compileCastExpansion(position, environment, type)) {
|
||||
environment.error(position, "cannot cast " + this + " to " + type);
|
||||
}
|
||||
@@ -557,5 +559,21 @@ public class ZenTypeString extends ZenType {
|
||||
output.loadObject(0);
|
||||
output.getField(ANY_NAME, "value", "Ljava/lang/String;");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineEquals(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.loadObject(1);
|
||||
output.invoke(METHOD_ASSTRING);
|
||||
output.invokeVirtual(String.class, "equals", boolean.class, Object.class);
|
||||
output.returnInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defineHashCode(MethodOutput output) {
|
||||
getValue(output);
|
||||
output.invokeVirtual(String.class, "hashCode", int.class);
|
||||
output.returnInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class IteratorIterable implements IZenIterator {
|
||||
|
||||
methodOutput.loadObject(iterator);
|
||||
methodOutput.invokeInterface(Iterator.class, "next", Object.class);
|
||||
methodOutput.checkCast(iteratorType.getSignature());
|
||||
methodOutput.checkCast(iteratorType.toASMType().getInternalName());
|
||||
methodOutput.store(iteratorType.toASMType(), locals[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,13 +41,14 @@ public class IteratorMap implements IZenIterator {
|
||||
|
||||
@Override
|
||||
public void compilePreIterate(int[] locals, Label exit) {
|
||||
methodOutput.dup();
|
||||
methodOutput.loadObject(iterator);
|
||||
methodOutput.invokeInterface(
|
||||
Iterator.class,
|
||||
"hasNext",
|
||||
boolean.class);
|
||||
methodOutput.ifEQ(exit);
|
||||
|
||||
methodOutput.loadObject(iterator);
|
||||
methodOutput.invokeInterface(Iterator.class, "next", Object.class);
|
||||
methodOutput.dup();
|
||||
|
||||
@@ -65,7 +66,7 @@ public class IteratorMap implements IZenIterator {
|
||||
|
||||
@Override
|
||||
public void compileEnd() {
|
||||
methodOutput.pop();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,7 @@ public class IteratorMapKeys implements IZenIterator {
|
||||
|
||||
@Override
|
||||
public void compileStart(int[] locals) {
|
||||
methodOutput.invokeInterface(Map.class, "entrySet", Set.class);
|
||||
methodOutput.invokeInterface(Map.class, "keySet", Set.class);
|
||||
|
||||
iterator = methodOutput.local(Type.getType(Iterator.class));
|
||||
methodOutput.invokeInterface(Set.class, "iterator", Iterator.class);
|
||||
@@ -41,16 +41,15 @@ public class IteratorMapKeys implements IZenIterator {
|
||||
|
||||
@Override
|
||||
public void compilePreIterate(int[] locals, Label exit) {
|
||||
methodOutput.dup();
|
||||
methodOutput.loadObject(iterator);
|
||||
methodOutput.invokeInterface(
|
||||
Iterator.class,
|
||||
"hasNext",
|
||||
boolean.class);
|
||||
methodOutput.ifEQ(exit);
|
||||
|
||||
|
||||
methodOutput.loadObject(iterator);
|
||||
methodOutput.invokeInterface(Iterator.class, "next", Object.class);
|
||||
|
||||
methodOutput.invokeInterface(Map.Entry.class, "getKey", Object.class);
|
||||
methodOutput.store(type.getKeyType().toASMType(), locals[0]);
|
||||
}
|
||||
|
||||
@@ -61,7 +60,7 @@ public class IteratorMapKeys implements IZenIterator {
|
||||
|
||||
@Override
|
||||
public void compileEnd() {
|
||||
methodOutput.pop();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -382,6 +382,28 @@ public class AnyClassWriter {
|
||||
definition.defineIteratorMulti(outputIteratorMulti);
|
||||
outputIteratorMulti.end();
|
||||
|
||||
MethodOutput outputHashCode = new MethodOutput(
|
||||
writer,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
"hashCode",
|
||||
"()I",
|
||||
null,
|
||||
null);
|
||||
outputHashCode.start();
|
||||
definition.defineHashCode(outputHashCode);
|
||||
outputHashCode.end();
|
||||
|
||||
MethodOutput outputEquals = new MethodOutput(
|
||||
writer,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
"equals",
|
||||
"(Ljava/lang/Object;)Z",
|
||||
null,
|
||||
null);
|
||||
outputEquals.start();
|
||||
definition.defineEquals(outputEquals);
|
||||
outputEquals.end();
|
||||
|
||||
writer.visitEnd();
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
@@ -84,4 +84,8 @@ public interface IAnyDefinition {
|
||||
public void defineIteratorSingle(MethodOutput output);
|
||||
|
||||
public void defineIteratorMulti(MethodOutput output);
|
||||
|
||||
public void defineEquals(MethodOutput output);
|
||||
|
||||
public void defineHashCode(MethodOutput output);
|
||||
}
|
||||
@@ -183,7 +183,7 @@ public class MethodOutput {
|
||||
}
|
||||
|
||||
public void checkCast(String newClass) {
|
||||
visitor.visitTypeInsn(CHECKCAST, newClass.substring(1, newClass.length() - 1));
|
||||
visitor.visitTypeInsn(CHECKCAST, newClass);
|
||||
}
|
||||
|
||||
public void iNeg() {
|
||||
@@ -227,6 +227,14 @@ public class MethodOutput {
|
||||
visitor.visitInsn(IXOR);
|
||||
}
|
||||
|
||||
public void iShr() {
|
||||
visitor.visitInsn(ISHR);
|
||||
}
|
||||
|
||||
public void iShl() {
|
||||
visitor.visitInsn(ISHL);
|
||||
}
|
||||
|
||||
public void lNeg() {
|
||||
visitor.visitInsn(LNEG);
|
||||
}
|
||||
@@ -268,6 +276,14 @@ public class MethodOutput {
|
||||
lXor();
|
||||
}
|
||||
|
||||
public void lShr() {
|
||||
visitor.visitInsn(LSHR);
|
||||
}
|
||||
|
||||
public void lShl() {
|
||||
visitor.visitInsn(LSHL);
|
||||
}
|
||||
|
||||
public void fNeg() {
|
||||
visitor.visitInsn(FNEG);
|
||||
}
|
||||
@@ -392,6 +408,10 @@ public class MethodOutput {
|
||||
visitor.visitInsn(DCMPL);
|
||||
}
|
||||
|
||||
public void instanceOf(String clsName) {
|
||||
visitor.visitTypeInsn(INSTANCEOF, clsName);
|
||||
}
|
||||
|
||||
public void invokeStatic(String owner, String name, String descriptor) {
|
||||
if (owner == null)
|
||||
throw new IllegalArgumentException("owner cannot be null");
|
||||
|
||||
@@ -39,6 +39,6 @@ public class ZenPosition {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (file == null ? "?" : file.getFileName()) + " - " + Integer.toString(line) + ":" + offset;
|
||||
return (file == null ? "?" : file.getFileName()) + ":" + Integer.toString(line);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import java.util.Iterator;
|
||||
* @author Stan Hebben
|
||||
*/
|
||||
public interface IAny {
|
||||
public static final String NAME = "stanhebben/zenscript/value/IAny";
|
||||
|
||||
public static final int NUM_BYTE = 1;
|
||||
public static final int NUM_SHORT = 2;
|
||||
public static final int NUM_INT = 3;
|
||||
|
||||
Reference in new issue
Block a user