#include "ASMParser.h"
#include "ParseResult.h"
#include "DATAParser.h"
#include "SymbolTable.h"
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define MAX_LINE_LENGTH 257
void getTextSymbols(FILE *readF, uint16_t currOffset);
void getDataSymbols(FILE *readF, uint16_t currOffset);
int main(int args, char *files[])
{
if (args > 2)
{
// Reads in input file and create output file
FILE *readF = fopen(files[1], "r");
FILE *outF = fopen(files[2], "w");
// Checks for input file
if (!readF)
printf("Error: unable to create %s\n", files[1]);
else
{
char *line = calloc(MAX_LINE_LENGTH, sizeof(char)),
*dataSection = NULL;
bool data = false,
text = false,
table = false;
int instructionNum = 0;
while (fgets(line, MAX_LINE_LENGTH - 1, readF))
{
char lineCopy[MAX_LINE_LENGTH + 1];
strcpy(lineCopy, line);
char instruction[MAX_LINE_LENGTH + 1];
strcpy(instruction, strtok(lineCopy, " ,\t"));
instruction[strcspn(instruction, "\n")] = 0;
char *type = findType(instruction);
if (strcmp(instruction, "#") != 0 && strcmp(instruction, " ") != 0)
{
if (table)
{
free(type);
free(line);
fclose(outF);
fclose(readF);
return 0;
}
if (!strcmp(instruction, ".data"))
{
data = true;
getDataSymbols(readF, ftell(readF));
continue;
}
if (!strcmp(instruction, ".text"))
{
text = true;
getTextSymbols(readF, ftell(readF));
if ((table = (args == 4)))
makeTable(outF);
continue;
}
if (data)
{
int i = 0, x = 0, length = 0;
while (dataSymbols[x].binary)
length += strlen(dataSymbols[x++].binary) + 1;
dataSection = calloc(length * 2, sizeof(char));
strcpy(dataSection, dataSymbols[0].binary);
while (dataSymbols[++i].binary)
{
int prevLength = strlen(dataSymbols[i - 1].binary);
char *prevType = dataSymbols[i - 1].type,
*currType = dataSymbols[i].type;
if (!strcmp(prevType, ".asciiz") && !strcmp(currType, ".word"))
{
int length = (prevLength < 33) ? prevLength : prevLength % 33,
num_zero = 32 - length, x = 0;
if (prevLength != 33)
{
while (x++ < num_zero)
strcat(dataSection, "0");
strcat(dataSection, "\n");
}
}
strcat(dataSection, dataSymbols[i].binary);
if ((prevLength + strlen(dataSymbols[i].binary)) % 33 == 32)
strcat(dataSection, "\n");
}
int dataLen = strlen(dataSection), remainder, j = 0;
if ((remainder = (dataLen % 33)) != 0)
{
while (j++ < (32 - (dataLen % 33)))
strcat(dataSection, "0");
strcat(dataSection, "\n");
}
data = false;
continue;
}
if (text)
{
if (type)
{
line[strcspn(line, "\n")] = 0;
char *bltCopy;
if (!strcmp(instruction, "blt"))
{
bltCopy = calloc(MAX_LINE_LENGTH + 1, sizeof(char));
strcpy(bltCopy, line);
}
ParseResult *asmI = parseASM(line, ++instructionNum);
if (!strcmp(type, "r"))
fprintf(outF, "%s%s%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT,
asmI->RD, asmI->shamt, asmI->Funct);
if (!strcmp(type, "i"))
fprintf(outF, "%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT, asmI->IMM);
if (!strcmp(type, "s"))
fprintf(outF, "%s%s%s%s%s%s\n", asmI->Opcode, asmI->RS, asmI->RT, asmI->RD,
asmI->RD, asmI->Funct);
if (!strcmp(type, "ju"))
fprintf(outF, "%s%s\n", asmI->Opcode, asmI->Target);
if (!strcmp(asmI->Mnemonic, "blt"))
{
ParseResult *bltAsmi = parseASM(bltCopy, ++instructionNum);
fprintf(outF, "%s%s%s%s\n", bltAsmi->Opcode, bltAsmi->RS, bltAsmi->RT, bltAsmi->IMM);
free(bltAsmi);
free(bltCopy);
}
clearResult(asmI);
free(asmI);
}
continue;
}
}
}
fprintf(outF, "\n%s", dataSection);
free(line);
free(dataSection);
fclose(outF);
fclose(readF);
}
cleanTable();
}
return 0;
}
void getDataSymbols(FILE *readF, uint16_t currOffset)
{
fseek(readF, currOffset, SEEK_SET);
char *line = calloc(MAX_LINE_LENGTH, sizeof(char));
int count = 0, address = 8192;
while (fgets(line, MAX_LINE_LENGTH - 1, readF))
{
char lineCopyData[MAX_LINE_LENGTH + 1];
strcpy(lineCopyData, line);
strcpy(dataSymbols[count].key, strtok(line, " ,\t"));
dataSymbols[count].key[strcspn(dataSymbols[count].key, "\n")] = 0;
if (!strcmp(dataSymbols[count].key, ".text"))
break;
if (!findType(dataSymbols[count].key) && strlen(dataSymbols[count].key) > 0)
{
dataSymbols[count].key[strcspn(dataSymbols[count].key, ":")] = 0;
parseDATA(lineCopyData, count);
dataSymbols[count].address = address;
int binLength = strlen(dataSymbols[count++].binary);
address += (binLength % 33 == 0) ? (4 * (binLength / 33)) : (4 * ((binLength / 33) + 1));
}
}
dataSymbols[count].binary = NULL;
fseek(readF, currOffset, SEEK_SET);
free(line);
}
void getTextSymbols(FILE *readF, uint16_t currOffset)
{
fseek(readF, currOffset, SEEK_SET);
char *line = calloc(MAX_LINE_LENGTH, sizeof(char));
int count = 0, address = 0, instructionCount = 0;
while (fgets(line, MAX_LINE_LENGTH, readF))
{
char tSymbol[MAX_LINE_LENGTH + 1];
strcpy(tSymbol, strtok(line, " ,\t"));
tSymbol[strcspn(tSymbol, "\n")] = 0;
if (!findType(tSymbol) && strcmp(tSymbol, "") != 0 && strcmp(tSymbol, "#") != 0)
{
tSymbol[strcspn(tSymbol, ":")] = 0;
textSymbols[count].key = calloc(MAX_LINE_LENGTH, sizeof(char));
strcpy(textSymbols[count].key, tSymbol);
textSymbols[count].instructionNum = (strcmp(tSymbol, "main") == 0) ? instructionCount : (instructionCount + 1);
address = (4 * instructionCount);
textSymbols[count++].address = address;
}
if (findType(tSymbol))
instructionCount++;
}
textSymbols[count].key = NULL;
textSymbols[count].instructionNum = 0;
fseek(readF, currOffset, SEEK_SET);
free(line);
}