package io.collap.bryg.compiler.ast.expression.unary;

import io.collap.bryg.compiler.ast.expression.Expression;
import io.collap.bryg.compiler.context.Context;
import io.collap.bryg.compiler.type.Type;
import io.collap.bryg.compiler.type.TypeInterpreter;
import io.collap.bryg.compiler.util.CoercionUtil;
import io.collap.bryg.exception.BrygJitException;
import io.collap.bryg.parser.BrygParser;

import static bryg.org.objectweb.asm.Opcodes.NOP;

public class CastExpression extends Expression {

    private Expression child;
    private int conversionOpcode;

    public CastExpression (Context context, BrygParser.CastExpressionContext ctx) {
        this (
                context,
                new TypeInterpreter (context.getEnvironment ().getClassResolver ()).interpretType (ctx.type ()),
                (Expression) context.getParseTreeVisitor ().visit (ctx.expression ()),
                ctx.getStart ().getLine ()
        );
    }

    public CastExpression (Context context, Type targetType, Expression child, int line) {
        super (context);
        this.child = child;
        setType (targetType);
        setLine (line);

        Type from = child.getType ();
        Type to = type;
        if (from.getJavaType ().isPrimitive () && to.getJavaType ().isPrimitive ()) {
            conversionOpcode = CoercionUtil.getConversionOpcode (from, to, getLine ());
        }else {
            throw new BrygJitException ("Only casts between primitive types are currently supported", getLine ());
        }
    }

    public CastExpression (Context context, Type targetType, Expression child, int conversionOpcode, int line) {
        super (context);
        this.child = child;
        this.conversionOpcode = conversionOpcode;
        setType (targetType);
        setLine (line);
    }

    @Override
    public void compile () {
        child.compile ();
        // -> from

        if (conversionOpcode != NOP) {
            context.getMethodVisitor ().visitInsn (conversionOpcode);
            // from -> to
        }
    }

}

@@ -102,24 +102,83 @@
 Expression;%0A
+import io.collap.bryg.compiler.bytecode.BrygMethodVisitor;%0A
 import io.co
@@ -362,58 +362,8 @@
 il;%0A
-import io.collap.bryg.exception.BrygJitException;%0A
 impo
@@ -445,19 +445,17 @@
 Opcodes.
-NOP
+*
 ;%0A%0Apubli
@@ -525,24 +525,61 @@
 sion child;%0A
+    private boolean isPrimitiveCast;%0A
     private 
@@ -1433,129 +1433,87 @@
     
-%7Delse %7B%0A            throw new BrygJitException (%22Only casts between primitive types are currently supported%22, getLine ())
+    isPrimitiveCast = true;%0A        %7Delse %7B%0A            isPrimitiveCast = false
 ;%0A  
@@ -1743,16 +1743,48 @@
 Opcode;%0A
+        isPrimitiveCast = true;%0A
         
@@ -1875,24 +1875,85 @@
 ompile () %7B%0A
+        BrygMethodVisitor mv = context.getMethodVisitor ();%0A%0A
         chil
@@ -1986,16 +1986,51 @@
 %3E from%0A%0A
+        if (isPrimitiveCast) %7B%0A    
         
@@ -2076,35 +2076,14 @@
     
-context.getMethodVisitor ()
+    mv
 .vis
@@ -2105,24 +2105,184 @@
 ionOpcode);%0A
+                // from -%3E to%0A            %7D%0A        %7Delse %7B /* Object cast. */%0A            mv.visitTypeInsn (CHECKCAST, type.getAsmType ().getInternalName ());%0A
             

Allow CastExpression to cast objects as well.