12
12
13
13
using namespace std ;
14
14
15
+ ofstream log (" log.txt" , ios::ate | ios::app);
16
+ int lineNum = 0 ;
17
+ bool errorFlag = false ;
18
+
15
19
/* ========== Methods to determine which relative addressing mode is to be used ========== */
16
20
bool checkPCRel (int operandVal);
17
21
@@ -75,6 +79,15 @@ printListLine(ostream &lout, int lineNum, int locctr, string label, string opcod
75
79
lout << setw (10 ) << left << objectcode << " \n " ;
76
80
}
77
81
82
+ void printLogLine (vector<string> &line) {
83
+ errorFlag = true ;
84
+ std::string outLine = " " ;
85
+ for (auto const &s : line) {
86
+ outLine += s + " " ;
87
+ }
88
+ log << outLine << " \n " ;
89
+ }
90
+
78
91
string createObjectFile (std::string intermediateFile) {
79
92
ifstream fin (intermediateFile.c_str ());
80
93
if (!fin.is_open ()) {
@@ -86,6 +99,9 @@ string createObjectFile(std::string intermediateFile) {
86
99
87
100
ofstream fout (objectFile.c_str ());
88
101
ofstream lout (listingFile.c_str ());
102
+ if (!log .is_open ()) {
103
+ log .open (" log.txt" , ios::ate | ios::app);
104
+ }
89
105
90
106
prepareListingFile (lout);
91
107
@@ -95,13 +111,14 @@ string createObjectFile(std::string intermediateFile) {
95
111
}
96
112
vector<string> line;
97
113
string opcode, operand, label, locctr;
98
- int lineNum = 5 ;
114
+ lineNum = 5 ;
99
115
string baseLocHex;
100
116
string textRecord = " T" ;
101
117
string objectCode = " " ;
102
118
string modificationRecord = " " ;
103
119
bool shouldAddMRecord = startAddr == 0 ;
104
120
bool canUseBase = false ;
121
+ errorFlag = false ;
105
122
string currBlock = " DEFAULT" ;
106
123
while (readLine (fin, line)) {
107
124
// Skip the line if it's empty or contains on the location counter's value
@@ -149,12 +166,13 @@ string createObjectFile(std::string intermediateFile) {
149
166
if (instrInfo.first == " 1" ) {
150
167
instructionHex = instrInfo.second ;
151
168
} else if (instrInfo.first == " 2" ) {
152
- cerr << " No operand specified for " << opcode << " instruction\n " ;
169
+ log << " Line: " << lineNum << " , No operand specified for " << opcode << " instruction\n " ;
153
170
} else if (safe (opcode) == " RSUB" ) {
154
171
int xbpe = opcode[0 ] == ' +' ? 1 : 0 ;
155
172
instructionHex = assInstr_34 (instrInfo.second , 3 , xbpe, 0 );
156
173
} else {
157
- cerr << " No operand specified for " ;
174
+ log << " Line: " << lineNum << " , No operand specified for " << opcode << " instruction\n " ;
175
+ printLogLine (line);
158
176
}
159
177
break ;
160
178
}
@@ -169,7 +187,9 @@ string createObjectFile(std::string intermediateFile) {
169
187
sym_it = it_sym;
170
188
ni = 1 ;
171
189
} else {
172
- cerr << " Can't use Immediate addr with format " << instrInfo.first << " \n " ;
190
+ log << " Line: " << lineNum << " Can't use Immediate addr with format " << instrInfo.first
191
+ << " \n " ;
192
+ printLogLine (line);
173
193
}
174
194
} else {
175
195
instructionHex = handleImmediateIntegerOperand (instrInfo.second , operand, opcode[0 ]);
@@ -187,10 +207,13 @@ string createObjectFile(std::string intermediateFile) {
187
207
sym_it = it_sym;
188
208
ni = 2 ;
189
209
} else {
190
- cerr << " Can't use indirect addr with format " << instrInfo.first << " \n " ;
210
+ log << " Line: " << lineNum << " , Can't use indirect addr with format "
211
+ << instrInfo.first << " \n " ;
212
+ printLogLine (line);
191
213
}
192
214
} else {
193
- cerr << " Symbol: " << it_sym->first << " not found in symtab" ;
215
+ log << " Line: " << lineNum << " , Symbol: " << it_sym->first << " not found in symtab" ;
216
+ printLogLine (line);
194
217
}
195
218
break ;
196
219
}
@@ -207,19 +230,23 @@ string createObjectFile(std::string intermediateFile) {
207
230
x = 8 ;
208
231
break ;
209
232
} else if (instrInfo.first != " 2" ) {
210
- cerr << " Can't use indexed addr with format " << instrInfo.first << " \n " ;
233
+ log << " Line: " << lineNum << " , Can't use indexed addr with format " << instrInfo.first
234
+ << " \n " ;
235
+ printLogLine (line);
211
236
break ;
212
237
}
213
238
} else {
214
- cerr << " Symbol: " << it_sym->first << " not found in symtab" ;
239
+ log << " Line: " << lineNum << " , Symbol: " << it_sym->first << " not found in symtab" ;
240
+ printLogLine (line);
215
241
break ;
216
242
}
217
243
// Break not added to allow the passing of format 2 instructions into the next case.
218
244
}
219
245
// Two register instructions
220
246
case 4 : {
221
247
if (instrInfo.first != " 2" ) {
222
- cerr << " Unknown symbol: " << operand;
248
+ log << " Line: " << lineNum << " , Unknown symbol: " << operand;
249
+ printLogLine (line);
223
250
} else {
224
251
string r1, r2;
225
252
unsigned long pos = operand.find (' ,' );
@@ -246,7 +273,8 @@ string createObjectFile(std::string intermediateFile) {
246
273
ni = 3 ;
247
274
}
248
275
} else {
249
- cerr << " Symbol: " << it_sym->first << " not found in symtab" ;
276
+ log << " Line: " << lineNum << " , Symbol: " << it_sym->first << " not found in symtab" ;
277
+ printLogLine (line);
250
278
}
251
279
break ;
252
280
}
@@ -266,7 +294,8 @@ string createObjectFile(std::string intermediateFile) {
266
294
} else if (canUseBase && checkBaseRel (baseRelOp)) {
267
295
instructionHex = assInstr_34 (instrInfo.second , ni, x + 4 , baseRelOp);
268
296
} else {
269
- cerr << " Can't use PC rel or Base rel addr to assemble this instr\n " ;
297
+ log << " Line: " << lineNum << " , Can't use PC rel or Base rel addr to assemble this instr\n " ;
298
+ printLogLine (line);
270
299
}
271
300
}
272
301
} else if (opcode == " BYTE" | opcode == " WORD" ) {
@@ -284,7 +313,8 @@ string createObjectFile(std::string intermediateFile) {
284
313
instructionHex = intToHexStr (dec_val);
285
314
}
286
315
catch (const invalid_argument &ia) {
287
- cerr << " wrong WORD value " << operand << " \n " ;
316
+ log << " Line: " << lineNum << " , wrong WORD value " << operand << " \n " ;
317
+ printLogLine (line);
288
318
}
289
319
}
290
320
}
@@ -304,6 +334,12 @@ string createObjectFile(std::string intermediateFile) {
304
334
string retVal = fout.is_open () ? objectFile : " Not created" ;
305
335
fin.close ();
306
336
fout.close ();
337
+ log .close ();
338
+ if (errorFlag) {
339
+ cerr << " Assembly not successful, check log.txt for more info\n " ;
340
+ } else {
341
+ cout << " Object program File successfully generated!\n " ;
342
+ }
307
343
return retVal;
308
344
}
309
345
@@ -353,9 +389,6 @@ void initVariables(vector<string> &line, string &label, string &opcode, string &
353
389
if (OPTAB.safeFind (opcode) == OPTAB.end ()) {
354
390
label = line[1 ];
355
391
opcode = line[2 ];
356
- if (OPTAB.safeFind (operand) == OPTAB.end ()) {
357
- cerr << " Unknown Line\n " ;
358
- }
359
392
}
360
393
} else if (line.size () == 2 ) {
361
394
opcode = line[1 ];
@@ -369,30 +402,35 @@ string handleImmediateIntegerOperand(string opcodeHex, const string &operand, ch
369
402
operand_dec = static_cast <unsigned int >(stoi (_operand));
370
403
}
371
404
catch (const invalid_argument &ia) {
372
- cerr << " Unspecified immediate operand: " << _operand << " \n " ;
405
+ log << " Line: " << lineNum << " , Unspecified immediate operand: " << _operand << " \n " ;
406
+ errorFlag = true ;
373
407
return " " ;
374
408
}
375
409
if (opcode_first_char == ' +' ) {
376
410
if (operand_dec > 1048575 ) {
377
- cerr << " operand too large to fit in format 4: " << operand;
411
+ log << " Line: " << lineNum << " , operand too large to fit in format 4: " << operand;
412
+ errorFlag = true ;
378
413
} else {
379
414
return assInstr_34 (opcodeHex, 1 , 1 , operand_dec);
380
415
}
381
416
} else if (operand_dec < 4096 ) {
382
417
return assInstr_34 (opcodeHex, 1 , 0 , operand_dec);
383
418
} else {
384
- cerr << " operand too large to fit in format 3: " << operand;
419
+ log << " Line: " << lineNum << " , operand too large to fit in format 3: " << operand;
420
+ errorFlag = true ;
385
421
}
386
422
}
387
423
388
424
template <typename T>
389
425
bool isRegisterValid (T it1, const string &operand) {
390
426
if (it1 == SYMTAB.end ()) {
391
- cerr << " Invalid register symbol: " << operand << " \n " ;
427
+ log << " Line: " << lineNum << " , Invalid register symbol: " << operand << " \n " ;
428
+ errorFlag = true ;
392
429
return false ;
393
430
}
394
431
if (stoi (it1->second .first ) < 0 || stoi (it1->second .first ) > 9 || stoi (it1->second .first ) == 7 ) {
395
- cerr << " Expected a register, found: " << it1->first << " \n " ;
432
+ log << " Line: " << lineNum << " , Expected a register, found: " << it1->first << " \n " ;
433
+ errorFlag = true ;
396
434
return false ;
397
435
}
398
436
return true ;
@@ -406,7 +444,8 @@ string assInstr_2(string opcodeHex, string r1, string r2) {
406
444
b = stoi (r2);
407
445
}
408
446
catch (const invalid_argument &ia) {
409
- cerr << " Not correct register types: " << r1 << " " << r2 << " \n " ;
447
+ log << " Line: " << lineNum << " , Not correct register types: " << r1 << " " << r2 << " \n " ;
448
+ errorFlag = true ;
410
449
}
411
450
return intToHexStr ((opcode_dec << 8 ) + a + b, 4 );
412
451
}
0 commit comments