import java.util.*;
import java.io.*;
public class Assembler_SICXE {
static Vector<String> location = new Vector<String>();
static String address = "";
static String[][] opCode ={
{"ADD","18"},{"ADDF","58"},{"ADDR","90"},{"AND","40"},{"CLEAR","B4"}
,{"COMP","28"},{"COMPF","88"},{"COMPR","A0"},{"DIV","24"},{"DIVF","64"}
,{"DIVR","9C"},{"FIX","C4"},{"FLOAT","C0"},{"HIO","F4"},{"J","3C"}
,{"JEQ","30"},{"JGT","34"},{"JLT","38"},{"JSUB","48"},{"LDA","00"}
,{"LDB","68"},{"LDCH","50"},{"LDF","70"},{"LDL","08"},{"LDS","6C"}
,{"LDT","74"},{"LDX","04"},{"LPS","D0"},{"MULF","60"},{"MULR","98"}
,{"NORM","C8"},{"OR","44"},{"RD","D8"},{"RMO","AC"},{"RSUB","4C"}
,{"SHIFTL","A4"},{"SHIFTR","A8"},{"SIO","F0"},{"SSK","EC"},{"STA","0C"}
,{"STB","78"},{"STCH","54"},{"STF","80"},{"STI","D4"},{"STL","14"}
,{"STS","7C"},{"STSW","E8"},{"STT","84"},{"STX","10"},{"SUB","1C"}
,{"SUBF","5C"},{"SUBR","94"},{"SVC","B0"},{"TD","E0"},{"TIO","F8"}
,{"TIX","2C"},{"TIXR","B8"},{"WD","DC"}};
static String[][] opCode_2BYTE ={
{"ADDR","90"},{"CLEAR","B4"},{"COMPR","A0"},{"DIVR","9C"},{"MULR","98"}
,{"RMO","AC"},{"SHIFTL","A4"},{"SHIFTR","A8"},{"SUBR","94"},{"SVC","B0"}
,{"TIXR","B8"}};
static String[] pseudoInstruction={"START","END","BYTE","WORD","RESB","RESW"};
static Vector<String> SYM_TAB = new Vector<String>();
static Vector<String> SYM_NUM = new Vector<String>();
static Vector<String> inputSymbol = new Vector<String>();
static Vector<String> inputOpCode = new Vector<String>();
static Vector<String> inputOperator = new Vector<String>();
static int indexLocation = 0;
static String n,i,x,b,p,e,BASE;
static String[][] registerNumber ={
{"A","0"},{"X","1"},{"L","2"}
,{"B","3"},{"S","4"},{"T","5"},{"F","6"}};
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
FileReader fr = new FileReader("C:\\users\\Scout\\Desktop\\SICXE2.txt");
BufferedReader bfr = new BufferedReader(fr);
boolean start = false;
Scanner scanner = new Scanner(bfr);
String str1 = "" ,str2 = "" ,str3 = "" ;
boolean oneLine,symbolFind,isPlus;
oneLine = symbolFind = isPlus = false;
while(scanner.hasNext()){
isPlus = false;
String tempString = scanner.next();
StringTokenizer strToken = new StringTokenizer(tempString,"[];',./\\~!@#$%^&*()_+*-{}:\"<>?`=");
if(strToken.countTokens() == 0){
str1 = "";
symbolFind = true;
continue;
}
if(Character.toString(tempString.charAt(0)).equals("+")){
isPlus = true;
StringTokenizer strtkn = new StringTokenizer(tempString,"+");
tempString = strtkn.nextToken();
}
for(int i=0;i<opCode.length;i++){
if(tempString.equals(opCode[i][0]) || tempString.equals(pseudoInstruction[i%6]) || tempString.equals("BASE") || tempString.equals("CLEAR") ){
oneLine = true;
str2 = tempString;
if(str2.equals("RSUB")){
str3 = "";
}else{
str3 = scanner.next();
}
break;
}
}
if(!oneLine && !symbolFind){
symbolFind = true;
str1 = tempString;
}
if(str1.length() == 1){
String temp = inputOperator.lastElement();
inputOperator.remove(inputOperator.size()-1);
temp += ","+str1;
inputOperator.add(temp);
str1 = "";
}
if(oneLine){
if(isPlus){
String temp = "+" + str2;
str2 = temp;
}
inputSymbol.add(str1);
inputOpCode.add(str2);
inputOperator.add(str3);
oneLine = symbolFind = false;
str1 = str2 = str3 = "";
}
}
for(int i=0;i<inputSymbol.size();i++){
StringTokenizer strToken = new StringTokenizer(inputSymbol.get(i)+"\t"+inputOpCode.get(i)+"\t"+inputOperator.get(i));
if(strToken.countTokens() == 3){
if(!start){
address = "0000";
location.add(address);
start = true;
}else{
SYM_TAB.add(inputSymbol.get(i));
SYM_NUM.add(address);
location.add(address);
addAddress(inputOpCode.get(i),inputOperator.get(i));
}
}else if(strToken.countTokens() == 2){
if(inputOpCode.get(i).equals("BASE")){
BASE = inputOperator.get(i);
continue;
}else{
location.add(address);
addAddress(inputOpCode.get(i),inputOperator.get(i));
}
}else if(strToken.countTokens() == 1){
location.add(address);
addAddress(inputOpCode.get(i),inputOperator.get(i));
}
}
for(int i=0;i<SYM_TAB.size();i++){
if(SYM_TAB.get(i).equals(BASE)){
BASE = SYM_NUM.get(i);
}
}
start = false;
for(int i=0;i<inputOpCode.size();i++){
if(!start && inputOpCode.get(i).equals("START")){
start = true;
showLocation();
System.out.println(inputSymbol.get(i)+"\t"+inputOpCode.get(i)+"\t"+inputOperator.get(i));
}else if(inputOpCode.get(i).equals("END")){
System.out.println("\t\t"+inputOpCode.get(i)+"\t"+inputOperator.get(i));
}else if(inputOpCode.get(i).equals("BASE")){
for(int k=0;k<SYM_TAB.size();k++){
if(inputOperator.get(k).equals(SYM_TAB.get(k))){
BASE = SYM_NUM.get(k);
}
}
System.out.println("\t"+inputSymbol.get(i)+"\t"+inputOpCode.get(i)+"\t"+inputOperator.get(i));
}else{
showLocation();
System.out.print(inputSymbol.get(i)+"\t"+inputOpCode.get(i)+"\t"+inputOperator.get(i));
StringTokenizer strToken = new StringTokenizer(inputOperator.get(i),",");
if(strToken.countTokens() == 1){
System.out.print("\t");
}else if(strToken.countTokens() == 2){
String part1 = strToken.nextToken();
String part2 = strToken.nextToken();
if(!part2.equals("X")){
System.out.print("\t");
}
}
System.out.println("\t"+objectCode(inputOpCode.get(i),inputOperator.get(i),i));
}
}
}
public static void addAddress(String str2,String str3){
boolean isPlus = false ;
boolean is2BYTE = false;
if(Character.toString(str2.charAt(0)).equals("+")){
StringTokenizer strToken = new StringTokenizer(str2,"+");
str2 = strToken.nextToken();
isPlus = true;
}
if(str2.equals("BASE")){
return;
}
// else if(str2.equals("CLEAR") || str2.equals("TIXR") || str2.equals("COMPR")){
// address = Integer.toHexString(Integer.parseInt(address,16)+2);
// return;
// }
for(int i=0;i<opCode_2BYTE.length;i++){
if(str2.equals(opCode_2BYTE[i][0])){
address = Integer.toHexString(Integer.parseInt(address,16)+2);
is2BYTE = true;
break;
}
}
if(!is2BYTE){
for(int i=0;i<opCode.length;i++){
if(str2.equals(opCode[i][0])){
address = Integer.toHexString(Integer.parseInt(address,16)+3);
break;
}else if(str2.equals("WORD")){
address = Integer.toHexString(Integer.parseInt(address,16)+3);
break;
}
}
}
// if(str2.equals("STL") || str2.equals("JSUB") || str2.equals("LDA") || str2.equals("COMP") || str2.equals("JEQ") || str2.equals("J") || str2.equals("STA") || str2.equals("LDL") || str2.equals("RSUB") || str2.equals("WORD") || str2.equals("LDX") || str2.equals("TD") || str2.equals("RD") || str2.equals("STCH") || str2.equals("TIX") || str2.equals("JLT") || str2.equals("STX") || str2.equals("LDCH") || str2.equals("WD")){
// address = Integer.toHexString(Integer.parseInt(address,16)+3);
if(str2.equals("BYTE")){
StringTokenizer token = new StringTokenizer(str3,"'");
if(token.nextToken().equals("C")){
String temp = token.nextToken();
address = Integer.toHexString(Integer.parseInt(address,16)+temp.length());
}else{
address = Integer.toHexString(Integer.parseInt(address,16)+1);
}
}else if(str2.equals("RESW")){
address = Integer.toHexString(Integer.parseInt(address,16)+(Integer.parseInt(str3)*3));
}else if(str2.equals("RESB")){
address = Integer.toHexString(Integer.parseInt(address,16)+(Integer.parseInt(str3)));
}
if(isPlus){
address = Integer.toHexString(Integer.parseInt(address,16)+1);
}
if(address.length() < 4){
StringBuilder temp = new StringBuilder(address);
temp.reverse();
for(int i=0;i<(4-address.length());i++){
temp.append("0");
}
temp.reverse();
address = temp.toString();
}
}
public static String objectCode(String str2,String str3,int index){
n = i= x = b = p = e = "0";
String objectCode = "";
boolean isPlus,isHashTag,isAt,is2BYTE,isPseudoInstruction;
isPlus = isHashTag = isAt = is2BYTE = isPseudoInstruction = false;
if(str2.equals("RSUB")){
return "\t4F0000";
}
for(int k=0;k<opCode_2BYTE.length;k++){
if(str2.equals(opCode_2BYTE[k][0])){
is2BYTE = true;
break;
}
}
for(int k=0;k<pseudoInstruction.length;k++){
if(str2.equals(pseudoInstruction[k])){
isPseudoInstruction = true;
break;
}
}
if(Character.toString(str2.charAt(0)).equals("+")){
isPlus = true;
StringTokenizer strtkn = new StringTokenizer(str2,"+");
str2 = strtkn.nextToken();
}
if(Character.toString(str3.charAt(0)).equals("#")){
isHashTag = true;
StringTokenizer strtkn = new StringTokenizer(str3,"#");
str3 = strtkn.nextToken();
}else if(Character.toString(str3.charAt(0)).equals("@")){
isAt = true;
StringTokenizer strtkn = new StringTokenizer(str3,"@");
str3 = strtkn.nextToken();
}
if(str2.equals("BASE") || str2.equals("RESB") || str2.equals("RESW")){
return objectCode;
}else if(isPseudoInstruction){
if(str2.equals("BYTE")){
StringTokenizer tempSTK = new StringTokenizer(str3,"'");
String temp1 = tempSTK.nextToken() , temp2 = tempSTK.nextToken();
if(temp1.equals("X")){
objectCode += temp2;
}else{
char[] temp = temp2.toCharArray();
for(int k=0;k<temp.length;k++){
objectCode += Integer.toHexString((int)temp[k]);
}
}
}else if(str2.equals("WORD")){
String temp = Integer.toHexString(Integer.parseInt(str3)).toUpperCase();
StringBuilder strB = new StringBuilder(temp);
strB.reverse();
if(strB.length() < 6){
for(int i=0;i<(6-temp.length());i++){
strB.append("0");
}
}
strB.reverse();
return strB.substring(strB.length()-6,strB.length());
}
}else if(is2BYTE){
StringTokenizer strtkn = new StringTokenizer(str3,",");
if(strtkn.countTokens() == 1){
for(int k=0;k<opCode_2BYTE.length;k++){
if(str2.equals(opCode_2BYTE[k][0])){
objectCode += opCode_2BYTE[k][1];
//return objectCode.toUpperCase();
}
}
for(int k=0;k<registerNumber.length;k++){
if(str3.equals(registerNumber[k][0])){
objectCode += registerNumber[k][1] + "0";
}
}
}else if(strtkn.countTokens() == 2){
str3 = strtkn.nextToken();
String tempString = strtkn.nextToken();
for(int k=0;k<opCode_2BYTE.length;k++){
if(str2.equals(opCode_2BYTE[k][0])){
objectCode += opCode_2BYTE[k][1];
}
}
for(int k=0;k<registerNumber.length;k++){
for(int j=0;j<registerNumber.length;j++){
if(str3.equals(registerNumber[k][0]) && tempString.equals(registerNumber[j][0])){
objectCode += registerNumber[k][1] + registerNumber[j][1];
//return objectCode.toUpperCase();
}
}
}
}
}else if(isPlus){
if(isPlus){
boolean isSYM = false;
e = "1";
if(isHashTag){
i = "1";
}else if(isAt){
n = "1";
}else if(!isHashTag && !isAt){
n = i = "1";
}
StringTokenizer strtkn = new StringTokenizer(str3,",");
if(strtkn.countTokens() == 2){
x = "1";
str3 = strtkn.nextToken();
}
for(int i=0;i<opCode.length;i++){
if(str2.equals(opCode[i][0])){
String BinaryOpcode = Integer.toBinaryString(Integer.parseInt(opCode[i][1],16));
for(int j=0;j<BinaryOpcode.length()-2;j++){
objectCode += Character.toString(BinaryOpcode.charAt(j));
}
break;
}
}
objectCode += n + i + x + b + p + e;
for(int i=0;i<SYM_TAB.size();i++){
if(str3.equals(SYM_TAB.get(i))){
isSYM = true;
String temp = Integer.toBinaryString(Integer.parseInt(SYM_NUM.get(i),16));
if(temp.length() < 20){
StringBuilder strb = new StringBuilder(temp);
strb.reverse();
for(int k=0;k<(20-temp.length());k++){
strb.append("0");
}
strb.reverse();
temp = strb.toString();
}
objectCode += temp;
break;
}
}
if(!isSYM){
String temp = Integer.toBinaryString(Integer.parseInt(str3));
if(temp.length() < 20){
StringBuilder strb = new StringBuilder(temp);
strb.reverse();
for(int k=0;k<(20-temp.length());k++){
strb.append("0");
}
strb.reverse();
temp = strb.toString();
}
objectCode += temp;
}
objectCode = Integer.toHexString(Integer.parseInt(objectCode,2));
}
}else if(isHashTag){
i = "1";
PCorBASE(str3);
objectCode = generateObjectCode(str2,str3);
}else if(isAt){
n = "1";
PCorBASE(str3);
objectCode = generateObjectCode(str2,str3);
}else{
n = i = "1";
PCorBASE(str3);
objectCode = generateObjectCode(str2,str3);
}
return objectCode.toUpperCase();
}
public static String generateObjectCode(String str2,String str3){
String objectCode = "";
boolean isSYM = false;
StringTokenizer strtkn = new StringTokenizer(str3,",");
if(strtkn.countTokens() == 2){
x = "1";
str3 = strtkn.nextToken();
}
for(int i=0;i<opCode.length;i++){
if(str2.equals(opCode[i][0])){
String BinaryOpcode = Integer.toBinaryString(Integer.parseInt(opCode[i][1],16));
for(int j=0;j<BinaryOpcode.length()-2;j++){
objectCode += Character.toString(BinaryOpcode.charAt(j));
}
break;
}
}
objectCode += n + i + x + b + p + e;
String temp = "";
for(int i=0;i<SYM_TAB.size();i++){
if(str3.equals(SYM_TAB.get(i))){
isSYM = true;
str3 = SYM_NUM.get(i);
if(p.equals("1")){
temp = Integer.toHexString(Integer.parseInt(str3,16)-Integer.parseInt(location.get(indexLocation),16));
}else if(b.equals("1")){
temp = Integer.toHexString(Integer.parseInt(str3,16)-Integer.parseInt(BASE,16));
}
if(temp.length() < 3){
StringBuilder strb = new StringBuilder(temp);
strb.reverse();
for(int k=0;k<(3-temp.length());k++){
strb.append("0");
}
strb.reverse();
temp = strb.toString();
}
break;
}
}
if(!isSYM){
String tempstr = Integer.toBinaryString(Integer.parseInt(str3));
if(tempstr.length() < 12){
StringBuilder strb = new StringBuilder(tempstr);
strb.reverse();
for(int k=0;k<(12-tempstr.length());k++){
strb.append("0");
}
strb.reverse();
tempstr = strb.toString();
}
objectCode += tempstr;
}
if(temp.length() > 3){
String str = "";
for(int i=temp.length()-3;i<temp.length();i++){
str += Character.toString(temp.charAt(i));
}
temp = str;
}
objectCode = Integer.toHexString(Integer.parseInt(objectCode,2)) + temp;
if(objectCode.length() < 6){
StringBuilder strb = new StringBuilder(objectCode);
strb.reverse();
for(int k=0;k<(6-objectCode.length());k++){
strb.append("0");
}
strb.reverse();
objectCode = strb.toString();
}
return objectCode;
}
public static void PCorBASE(String str3){
boolean isSYM = false;
StringTokenizer strtkn = new StringTokenizer(str3,",");
if(strtkn.countTokens() == 2){
x = "1";
str3 = strtkn.nextToken();
}
for(int i=0;i<SYM_TAB.size();i++){
if(str3.equals(SYM_TAB.get(i))){
isSYM = true;
str3 = SYM_NUM.get(i);
}
}
if(isSYM){
int temp = Integer.parseInt(str3,16)-Integer.parseInt(location.get(indexLocation),16);
if(temp >= -2048 && temp <=2047){
b="0";p="1";
return;
}else{
b="1";p="0";
}
}else{
b = p = "0";
}
}
public static void showLocation(){
System.out.print(location.get(indexLocation).toUpperCase()+"\t");
indexLocation++;
}
}