This document is written in GitHub-flavored markdown. You may view the visualized version here.
##Overview I've done the following items in this assignment:
- Modify
assignment1.landassignment2.yto generate the assembly code oftest1.c. - Modify the symbol table structure.
- Fix the issue in the previous assignment that the program will not terminate after the file is read.
##Testing Data
This is the modified version of test1.c:
int main(){
int a = 3;
int b = 4;
int c = 5;
int d = 0;
int i;
i = a + b + 3 + 6;
int j;
int k;
a = i + j + k + 3;
printf("a = %d\n", a);
}Which avoids errors of the code provided in the slides (contains undeclared variables).
##Code Generation
By observing the behaviours of the assignment2.l,
I came up with the following schemes:
###Modify Symbol Table Structure
/* symbol_table.c */
#define MAX_ENTRY 1000
struct symbol
{
char id[32];
double value;
// store the offset of the variable for code generation
int offset;
};
struct symbol symbolTable[MAX_ENTRY];###Insert Code For simple variable declarations:
int a;
int b = 10;I use the following code to generate the assembly codes:
fprintf(fp, "\tmovi\t$r0, %d\n", 0);
fprintf(fp, "\tswi\t$r0, [$fp+(%d)]\n", offset);which will generate something like this:
movi $r0, 13
swi $r0, [$fp+(20)]
And for the addition and assign expression:
int i;
i = a + b;the assembly codes will be generated
for values of a and b once the statement is reduced to ID.
ID {
int i = 0, declared = 0;
for(i=0; i<MAX_ENTRY; i++){
if(strcmp(symbolTable[i].id, $1->id)==0){
$$ = symbolTable[i].value; //update value
declared = 1;
fprintf(fp, "\tlwi\t$r%d, [$fp+(%d)]\n", reg, symbolTable[i].offset);
reg++;
break;
}
}this will generate
lwi $3, [$fp+(24)]
the reg++ will automatically update the #registers,
so the next time when the statement is reduced to ID,
we will load the value to another register.
When a constant value is parse, it will reduced to INT,
the code must be generated there:
INT {
$$ = $1;
printf("Reduce to factor from INT:%d\n", $1);
if(reg!=0){
fprintf(fp,"\taddi\t$r0, $r0, %d\n", $1);
}
}will generate something like:
addi $r0, $r0, 10
Finally, when the statement is done, we store the value back to the memory.
ID '=' element ';' {
int i=0, declared = 0;
for(i=0; i<MAX_ENTRY; i++){
if(strcmp(symbolTable[i].id, $1->id)==0){ //symbol already exists
declared = 1;
$$ = $3;
symbolTable[i].value = $3; //update value
fprintf(fp, "\tswi\t$r0, [$fp+(%d)]\n", symbolTable[i].offset);
reg=0;
break;
}
}
}which will generate:
swi $r0, [$fp+(16)]
There are still some code patterns unlisted,
you may check it in the assignment2.l.
##Implementation obstacles
It's quite hard to track the data
flow in the hardware level.
However,
I've written a similar parser like this
in the course Computer Architecture offered by
Ren-Song Tsay.
This helped a lot to finish this assignment.
##Known Bugs
I didn't test anything else except for test1.c,
so I don't know if there's a bug or not.
##Anything worth to be mentioned Please let me pass the course, I want my B.S. degree, QQ!