|  | @@ -2,17 +2,16 @@ package org.openzen.zenscript.javabytecode.compiler;
 | 
		
	
		
			
			| 2 | 2 |  
 | 
		
	
		
			
			| 3 | 3 |  import org.objectweb.asm.Label;
 | 
		
	
		
			
			| 4 | 4 |  import org.objectweb.asm.Type;
 | 
		
	
		
			
			| 5 |  | -import org.openzen.zenscript.codemodel.definition.ZSPackage;
 | 
		
	
		
			
			| 6 |  | -import org.objectweb.asm.Type;
 | 
		
	
		
			
			|  | 5 | +import org.openzen.zenscript.codemodel.CompareType;
 | 
		
	
		
			
			| 7 | 6 |  import org.openzen.zenscript.codemodel.expression.*;
 | 
		
	
		
			
			| 8 | 7 |  import org.openzen.zenscript.codemodel.member.DefinitionMember;
 | 
		
	
		
			
			| 9 | 8 |  import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
 | 
		
	
		
			
			|  | 9 | +import org.openzen.zenscript.codemodel.type.ITypeID;
 | 
		
	
		
			
			| 10 | 10 |  import org.openzen.zenscript.implementations.IntRange;
 | 
		
	
		
			
			| 11 | 11 |  import org.openzen.zenscript.javabytecode.*;
 | 
		
	
		
			
			| 12 | 12 |  import org.openzen.zenscript.shared.CompileException;
 | 
		
	
		
			
			| 13 | 13 |  import org.openzen.zenscript.shared.CompileExceptionCode;
 | 
		
	
		
			
			| 14 | 14 |  
 | 
		
	
		
			
			| 15 |  | -
 | 
		
	
		
			
			| 16 | 15 |  import java.util.Map;
 | 
		
	
		
			
			| 17 | 16 |  
 | 
		
	
		
			
			| 18 | 17 |  public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
	
		
			
			|  | @@ -29,8 +28,34 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 29 | 28 |          this.isInit = isInit;
 | 
		
	
		
			
			| 30 | 29 |      }
 | 
		
	
		
			
			| 31 | 30 |  
 | 
		
	
		
			
			|  | 31 | +    private static Class<?> getForEquals(ITypeID id) {
 | 
		
	
		
			
			|  | 32 | +        if (CompilerUtils.isPrimitive(id))
 | 
		
	
		
			
			|  | 33 | +            return id.accept(JavaTypeClassVisitor.INSTANCE);
 | 
		
	
		
			
			|  | 34 | +        return Object.class;
 | 
		
	
		
			
			|  | 35 | +    }
 | 
		
	
		
			
			|  | 36 | +
 | 
		
	
		
			
			| 32 | 37 |      @Override
 | 
		
	
		
			
			| 33 | 38 |      public Void visitAndAnd(AndAndExpression expression) {
 | 
		
	
		
			
			|  | 39 | +        Label end = new Label();
 | 
		
	
		
			
			|  | 40 | +        Label onFalse = new Label();
 | 
		
	
		
			
			|  | 41 | +
 | 
		
	
		
			
			|  | 42 | +        expression.left.accept(this);
 | 
		
	
		
			
			|  | 43 | +
 | 
		
	
		
			
			|  | 44 | +        javaWriter.ifEQ(onFalse);
 | 
		
	
		
			
			|  | 45 | +        expression.right.accept(this);
 | 
		
	
		
			
			|  | 46 | +
 | 
		
	
		
			
			|  | 47 | +        // //these two calls are redundant but make decompiled code look better. Keep?
 | 
		
	
		
			
			|  | 48 | +        // javaWriter.ifEQ(onFalse);
 | 
		
	
		
			
			|  | 49 | +        // javaWriter.iConst1();
 | 
		
	
		
			
			|  | 50 | +
 | 
		
	
		
			
			|  | 51 | +        javaWriter.goTo(end);
 | 
		
	
		
			
			|  | 52 | +
 | 
		
	
		
			
			|  | 53 | +        javaWriter.label(onFalse);
 | 
		
	
		
			
			|  | 54 | +        javaWriter.iConst0();
 | 
		
	
		
			
			|  | 55 | +
 | 
		
	
		
			
			|  | 56 | +
 | 
		
	
		
			
			|  | 57 | +        javaWriter.label(end);
 | 
		
	
		
			
			|  | 58 | +
 | 
		
	
		
			
			| 34 | 59 |          return null;
 | 
		
	
		
			
			| 35 | 60 |      }
 | 
		
	
		
			
			| 36 | 61 |  
 | 
		
	
	
		
			
			|  | @@ -50,6 +75,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 50 | 75 |  
 | 
		
	
		
			
			| 51 | 76 |      @Override
 | 
		
	
		
			
			| 52 | 77 |      public Void visitCompare(BasicCompareExpression expression) {
 | 
		
	
		
			
			|  | 78 | +        expression.left.accept(this);
 | 
		
	
		
			
			|  | 79 | +        expression.right.accept(this);
 | 
		
	
		
			
			|  | 80 | +        javaWriter.constant(expression.operator.name());
 | 
		
	
		
			
			|  | 81 | +
 | 
		
	
		
			
			|  | 82 | +        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), String.class);
 | 
		
	
		
			
			|  | 83 | +
 | 
		
	
		
			
			| 53 | 84 |          return null;
 | 
		
	
		
			
			| 54 | 85 |      }
 | 
		
	
		
			
			| 55 | 86 |  
 | 
		
	
	
		
			
			|  | @@ -67,6 +98,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 67 | 98 |  
 | 
		
	
		
			
			| 68 | 99 |      @Override
 | 
		
	
		
			
			| 69 | 100 |      public Void visitCallStatic(CallStaticExpression expression) {
 | 
		
	
		
			
			|  | 101 | +        for (Expression argument : expression.arguments.arguments) {
 | 
		
	
		
			
			|  | 102 | +            argument.accept(this);
 | 
		
	
		
			
			|  | 103 | +        }
 | 
		
	
		
			
			|  | 104 | +        //TODO: Test with actual static method
 | 
		
	
		
			
			|  | 105 | +        final JavaMethodInfo info = expression.member.getTag(JavaMethodInfo.class);
 | 
		
	
		
			
			|  | 106 | +        javaWriter.invokeStatic(info.javaClass.internalClassName, info.name, info.signature);
 | 
		
	
		
			
			| 70 | 107 |          return null;
 | 
		
	
		
			
			| 71 | 108 |      }
 | 
		
	
		
			
			| 72 | 109 |  
 | 
		
	
	
		
			
			|  | @@ -95,34 +132,65 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 95 | 132 |      public Void visitCapturedThis(CapturedThisExpression expression) {
 | 
		
	
		
			
			| 96 | 133 |          return null;
 | 
		
	
		
			
			| 97 | 134 |      }
 | 
		
	
		
			
			| 98 |  | -	
 | 
		
	
		
			
			| 99 |  | -	@Override
 | 
		
	
		
			
			|  | 135 | +
 | 
		
	
		
			
			|  | 136 | +    @Override
 | 
		
	
		
			
			| 100 | 137 |      public Void visitCast(CastExpression expression) {
 | 
		
	
		
			
			| 101 |  | -		expression.target.accept(this);
 | 
		
	
		
			
			|  | 138 | +        expression.target.accept(this);
 | 
		
	
		
			
			| 102 | 139 |          if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
 | 
		
	
		
			
			| 103 | 140 |              throw new IllegalStateException("Call target has no method info!");
 | 
		
	
		
			
			| 104 |  | -		
 | 
		
	
		
			
			|  | 141 | +
 | 
		
	
		
			
			| 105 | 142 |          return null;
 | 
		
	
		
			
			| 106 |  | -	}
 | 
		
	
		
			
			|  | 143 | +    }
 | 
		
	
		
			
			| 107 | 144 |  
 | 
		
	
		
			
			| 108 | 145 |      @Override
 | 
		
	
		
			
			| 109 | 146 |      public Void visitCheckNull(CheckNullExpression expression) {
 | 
		
	
		
			
			|  | 147 | +        final Label end = new Label();
 | 
		
	
		
			
			|  | 148 | +        expression.value.accept(this);
 | 
		
	
		
			
			|  | 149 | +        javaWriter.dup();
 | 
		
	
		
			
			|  | 150 | +        javaWriter.ifNonNull(end);
 | 
		
	
		
			
			|  | 151 | +        javaWriter.pop();
 | 
		
	
		
			
			|  | 152 | +        javaWriter.newObject(NullPointerException.class);
 | 
		
	
		
			
			|  | 153 | +        javaWriter.dup();
 | 
		
	
		
			
			|  | 154 | +        javaWriter.constant("Tried to convert a null value to nonnull type " + expression.type.accept(JavaTypeClassVisitor.INSTANCE).getSimpleName());
 | 
		
	
		
			
			|  | 155 | +        javaWriter.invokeSpecial(NullPointerException.class, "<init>", "(Ljava/lang/String;)V");
 | 
		
	
		
			
			|  | 156 | +        javaWriter.aThrow();
 | 
		
	
		
			
			|  | 157 | +        javaWriter.label(end);
 | 
		
	
		
			
			|  | 158 | +
 | 
		
	
		
			
			| 110 | 159 |          return null;
 | 
		
	
		
			
			| 111 | 160 |      }
 | 
		
	
		
			
			| 112 | 161 |  
 | 
		
	
		
			
			| 113 | 162 |      @Override
 | 
		
	
		
			
			| 114 | 163 |      public Void visitCoalesce(CoalesceExpression expression) {
 | 
		
	
		
			
			|  | 164 | +        final Label end = new Label();
 | 
		
	
		
			
			|  | 165 | +        expression.left.accept(this);
 | 
		
	
		
			
			|  | 166 | +        javaWriter.dup();
 | 
		
	
		
			
			|  | 167 | +        javaWriter.ifNonNull(end);
 | 
		
	
		
			
			|  | 168 | +        javaWriter.pop();
 | 
		
	
		
			
			|  | 169 | +        expression.right.accept(this);
 | 
		
	
		
			
			|  | 170 | +        javaWriter.label(end);
 | 
		
	
		
			
			| 115 | 171 |          return null;
 | 
		
	
		
			
			| 116 | 172 |      }
 | 
		
	
		
			
			| 117 | 173 |  
 | 
		
	
		
			
			| 118 | 174 |      @Override
 | 
		
	
		
			
			| 119 | 175 |      public Void visitConditional(ConditionalExpression expression) {
 | 
		
	
		
			
			|  | 176 | +        final Label end = new Label();
 | 
		
	
		
			
			|  | 177 | +        final Label onElse = new Label();
 | 
		
	
		
			
			|  | 178 | +        expression.condition.accept(this);
 | 
		
	
		
			
			|  | 179 | +        javaWriter.ifEQ(onElse);
 | 
		
	
		
			
			|  | 180 | +        expression.ifThen.accept(this);
 | 
		
	
		
			
			|  | 181 | +        javaWriter.goTo(end);
 | 
		
	
		
			
			|  | 182 | +        javaWriter.label(onElse);
 | 
		
	
		
			
			|  | 183 | +        expression.ifElse.accept(this);
 | 
		
	
		
			
			|  | 184 | +        javaWriter.label(end);
 | 
		
	
		
			
			| 120 | 185 |          return null;
 | 
		
	
		
			
			| 121 | 186 |      }
 | 
		
	
		
			
			| 122 | 187 |  
 | 
		
	
		
			
			| 123 | 188 |      @Override
 | 
		
	
		
			
			| 124 | 189 |      public Void visitConstantBool(ConstantBoolExpression expression) {
 | 
		
	
		
			
			| 125 |  | -        getJavaWriter().constant(expression.value);
 | 
		
	
		
			
			|  | 190 | +        if (expression.value)
 | 
		
	
		
			
			|  | 191 | +            javaWriter.iConst1();
 | 
		
	
		
			
			|  | 192 | +        else
 | 
		
	
		
			
			|  | 193 | +            javaWriter.iConst0();
 | 
		
	
		
			
			| 126 | 194 |          return null;
 | 
		
	
		
			
			| 127 | 195 |      }
 | 
		
	
		
			
			| 128 | 196 |  
 | 
		
	
	
		
			
			|  | @@ -211,16 +279,29 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 211 | 279 |  
 | 
		
	
		
			
			| 212 | 280 |      @Override
 | 
		
	
		
			
			| 213 | 281 |      public Void visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
 | 
		
	
		
			
			|  | 282 | +        javaWriter.loadObject(0);
 | 
		
	
		
			
			|  | 283 | +        for (Expression argument : expression.arguments.arguments) {
 | 
		
	
		
			
			|  | 284 | +            argument.accept(this);
 | 
		
	
		
			
			|  | 285 | +        }
 | 
		
	
		
			
			|  | 286 | +        //No super calls in enums possible, and that's already handled in the enum constructor itself.
 | 
		
	
		
			
			|  | 287 | +        javaWriter.invokeSpecial(expression.objectType.accept(JavaTypeClassVisitor.INSTANCE), "<init>", CompilerUtils.calcDesc(expression.constructor.header, false));
 | 
		
	
		
			
			| 214 | 288 |          return null;
 | 
		
	
		
			
			| 215 | 289 |      }
 | 
		
	
		
			
			| 216 | 290 |  
 | 
		
	
		
			
			| 217 | 291 |      @Override
 | 
		
	
		
			
			| 218 | 292 |      public Void visitEnumConstant(EnumConstantExpression expression) {
 | 
		
	
		
			
			|  | 293 | +        final Type type = expression.type.accept(JavaTypeVisitor.INSTANCE);
 | 
		
	
		
			
			|  | 294 | +        javaWriter.getStaticField(type.getInternalName(), expression.value.name, type.getDescriptor());
 | 
		
	
		
			
			| 219 | 295 |          return null;
 | 
		
	
		
			
			| 220 | 296 |      }
 | 
		
	
		
			
			| 221 | 297 |  
 | 
		
	
		
			
			| 222 | 298 |      @Override
 | 
		
	
		
			
			| 223 | 299 |      public Void visitEquals(EqualsExpression expression) {
 | 
		
	
		
			
			|  | 300 | +        expression.left.accept(this);
 | 
		
	
		
			
			|  | 301 | +        expression.right.accept(this);
 | 
		
	
		
			
			|  | 302 | +        javaWriter.constant(CompareType.EQ.name());
 | 
		
	
		
			
			|  | 303 | +        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), String.class);
 | 
		
	
		
			
			|  | 304 | +
 | 
		
	
		
			
			| 224 | 305 |          return null;
 | 
		
	
		
			
			| 225 | 306 |      }
 | 
		
	
		
			
			| 226 | 307 |  
 | 
		
	
	
		
			
			|  | @@ -231,6 +312,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 231 | 312 |  
 | 
		
	
		
			
			| 232 | 313 |      @Override
 | 
		
	
		
			
			| 233 | 314 |      public Void visitGenericCompare(GenericCompareExpression expression) {
 | 
		
	
		
			
			|  | 315 | +        //TODO: What am I supposed to do here?
 | 
		
	
		
			
			| 234 | 316 |          return null;
 | 
		
	
		
			
			| 235 | 317 |      }
 | 
		
	
		
			
			| 236 | 318 |  
 | 
		
	
	
		
			
			|  | @@ -286,7 +368,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 286 | 368 |  
 | 
		
	
		
			
			| 287 | 369 |      @Override
 | 
		
	
		
			
			| 288 | 370 |      public Void visitMakeConst(MakeConstExpression expression) {
 | 
		
	
		
			
			| 289 |  | -
 | 
		
	
		
			
			|  | 371 | +        //TODO: What am I supposed to do here?
 | 
		
	
		
			
			| 290 | 372 |          return null;
 | 
		
	
		
			
			| 291 | 373 |      }
 | 
		
	
		
			
			| 292 | 374 |  
 | 
		
	
	
		
			
			|  | @@ -308,7 +390,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 308 | 390 |      @Override
 | 
		
	
		
			
			| 309 | 391 |      public Void visitNew(NewExpression expression) {
 | 
		
	
		
			
			| 310 | 392 |          final String type;
 | 
		
	
		
			
			| 311 |  | -        if(expression.type instanceof DefinitionTypeID)
 | 
		
	
		
			
			|  | 393 | +        if (expression.type instanceof DefinitionTypeID)
 | 
		
	
		
			
			| 312 | 394 |              type = ((DefinitionTypeID) expression.type).definition.name;
 | 
		
	
		
			
			| 313 | 395 |          else
 | 
		
	
		
			
			| 314 | 396 |              type = Type.getDescriptor(expression.type.accept(JavaTypeClassVisitor.INSTANCE));
 | 
		
	
	
		
			
			|  | @@ -341,6 +423,26 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 341 | 423 |  
 | 
		
	
		
			
			| 342 | 424 |      @Override
 | 
		
	
		
			
			| 343 | 425 |      public Void visitOrOr(OrOrExpression expression) {
 | 
		
	
		
			
			|  | 426 | +        Label end = new Label();
 | 
		
	
		
			
			|  | 427 | +        Label onTrue = new Label();
 | 
		
	
		
			
			|  | 428 | +
 | 
		
	
		
			
			|  | 429 | +        expression.left.accept(this);
 | 
		
	
		
			
			|  | 430 | +
 | 
		
	
		
			
			|  | 431 | +        javaWriter.ifNE(onTrue);
 | 
		
	
		
			
			|  | 432 | +        expression.right.accept(this);
 | 
		
	
		
			
			|  | 433 | +
 | 
		
	
		
			
			|  | 434 | +        // //these two calls are redundant but make decompiled code look better. Keep?
 | 
		
	
		
			
			|  | 435 | +        // javaWriter.ifNE(onTrue);
 | 
		
	
		
			
			|  | 436 | +        // javaWriter.iConst0();
 | 
		
	
		
			
			|  | 437 | +
 | 
		
	
		
			
			|  | 438 | +        javaWriter.goTo(end);
 | 
		
	
		
			
			|  | 439 | +
 | 
		
	
		
			
			|  | 440 | +        javaWriter.label(onTrue);
 | 
		
	
		
			
			|  | 441 | +        javaWriter.iConst1();
 | 
		
	
		
			
			|  | 442 | +
 | 
		
	
		
			
			|  | 443 | +
 | 
		
	
		
			
			|  | 444 | +        javaWriter.label(end);
 | 
		
	
		
			
			|  | 445 | +
 | 
		
	
		
			
			| 344 | 446 |          return null;
 | 
		
	
		
			
			| 345 | 447 |      }
 | 
		
	
		
			
			| 346 | 448 |  
 | 
		
	
	
		
			
			|  | @@ -371,6 +473,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 371 | 473 |  
 | 
		
	
		
			
			| 372 | 474 |      @Override
 | 
		
	
		
			
			| 373 | 475 |      public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
 | 
		
	
		
			
			|  | 476 | +        //TODO is static?
 | 
		
	
		
			
			|  | 477 | +        final boolean isStatic = false;
 | 
		
	
		
			
			|  | 478 | +        expression.value.accept(this);
 | 
		
	
		
			
			|  | 479 | +        javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), isStatic ? expression.parameter.index : expression.parameter.index + 1);
 | 
		
	
		
			
			| 374 | 480 |          return null;
 | 
		
	
		
			
			| 375 | 481 |      }
 | 
		
	
		
			
			| 376 | 482 |  
 | 
		
	
	
		
			
			|  | @@ -422,6 +528,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
 | 
		
	
		
			
			| 422 | 528 |  
 | 
		
	
		
			
			| 423 | 529 |      @Override
 | 
		
	
		
			
			| 424 | 530 |      public Void visitWrapOptional(WrapOptionalExpression expression) {
 | 
		
	
		
			
			|  | 531 | +        //TODO What am I supposed to do here?
 | 
		
	
		
			
			|  | 532 | +        expression.value.accept(this);
 | 
		
	
		
			
			| 425 | 533 |          return null;
 | 
		
	
		
			
			| 426 | 534 |      }
 | 
		
	
		
			
			| 427 | 535 |  
 |