import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class CSC242Assembler {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		
		if( args.length != 1 )
			System.out.println("Usage Error: java CSC242Assembler *.asm");
		else if( args[0].contentEquals(".asm") )
				System.out.println("Usage Error: java CSC242Assembler *.asm");
			else
			{
				String asmFile = args[0];
				int d = asmFile.indexOf('.');
				String hackFile = asmFile.substring(0,d).concat(".hack");
				System.out.println("asm file ".concat(asmFile));
				System.out.println("hack file ".concat(hackFile));
				int romAddress = 0;
				int ramAddress = 16;
				Parser p = new Parser(asmFile);
				Code c = new Code();
				SymbolTable st = new SymbolTable();
				PrintWriter outFile = new PrintWriter(new FileWriter(hackFile));
				int decimal = 0;
				
				while (p.hasMoreCommands())
				{
					p.advance();
					/*Required for use with Symbols stage 2 of project*/
					 if (p.commandType().equals("L_COMMAND"))
					{	
						String instruction = p.getInstruction();
						String label = instruction.substring(1,instruction.length() - 1);
						st.addEntry(label, romAddress);
					}
					else
						romAddress++;

					String instruction = p.getInstruction();
					if(p.commandType().equals("A_COMMAND"))
					{
						String address = instruction.substring(1,instruction.length());
						boolean variable = false;
						int i = 0;
						while (!variable && i < address.length())
						{
							if (address.substring(i, i+1).hashCode() < 48 || address.substring(i, i+1).hashCode() > 57)
								variable = true;
							else 
								i++;
						}
						if (variable)
						{
							if (st.contains(address))
								decimal	= st.getAddress(address);
							else
							{
								decimal = ramAddress;
								st.addEntry(address, decimal);
								ramAddress++;
							}
						}
						else
						{
							decimal = Integer.parseInt(address);
						}   
						String binaryAddress = Integer.toBinaryString(decimal);
						int neededZeros = 16 - binaryAddress.length();
							for (int z = 0 ; z < neededZeros ; z++)
							{
								binaryAddress = 0 +"" + binaryAddress;
							}
						outFile.println(binaryAddress);
					}
					if (p.commandType().equals("C_COMMAND"))
						outFile.println("111"+c.compute(p.comp())+ c.dest(p.dest())+c.jump(p.jump()));
				}
				outFile.close();	
			}  
	}
}
