diff --git a/src/test/output.txt b/src/test/output.txt index 494d0b7..d403e92 100644 --- a/src/test/output.txt +++ b/src/test/output.txt @@ -1,55 +1,55 @@ Compiling... Output... -.data -welcomeMessage:.asciiz"WelcometoaMIPSassemblyFibonacciSequencecalculator!\nThiswillcalculatethenthtermoftheFibonacciSequence.\n" -prompt:.asciiz"Enteranumber(ninputn>2)tofindthenthterm:" -foundTerm:.asciiz"Thenthtermis:" - -.text - -main: -li$v04 -la$a0welcomeMessage -syscall - -jalgetInput - -jalfibonacci -move$a0$v0 -li$v01 -syscall - -ori$v0$010 -syscall - -getInput: -li$v04 -la$a0prompt -syscall - -li$v05 -syscall -move$a0$v0 - -jr$ra - -fibonacci: -move$s1$a0 -li$t02 -li$t10 -li$t21 -li$t30 - -while: -bge$t0$s1done -add$t3$t1$t2 -move$t1$t2 - -move$t2$t3 -addi$t0$t01 - -bwhile - -done: -move$v0$t2 -jr$ra +.dataU +welcomeMessage: .asciiz "Welcome to a MIPS assembly Fibonacci Sequence calculator!\nThis will calculate the nth term of the Fibonacci Sequence.\n"! +prompt: .asciiz "Enter a number (n input n > 2) to find the nth term:" +foundTerm: .asciiz "The nth term is: "u +f +.textT +. +main:T +li v0 4r +la a0 welcomeMessageT +syscalle +s +jal getInpute +j +jal fibonacciM +move a0 v0c +li v0 1 +syscall +s +ori v0 0 10c +syscall0 +s +getInput:1 +li v0 4t +la a0 prompti +syscallr +s +li v0 5r +syscallr +move a0 v0p +m +jr raa +j +fibonacci:p +move s1 a0p +li t0 2 +li t1 0 +li t2 1 +li t3 0 +l +while:0 +bge t0 s1 donee +add t3 t1 t2n +move t1 t2t +m +move t2 t3t +addi t0 t0 1n +a +b while +b +done:l +move v0 t2 +jr rav diff --git a/src/util/functionAssigner.h b/src/util/functionAssigner.h new file mode 100644 index 0000000..aef2ac2 --- /dev/null +++ b/src/util/functionAssigner.h @@ -0,0 +1,14 @@ +#define FOREACH_FUNCTION(FUNCTION) \ + FUNCTION(add) \ + FUNCTION(li) \ + +#define GENERATE_ENUM(ENUM) ENUM, +#define GENERATE_STRING(STRING) #STRING, + +enum Function { + FOREACH_FUNCTION(GENERATE_ENUM) +}; + +static char* FUNCTION_STRING[] = { + FOREACH_FUNCTION(GENERATE_STRING) +}; diff --git a/src/util/functions.h b/src/util/functions.h index 9ea0944..22bce48 100644 --- a/src/util/functions.h +++ b/src/util/functions.h @@ -10,24 +10,24 @@ void initFunctions() { iFormat = (i*)malloc(sizeof(i)); } -int * add(int * args[]) { +char * add(int * args[]) { rFormat->opcode = 0; rFormat->rd = *args[0]; rFormat->rs = *args[1]; rFormat->rt = *args[2]; - rFormat->shamt = *args[4]; + rFormat->shamt = *args[3]; rFormat->funct = 20; - return rToBinary(rFormat); + return rToHex(rFormat); } -int * sub(int * args[]) { +char * sub(int * args[]) { rFormat->opcode = 0; rFormat->rd = *args[0]; rFormat->rs = *args[1]; rFormat->rt = *args[2]; - rFormat->shamt = *args[4]; + rFormat->shamt = *args[3]; rFormat->funct = 22; - return rToBinary(rFormat); + return rToHex(rFormat); } diff --git a/src/util/parse.h b/src/util/parse.h index c105060..3d42270 100644 --- a/src/util/parse.h +++ b/src/util/parse.h @@ -5,39 +5,90 @@ #include #include "formats.h" +#include "registers.h" +#include "functionAssigner.h" FILE * file; -char * removeCommentsAndWhiteSpace(char * line) { - int j = 0; - char * newLine; - for(int i = 0; i < strlen(line); i++) { - // If we've reached a comment, we can break to return what we have - if(line[i] == '#') break; +// Determines if the parser should keep a space, based upon if the space is surrounded by two non-space characters. +int determineKeepSpace(char prior, char after) { + if(prior != NULL && !isspace(prior)) + if(after != NULL && !isspace(after)) + return 1; - // Remove commas and spaces. - if((line[i] != ',') && (isspace(line[i]) == 0)) { - newLine[j] = line[i]; - j++; - } - } - - // Remove any excess that is stored from a prior line. - for(; j < strlen(line); j++) - newLine[j] = (char)NULL; - - return newLine; + return 0; } -// Extract the R, I, or J format instruction from each "bare line". A bare line has no spaces or commas. -r* parse(char * bareLine) { - r* format = (r*)malloc(sizeof(r)); +// Cleans up the input string to prepare for parsing into command and arguments. +char * removeCommentsAndWhiteSpace(char * line) { + int len = strlen(line); + char tmpLine[256]; + int parsedIndex = 0; - for(int i = 0; i < strlen(bareLine); i++) { - if(bareLine[i] == '$') { - + for(int i = 0; i < len; i++) { + + // Check if we've reached a comment and if so, break out of the loop + if(line[i] == '#') break; + + // Check if the current character is not a comma or dollar sign. + if(line[i] != ',' && line[i] != '$' && !isspace(line[i])) { + tmpLine[parsedIndex] = line[i]; + parsedIndex++; + + } else if(isspace(line[i])) { + + // Check if we're within bounds of the array to check whitespace + if((i - 1 >= 0) && (i + 1 < len)) { + if(determineKeepSpace(line[i - 1], line[i + 1]) == 1) { + tmpLine[parsedIndex] = line[i]; + parsedIndex++; + } + } } } + + // Create a dynamically sized array containing only the valid characters + char * parsed = (char *)calloc(parsedIndex, sizeof(char)); + for(int i = 0; i < parsedIndex; i++) + parsed[i] = tmpLine[i]; + + return parsed; +} + +// Parse a line of assembly into numerical representations for the function (eg. add = 0), registers, offset, etc. +int * parseIntoNotation(char * bareLine) { + int numFunctions = 2; // TODO: Need to obtain dynamically. + int * notation = (int *)calloc(4, sizeof(int)); + //char * tokens = strtok(bareLine, " "); + + char * token = strtok(bareLine, " "); + + int counter = 0; + while (token != NULL) + { + for(int i = 0; i < numFunctions; i++) { + if(strcmp(token, FUNCTION_STRING[i]) == 0) { + printf("found a match between %s and %s, value is %d\n", token, FUNCTION_STRING[i], i); + notation[counter] = i; + counter++; + continue; + } + } + + if(counter == 0) break; + + for(int i = 0; i < 32; i++) { + if(strcmp(token, REGISTER_STRING[i]) == 0) { + printf("found a match between %s and %s, value is %d\n", token, REGISTER_STRING[i], i); + notation[counter] = i; + counter++; + continue; + } + } + + token = strtok(NULL, " "); + } + return notation; } int initParse(char * filepath) { @@ -54,8 +105,13 @@ int initParse(char * filepath) { } // Get each line of the file, remove comments and whitespace, and attempt to parse - while(fgets(lines, sizeof(lines), file)) - printf("%s\n", removeCommentsAndWhiteSpace(lines)); + while(fgets(lines, sizeof(lines), file)) { + char * line = removeCommentsAndWhiteSpace(lines); + int * notation = parseIntoNotation(line); + + printf("notation: %d %d %d %d\n", notation[0], notation[1], notation[2], notation[3]); + free(notation); + } fclose(file);