-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssembler.java
More file actions
152 lines (151 loc) · 6.75 KB
/
Assembler.java
File metadata and controls
152 lines (151 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import java.util.HashMap;
public class Assembler {
// Hashmap to store codes which are in 2r or immediate formats.
private static HashMap<String, String> TwoRImmediateOpCodes = new HashMap<String, String>();
// Hashmap to store codes which are in call/return formats
private static HashMap<String, String> CallReturnOpCodes = new HashMap<String, String>();
// Method to place codes and their corresponding binary vals.
private static void setOpCodes(){
TwoRImmediateOpCodes.put("halt", "fffff");
TwoRImmediateOpCodes.put("add", "fffft");
TwoRImmediateOpCodes.put("and", "ffftf");
TwoRImmediateOpCodes.put("multiply","ffftt");
TwoRImmediateOpCodes.put("leftshift", "fftff");
TwoRImmediateOpCodes.put("subtract","fftft");
TwoRImmediateOpCodes.put("or", "ffttf");
TwoRImmediateOpCodes.put("rightshift", "ffttt");
CallReturnOpCodes.put("syscall", "ftfff");
CallReturnOpCodes.put("call", "ftfft");
CallReturnOpCodes.put("return", "ftftf");
TwoRImmediateOpCodes.put("compare", "ftftt");
CallReturnOpCodes.put("ble", "fttff");
CallReturnOpCodes.put("blt", "fttft");
CallReturnOpCodes.put("bge", "ftttf");
CallReturnOpCodes.put("bgt", "ftttt");
CallReturnOpCodes.put("beq", "tffff");
CallReturnOpCodes.put("bne", "tffft");
TwoRImmediateOpCodes.put("load", "tfftf");
TwoRImmediateOpCodes.put("store", "tfftt");
TwoRImmediateOpCodes.put("copy", "tftff");
}
// Method to convert integer number into binary format
private static String convertNumber(int value, int size){
// Final string fin to return for method
String fin = "";
// isNegative checks to see if the val is less than 0, if so prepare to negate it by adding 1 and conditionally manipulating the bits
// (depending on whether its a negative or not)
boolean isNegative = (value < 0);
// Index to ensure that the final string doesn't become bigger than index
int index = size;
if(isNegative)
value++;
// while the value isn't 0, divide it by 2, if the remainder after being divided isn't true, then set it to 1 (or 0). If it's negative and odd, then
// also set the bit to true.
while(value != 0 && index != 0){
if(!isNegative && ((value % 2) == 0))
fin += "f";
else if(!isNegative && ((value % 2) != 0))
fin += "t";
else if(isNegative && ((value % 2) == 0))
fin += "t";
else
fin += "f";
index--;
value /=2;
}
// Padding to convert negative numbers in the case the fin string is less than size.
String padding = "";
int len = size - fin.length();
int n = 0;
char ch = 'f';
// set ch to t if negative
if(isNegative)
ch = 't';
// Set padding to character
while(n < len){
padding += ch;
n++;
}
// Return padding + reversed string.
StringBuilder sb = new StringBuilder(fin);
return padding + sb.reverse();
}
public static String[] assemble(String[] input) {
// Set up the operation codes
setOpCodes();
// Initialize an output string
String[] output = new String[input.length];
// i to keep track the location of the string in each input string
int i = 0;
// iterate thru input and derivce the line from input string list.
for(String ln : input){
// isCallReturnFormat boolean to determine the type of format of ln.
boolean isCallReturnFormat = false;
// strForOutput is the final input to be used for the output str list
String strForOutput = "";
// wrds is the result of the ln splitted by space, this will then assemble
// the whole line into a legible 16 bit output.
String[] wrds = ln.split(" ");
for(String wrd : wrds){
// First check if the wrd is a number and is not in CallReturn format
if(checkIfNumber(wrd) && !isCallReturnFormat){
// If number, then replace 'f' with 't' to instructions + bin num.
strForOutput = strForOutput.substring(0, strForOutput.length()-1);
strForOutput += "t"+convertNumber(Integer.parseInt(wrd), 5);
}
// If not in call returnFormat, then add integer of size 11
else if(checkIfNumber(wrd)){
strForOutput += convertNumber(Integer.parseInt(wrd), 11);
}
// Check if wrd is a register + a number.
else if(wrd.charAt(0) == 'r' && !CallReturnOpCodes.containsKey(wrd) && !TwoRImmediateOpCodes.containsKey(wrd))
strForOutput += convertNumber(Integer.parseInt(wrd.substring(1)),5);
// Add CallReturnOpCodes bin val to strForOutput
else if(CallReturnOpCodes.containsKey(wrd)){
strForOutput += CallReturnOpCodes.get(wrd);
isCallReturnFormat = true;
}
// Add TwoRImmediateOpcodes val of string to strForOutput
else{
strForOutput += TwoRImmediateOpCodes.get(wrd) + "f";
}
}
// Fill the string with f if size of strForOutput is less than 16
int len = strForOutput.length();
while(len != 16){
strForOutput += 'f';
len++;
}
// Set output to strForOutput, add i to set up for next conversion.
output[i] = strForOutput;
i++;
}
return output;
}
// Check if number checks if a string is able to be converted to an int.
private static boolean checkIfNumber(String s){
try{
Integer.parseInt(s);
return true;
} catch(Exception e){
return false;
}
}
public static String[] finalOutput(String[] input) {
// newSize to account for odd instances of input len.
int newSize = (input.length + 1) / 2;
// Fin to be created as the output.
String[] fin = new String[newSize];
// Halt string in cases of a singular line.
String halt = "ffffffffffffffff";
// For each index in fin, if i value is in input, add it,
// else, add the final line plus halt as the final output for the assembler.
for (int i = 0; i < fin.length; i++) {
if (2 * i + 1 < input.length)
fin[i] = input[2 * i] + input[2 * i + 1];
else
fin[i] = input[2 * i] + halt;
}
return fin;
}
}