package com.github.forax.vmboiler;

import java.util.Objects;

import org.objectweb.asm.MethodVisitor;

import static com.github.forax.vmboiler.Type.VM_BOOLEAN;
import static com.github.forax.vmboiler.Type.VM_BYTE;
import static com.github.forax.vmboiler.Type.VM_CHAR;
import static com.github.forax.vmboiler.Type.VM_DOUBLE;
import static com.github.forax.vmboiler.Type.VM_FLOAT;
import static com.github.forax.vmboiler.Type.VM_INT;
import static com.github.forax.vmboiler.Type.VM_LONG;
import static com.github.forax.vmboiler.Type.VM_SHORT;
import static com.github.forax.vmboiler.Type.VM_VOID;
import static org.objectweb.asm.Opcodes.*;

/**
 * Base class that represents either {@link Var a virtual register} or
 * a {@link Constant a side effect free constant}.
 * 
 * Values are used by the {@link CodeGen} operations.
 */
public abstract class Value {
  private final Type type;

  Value(Type type) {
    this.type = Objects.requireNonNull(type);
  }
  
  /**
   * Returns the type of the current value.
   * @return the type of the current value.
   */
  public Type type() {
    return type;
  }
  
  abstract void loadAll(MethodVisitor mv);

  abstract void loadPrimitive(MethodVisitor mv);
  
  static int loadOpcode(String vmType) {
    return LOAD_OPS[vmType.charAt(0) - 'B'];
  }
  static int storeOpcode(String vmType) {
    return STORE_OPS[vmType.charAt(0) - 'B'];
  }
  static int returnOpcode(String vmType) {
    return RETURN_OPS[vmType.charAt(0) - 'B'];
  }
  static int size(String vmType) {
    return (vmType == VM_LONG || vmType == VM_DOUBLE)?2: (vmType == VM_VOID)? 0: 1;
  }
  
  private static final int[] LOAD_OPS =   { ILOAD  , ILOAD  , DLOAD  , 0, FLOAD  , 0, 0, ILOAD  , LLOAD  , 0, ALOAD  , 0, 0, 0, 0, 0, 0, ILOAD  , 0, 0, 0     , 0, 0, 0, ILOAD };
  private static final int[] STORE_OPS =  { ISTORE , ISTORE , DSTORE , 0, FSTORE , 0, 0, ISTORE , LSTORE , 0, ASTORE , 0, 0, 0, 0, 0, 0, ISTORE , 0, 0, 0     , 0, 0, 0, ISTORE };
  private static final int[] RETURN_OPS = { IRETURN, IRETURN, DRETURN, 0, FRETURN, 0, 0, IRETURN, LRETURN, 0, ARETURN, 0, 0, 0, 0, 0, 0, IRETURN, 0, 0, RETURN, 0, 0, 0, IRETURN };
}
@@ -33,76 +33,8 @@
 r;%0A%0A
-import java.util.Objects;%0A%0Aimport org.objectweb.asm.MethodVisitor;%0A%0A
 impo
@@ -81,15 +81,14 @@
 .VM_
-BOOLEAN
+DOUBLE
 ;%0Aim
@@ -137,12 +137,12 @@
 .VM_
-BYTE
+LONG
 ;%0Aim
@@ -191,12 +191,12 @@
 .VM_
-CHAR
+VOID
 ;%0Aim
@@ -211,334 +211,71 @@
 tic 
-com.github.forax.vmboiler.Type.VM_DOUBLE;%0Aimport static com.github.forax.vmboiler.Type.VM_FLOAT;%0Aimport static com.github.forax.vmboiler.Type.VM_INT;%0Aimport static com.github.forax.vmboiler.Type.VM_LONG;%0Aimport static com.github.forax.vmboiler.Type.VM_SHORT;%0Aimport static com.github.forax.vmboiler.Type.VM_VOID;%0Aimport static
+org.objectweb.asm.Opcodes.*;%0A%0Aimport java.util.Objects;%0A%0Aimport
  org
@@ -289,25 +289,29 @@
 web.asm.
-Opcodes.*
+MethodVisitor
 ;%0A%0A/**%0A 

remove unused imports