Skip to content

Instantly share code, notes, and snippets.

@hawkw
Last active December 30, 2015 09:39
Show Gist options
  • Save hawkw/7810491 to your computer and use it in GitHub Desktop.
Save hawkw/7810491 to your computer and use it in GitHub Desktop.
Tell me what's wrong with my program. See instructions.md for further instructions.

compile with:

gcc -c MIPSCodeGen.c -o MIPSCodeGen.o
gcc -c postscriptToMIPS.c -o postscriptToMIPS.o
gcc postscriptToMIPS.o MIPSCodeGen.o -o postscriptToMIPS

run with:

./postscriptToMIPS postscriptTest.ps <name of output file here>

and tell me what's wrong with my program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MIPSCodeGen.h"
/*
* lineCount(): returns the number of lines in a file.
*/
int lineCount (FILE *target) {
int numLines = 0, character = 0;
while((character = fgetc(target)) != EOF)
if (character == '\n')
numLines++;
return numLines;
}
void fileCopy(FILE *source, FILE *target) {
int character;
while((character = fgetc(source)) != EOF)
fputc(character, target);
}
FILE* sourceIO (int argc, char *argv[]) {
FILE *source;
switch(argc) {
case 1: // if there are no args, use console for input
source = stdin;
break;
case 2: // if there is an arg, use it as the in source
case 3: // if there are two args, use the first as the source and the second as the destination
if ((source = fopen(argv[1], "r")) == NULL) {
printf ("Can't open input file %s.\n", argv[1]);
exit(0);
}
break;
default: // if there are >2 args, than you have too many args (and will not go to space today)
printf("Oops, you entered too many arguments.\n");
exit(0);
}
return source;
}
FILE* destIO (int argc, char *argv[]) {
FILE *dest;
switch(argc) {
case 1: // if there are no args, use console for input
case 2: // if there is an arg, use it as the in source
dest = fopen(DEFAULT_OUT, "w");
break;
case 3: // if there are two args, use the first as the source and the second as the destination
if ((dest = fopen(argv[2], "w")) == NULL) {
printf ("Can't open destination file %s.\n", argv[1]);
exit(0);
}
break;
default: // if there are >2 args, than you have too many args (and will not go to space today)
printf("Oops, you entered too many arguments.\n");
exit(0);
}
return dest;
}
void getLibMethods(FILE* destination) {
int parsing = 0;
char* line;
FILE* source = fopen("MIPSCodeGen.h", "r");
while (!feof(source)) {
fgets(line, 256, source);
if (strcmp("BEGIN LIB METHOD SEGMENT", line)) {
parsing = 1;
} else if (strcmp("BEGIN LIB METHOD SEGMENT", line)) {
return;
} else if (parsing) {
fputs(line, destination);
}
}
}
void getLibData(FILE* destination) {
int parsing = 0;
char* line;
printf("IM HAPPEN L99");
FILE* source = fopen("MIPSCodeGen.h", "r");
while (!feof(source)) {
fgets(line, 256, source);
if (strcmp("BEGIN LIB DATA SEGMENT", line)) {
parsing = 1;
} else if (strcmp("END LIB DATA SEGMENT", line)) {
return;
} else if (parsing) {
fputs(line, destination);
}
}
}
#pragma once
#define DEFAULT_OUT "points.asm"
#define CALL_FORMAT "\t\t\t%s%d\n\t\t\t%s\n\t\t\t%s\n\n"
#define SET_COORD "li\t\t$a0,"
#define DO_TRACK "li\t\t$a1,1"
#define NO_TRACK "li\t\t$a1,0"
#define DO_X "jal\t\thoriz"
#define DO_Y "jal\t\tvert"
#define DROP_TRACK "\t\t\tlw\t\t$t0,LEAVETRK\t# \"drop\" the track\n\t\t\tsw\t\t$zero,0($t0)\n\n"
#define WARN_BEGIN "#======== BEGIN PROGRAMMATICALLY GENERATED CODE ========#\n"
#define WARN_END "#======== END PROGRAMMATICALLY GENERATED CODE ========#\n"
#define DATA_SEGMENT "# This file contains MIPS assembly code written by\n# Professor Robert Roos at Allegheny College.\n\t\t\t.data\nHEADING:\t.word\t0xffff8010\t# set by program\nLEAVETRK:\t.word\t0xffff8020\t# set by program\nWHEREX:\t.word\t0xffff8030\t# read by program\nWHEREY:\t.word\t0xffff8040\t# read by program\nMOVE:\t.word\t0xffff8050\t# set by program\n\t\t\t.text\n\t\t\t.globl\tmain\n"
#define METHOD_SEGMENT "##################################################\nhoriz:\t\t# Preserve registers (just in case!)\n\t\t\taddi\t\t$sp,$sp,-16\n\n\n\t\t\tsw\t\t$s0,0($sp)\n\t\t\tsw\t\t$s1,4($sp)\n\t\t\tsw\t\t$s2,8($sp)\n\t\t\tsw\t\t$s3,12($sp)\n\n\n\t\t\tlw\t\t$s0,HEADING\t # MMIO address for heading\n\t\t\tlw\t\t$s1,WHEREX\t\t# MMIO address for x-value\n\t\t\tlw\t\t$s2,MOVE\t\t# MMIO address for move command\n\t\t\tlw\t\t$s3,LEAVETRK\t# MMIO address for leave track\n\n\nxloop:\t\tlw\t\t$t0,0($s1)\t\t# t0 = current x location\n\t\t\tbeq\t $t0,$a0,donex # \"Are we there yet?\"...\n\n\n\t\t\t# ... No. See if we have to move left or right:\n\t\t\tsw\t\t$a1,0($s3)\t\t# set \"leave track\" as specified\n\t\t\tblt\t $t0,$a0,h90 # if current < goal, move right (heading 90)\n\n\nh270:\t\t # We have to move left (heading 270):\n\t\t\tli\t\t$t0,270\t\t # store the heading (270)...\n\t\t\tsw\t\t$t0,0($s0)\t\t# ... in the appropriate MMIO address\n\t\t\tli\t\t$t0,1\t\t\t # t0 = \"true\"\n\t\t\tsw\t\t$t0,0($s2)\t\t# start moving\nbusyX1:\t lw\t\t$t0,0($s1)\t\t# Get current location\n\t\t\tble\t $t0,$a0,donex # \"Are we there yet?\"\n\t\t\tj\t\t busyX1\n\n\nh90:\t\t # We have to move right (heading 90):\n\t\t\tli\t\t$t0,90\t\t\t# store the heading (90)...\n\t\t\tsw\t\t$t0,0($s0)\t\t# ... in the appropriate MMIO address\n\t\t\tli\t\t$t0,1\t\t\t # t0 = \"true\"\n\t\t\tsw\t\t$t0,0($s2)\t\t# start moving\nbusyX2:\t lw\t\t$t0,0($s1)\t\t# Get current location\n\t\t\tbge\t $t0,$a0,donex # \"Are we there yet?\"\n\t\t\tj\t\t busyX2\n\n\ndonex:\t\tsw\t\t$zero,0($s2)\t# stop moving\n\t\t\tlw\t\t$s0,0($sp)\n\t\t\tlw\t\t$s1,4($sp)\n\t\t\tlw\t\t$s2,8($sp)\n\t\t\tlw\t\t$s3,12($sp)\n\t\t\taddi\t$sp,$sp,16\n\t\t\tjr\t\t$ra\n\n\n##################################################\nvert:\t\t# Preserve registers (just in case!)\n\t\t\taddi\t$sp,$sp,-16\n\n\n\t\t\tsw\t\t$s0,0($sp)\n\t\t\tsw\t\t$s1,4($sp)\n\t\t\tsw\t\t$s2,8($sp)\n\t\t\tsw\t\t$s3,12($sp)\n\n\n\t\t\tlw\t\t$s0,HEADING # MMIO address for heading\n\t\t\tlw\t\t$s1,WHEREY # MMIO address for y-value\n\t\t\tlw\t\t$s2,MOVE\t# MMIO address for move command\n\t\t\tlw\t\t$s3,LEAVETRK # MMIO address for leave track\n\n\nyloop:\t\tlw\t\t$t0,0($s1) # t0 = current y location\n\t\t\tbeq\t $t0,$a0,doney # \"Are we there yet?\"...\n\n\n\t\t\t# ... No. See if we have to move up or down:\n\t\t\tsw\t\t$a1,0($s3)\t\t# set \"leave track\" as specified\n\t\t\tblt\t $t0,$a0,h180 # if current < goal, move down (heading 180)\nh0:\t\t # We have to move up (heading 0):\n\t\t\tli\t\t$t0,0\t# store the heading (0)...\n\t\t\tsw\t\t$t0,0($s0) # ... in the appropriate MMIO address\n\t\t\tli\t\t$t0,1\t\t# t0 = \"true\"\n\t\t\tsw\t\t$t0,0($s2) # start moving\nbusyY1:\t lw\t\t$t0,0($s1) # Get current location\n\t\t\tble\t $t0,$a0,doney # \"Are we there yet?\"\n\t\t\tj\t\t busyY1\nh180:\t\t # We have to move down (heading 180):\n\t\t\tli\t\t$t0,180\t# store the heading (180)...\n\t\t\tsw\t\t$t0,0($s0) # ... in the appropriate MMIO address\n\t\t\tli\t\t$t0,1\t\t# t0 = \"true\"\n\t\t\tsw\t\t$t0,0($s2) # start moving\nbusyY2:\t lw\t\t$t0,0($s1) # Get current location\n\t\t\tbge\t $t0,$a0,doney # \"Are we there yet?\"\n\t\t\tj\t\t busyY2\ndoney:\t\tsw\t\t$zero,0($s2) # stop moving\n\t\t\tlw\t\t$s0,0($sp)\n\t\t\tlw\t\t$s1,4($sp)\n\t\t\tlw\t\t$s2,8($sp)\n\t\t\tlw\t\t$s3,12($sp)\n\t\t\taddi\t$sp,$sp,16\n\t\t\tjr\t\t$ra"
/*
* Represents a cartesian point with x- and y-coordinates.
*/
typedef struct pointType {
int x; // the point's x-value
int y; // the point's y-value
} pointType;
typedef enum identityType {
RMOVETO,
RLINETO,
MOVETO,
LINETO
} identityType;
typedef struct statementType {
int x;
int y;
identityType identity;
} statementType;
int lineCount (FILE *target);
void fileCopy(FILE *source, FILE *target);
FILE* sourceIO (int argc, char *argv[]);
FILE* destIO (int argc, char *argv[]);
rmoveto (50,50)
lineto (100,100)
rmoveto (50,50)
rlineto (100,250)
#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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment