// Path: src/main/java/com/amanvishnani/sim8085/domain/IAddress.java
// public interface IAddress {
//     String hexValue();
//     Integer intValue();
//     IData getLSB();
//     IData getMSB();
//     IData getData();
//     void setData(IData data);
//     static IAddress ZERO = Address.from(0);
//     static IAddress FFFF = Address.from("FFFF");
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IData.java
// public interface IData {
//     IData ZERO = Data.from("00");
//     String hexValue();
//     Integer intValue();
//     IOperationResult add(IData data);
//     IOperationResult add(IData data, Integer carry);
//     IOperationResult minus(IData data);
//     IRegister toRegister();
//     public IData getLSB();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IOpcode.java
// public interface IOpcode {
//     String getInstruction();
//     IData getOpcodeData();
//     Integer getOpcodeLength();
// }


import com.amanvishnani.sim8085.domain.IAddress;
import com.amanvishnani.sim8085.domain.IData;
import com.amanvishnani.sim8085.domain.IOpcode;
import java.util.*;
package com.amanvishnani.sim8085.domain.Impl;



public class Compiler {

    private final Parser parser;
    Map<Integer, InstructionRow> instructionRowMap;
    Map<String, Integer> labelMap;

    public Compiler(Parser parser) {
        this.parser = parser;
        this.resetParams();
    }

    public Compiler() {
        this(new Parser());
    }

    public ArrayList<InstructionRow> compile(String code) {
        this.resetParams();
        List<String> instructions = parser.getLineInstructions(code);
        this.passOne(instructions);
        this.passTwo();
        ArrayList<InstructionRow> rows = new ArrayList<>(instructionRowMap.values());
        rows.sort(new InstructionSortByAddress());
        return rows;
    }

    private void resetParams() {
        instructionRowMap = new HashMap<>();
        labelMap = new HashMap<>();
    }

    private void passOne(List<String> instructions) {
        int localPointer = 0;
        for (String lineInstruction :
                instructions) {

            // Get Opcode
// Path: src/main/java/com/amanvishnani/sim8085/domain/IAddress.java
// public interface IAddress {
//     String hexValue();
//     Integer intValue();
//     IData getLSB();
//     IData getMSB();
//     IData getData();
//     void setData(IData data);
//     static IAddress ZERO = Address.from(0);
//     static IAddress FFFF = Address.from("FFFF");
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IData.java
// public interface IData {
//     IData ZERO = Data.from("00");
//     String hexValue();
//     Integer intValue();
//     IOperationResult add(IData data);
//     IOperationResult add(IData data, Integer carry);
//     IOperationResult minus(IData data);
//     IRegister toRegister();
//     public IData getLSB();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IOpcode.java
// public interface IOpcode {
//     String getInstruction();
//     IData getOpcodeData();
//     Integer getOpcodeLength();
// }


// Path: src/main/java/com/amanvishnani/sim8085/domain/Impl/Compiler.java
import com.amanvishnani.sim8085.domain.IAddress;
import com.amanvishnani.sim8085.domain.IData;
import com.amanvishnani.sim8085.domain.IOpcode;
import java.util.*;

package com.amanvishnani.sim8085.domain.Impl;



public class Compiler {

    private final Parser parser;
    Map<Integer, InstructionRow> instructionRowMap;
    Map<String, Integer> labelMap;

    public Compiler(Parser parser) {
        this.parser = parser;
        this.resetParams();
    }

    public Compiler() {
        this(new Parser());
    }

    public ArrayList<InstructionRow> compile(String code) {
        this.resetParams();
        List<String> instructions = parser.getLineInstructions(code);
        this.passOne(instructions);
        this.passTwo();
        ArrayList<InstructionRow> rows = new ArrayList<>(instructionRowMap.values());
        rows.sort(new InstructionSortByAddress());
        return rows;
    }

    private void resetParams() {
        instructionRowMap = new HashMap<>();
        labelMap = new HashMap<>();
    }

    private void passOne(List<String> instructions) {
        int localPointer = 0;
        for (String lineInstruction :
                instructions) {

            // Get Opcode
            IOpcode opcode = parser.getOpcode(lineInstruction);