|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include "MIPSCodeGen.h" |
|
|
|
#define LINE_LENGTH 256 |
|
|
|
void parseStatements(FILE *source, statementType statements[]) { |
|
char statement[LINE_LENGTH]; |
|
int x, y, lineNumber = 0; |
|
|
|
while (fscanf(source, "%s (%d, %d)", statement, &x, &y) != EOF) { |
|
printf("%s\" (%d, %d)", statement, x, y); |
|
|
|
if (strcmp(statement, "moveto")) { |
|
statements[lineNumber].identity = MOVETO; |
|
} else if (strcmp(statement, "lineto")) { |
|
statements[lineNumber].identity = LINETO; |
|
} else if (strcmp(statement, "rmoveto")) { |
|
statements[lineNumber].identity = RMOVETO; |
|
} else if (strcmp(statement, "rlineto")) { |
|
statements[lineNumber].identity = RLINETO; |
|
} |
|
|
|
statements[lineNumber].x = x; |
|
statements[lineNumber].y = y; |
|
lineNumber++; |
|
} |
|
|
|
printf("ParseStatements takes place\n"); |
|
} |
|
|
|
pointType buildNextMove(FILE *dest, statementType nextMove, pointType currentPosition) { |
|
pointType target; |
|
|
|
// calculate the x- and y-values for the next move |
|
switch (nextMove.identity) { |
|
case MOVETO: |
|
case LINETO: |
|
target.x = nextMove.x; |
|
target.y = nextMove.y; |
|
break; |
|
case RMOVETO: |
|
case RLINETO: |
|
target.x = nextMove.x + currentPosition.x; |
|
target.y = nextMove.y + currentPosition.y; |
|
break; |
|
default: // shouldn't happen |
|
break; |
|
} |
|
|
|
// code generation takes place |
|
switch (nextMove.identity) { |
|
case MOVETO: |
|
fprintf(dest, "\t\t\t# Move to (%d, %d)\n", target.x, target.y); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.x, NO_TRACK, DO_X); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.y, NO_TRACK, DO_Y); |
|
break; |
|
case LINETO: |
|
fprintf(dest, "\t\t\t# Draw a line to (%d, %d)\n", target.x, target.y); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.x, DO_TRACK, DO_X); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.y, DO_TRACK, DO_Y); |
|
fprintf(dest, DROP_TRACK); |
|
break; |
|
case RMOVETO: |
|
fprintf(dest, "\t\t\t# Move (%d, %d) from the current position\n", nextMove.x, nextMove.y); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.x, NO_TRACK, DO_X); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.y, NO_TRACK, DO_Y); |
|
break; |
|
case RLINETO: |
|
fprintf(dest, "\t\t\t# Draw line (%d, %d) from the curent position\n", nextMove.x, nextMove.y); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.x, DO_TRACK, DO_X); |
|
fprintf(dest, CALL_FORMAT, SET_COORD, target.y, DO_TRACK, DO_Y); |
|
fprintf(dest, DROP_TRACK); |
|
break; |
|
default: // shouldn't happen |
|
break; |
|
} |
|
return target; |
|
} |
|
|
|
int main (int argc, char *argv[]) { |
|
FILE *source, *dest; |
|
pointType currentPosition; |
|
int numLines, i; |
|
|
|
source = sourceIO(argc, argv); // set the source using the correct filepath |
|
dest = destIO(argc, argv); // set the destination filepath |
|
|
|
numLines = lineCount(source); // get the number of lines in the source file |
|
source = sourceIO(argc, argv); // resource the input stream; |
|
|
|
statementType statements[numLines]; |
|
|
|
parseStatements(source, statements); |
|
|
|
fprintf(dest, "# MIPS program automatically generated\n# from PostScript commands in the file %s\n", argv[1]); |
|
fprintf(dest, DATA_SEGMENT); |
|
fprintf(dest, WARN_BEGIN); |
|
|
|
// code generation takes place |
|
for (i = 0; i <= numLines; i++) { |
|
printf("Building move for line %d, %u(%d, %d)\n", i, statements[i].identity, statements[i].x, statements[i].y); |
|
currentPosition = buildNextMove(dest, statements[i], currentPosition); |
|
} |
|
|
|
fprintf(dest, "\t\t\tli\t\t$v0,10\n\t\t\tsyscall\n"); |
|
fprintf(dest, WARN_END); |
|
|
|
// add the horiz and vert methods |
|
fprintf(dest, METHOD_SEGMENT); |
|
|
|
// clean up |
|
fclose(source); |
|
fclose(dest); |
|
|
|
} |