Merge pull request #56 from UB-CSE443/DontBreakDev

Dont break dev
This commit is contained in:
Annie Slenker
2025-05-02 16:27:10 -04:00
committed by GitHub
20 changed files with 1311 additions and 733 deletions

View File

@ -3,8 +3,9 @@ CC := gcc
FLEX := flex FLEX := flex
BISON = bison BISON = bison
CFLAGS := -ggdb CFLAGS := -ggdb -g -O0 #-fsanitize=address
BISONFLAGS := -d # LDFLAGS := -fsanitize=address
BISONFLAGS := -d -Wcounterexamples
LEX := src/lexicalStructure.lex LEX := src/lexicalStructure.lex
YACC := src/grammar.y YACC := src/grammar.y
@ -24,7 +25,7 @@ TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha)
all: compiler all: compiler
compiler: clean tmp $(OBJS) compiler: clean tmp $(OBJS)
$(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(LDFLAGS)
clean: clean:
rm -f $(EXE) rm -f $(EXE)

View File

@ -47,7 +47,7 @@ int generate(){
break; break;
case E_IF_X_TRUE: case E_IF_X_TRUE:
generateIfTrue(i); generateIfTrue(i);
break; break;
case E_IF_X_FALSE: case E_IF_X_FALSE:
generateIfFalse(i); generateIfFalse(i);
break; break;
@ -148,7 +148,7 @@ int generateAdd(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateAdd failed, NULL operand"); printdebug("generateAdd failed, NULL operand");
return -1; return -1;
@ -157,8 +157,8 @@ int generateAdd(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -186,7 +186,7 @@ int generateSub(Instruction *instruction) {
TNodeOrConst *op1 = getOperand1(instruction); TNodeOrConst *op1 = getOperand1(instruction);
TNodeOrConst *op2 = getOperand2(instruction); TNodeOrConst *op2 = getOperand2(instruction);
CGNode *cg = findCG(getResult(instruction)); CGNode *cg = findCG(getResult(instruction));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateSub failed, NULL operand"); printdebug("generateSub failed, NULL operand");
return -1; return -1;
@ -195,7 +195,7 @@ int generateSub(Instruction *instruction) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(instruction), offset); cg = addCG(getResult(instruction), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -223,7 +223,7 @@ int generateMult(Instruction *inst){
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateMult failed, NULL operand"); printdebug("generateMult failed, NULL operand");
return -1; return -1;
@ -259,7 +259,7 @@ int generateDiv(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateDiv failed, NULL operand"); printdebug("generateDiv failed, NULL operand");
return -1; return -1;
@ -268,7 +268,7 @@ int generateDiv(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -284,7 +284,7 @@ int generateDiv(Instruction *inst) {
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\n", getAddress(op1CG)); //moves dividend into eax
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result
return 0; return 0;
} }
@ -297,7 +297,7 @@ int generateMod(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateMod failed, NULL operand"); printdebug("generateMod failed, NULL operand");
return -1; return -1;
@ -312,12 +312,12 @@ int generateMod(Instruction *inst) {
printdebug("generateMod failed, op1 is not constant but not in CGlist"); printdebug("generateMod failed, op1 is not constant but not in CGlist");
return -1; return -1;
} }
if (op2CG == NULL) { if (op2CG == NULL) {
printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1; return -1;
} }
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\n", getAddress(op1CG)); //moves dividend into eax
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack
@ -334,7 +334,7 @@ int generateOr(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("generateOr failed, NULL operand"); printdebug("generateOr failed, NULL operand");
return -1; return -1;
@ -343,7 +343,7 @@ int generateOr(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -358,22 +358,22 @@ int generateOr(Instruction *inst) {
int label = label_gen(); int label = label_gen();
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG));
fprintf(cg_flag, "\tjne\t.L%dor2\n", label); fprintf(cg_flag, "\tjne\t.L%dor2\n", label);
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
fprintf(cg_flag, "\tje\t.L%dor3\n", label); fprintf(cg_flag, "\tje\t.L%dor3\n", label);
fprintf(cg_flag, ".L%dor2:\n", label); fprintf(cg_flag, ".L%dor2:\n", label);
fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
fprintf(cg_flag, "\tjmp\t.L%dor4\n", label); fprintf(cg_flag, "\tjmp\t.L%dor4\n", label);
fprintf(cg_flag, ".L%dor3:\n", label); fprintf(cg_flag, ".L%dor3:\n", label);
fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
fprintf(cg_flag, ".L%dor4:\n", label); fprintf(cg_flag, ".L%dor4:\n", label);
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result
return 0; return 0;
} }
@ -386,7 +386,7 @@ int generateAnd(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED);
return -1; return -1;
@ -395,7 +395,7 @@ int generateAnd(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -409,27 +409,27 @@ int generateAnd(Instruction *inst) {
} }
int label = label_gen(); int label = label_gen();
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG));
fprintf(cg_flag, "\tje\t.L%dor2\n", label); fprintf(cg_flag, "\tje\t.L%dor2\n", label);
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
fprintf(cg_flag, "\tje\t.L%dor2\n", label); fprintf(cg_flag, "\tje\t.L%dor2\n", label);
fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
fprintf(cg_flag, "\tjmp\t.L%dor3\n", label); fprintf(cg_flag, "\tjmp\t.L%dor3\n", label);
fprintf(cg_flag, ".L%dor2:\n", label); fprintf(cg_flag, ".L%dor2:\n", label);
fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
fprintf(cg_flag, ".L%dor3:\n", label); fprintf(cg_flag, ".L%dor3:\n", label);
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result
return 0; return 0;
} }
int generateNeg(Instruction *inst) { int generateNeg(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) { if (op1 == NULL) {
printdebug("generateNeg failed, NULL operand"); printdebug("generateNeg failed, NULL operand");
return -1; return -1;
@ -438,14 +438,14 @@ int generateNeg(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) { if (op1CG == NULL) {
printdebug("generateNeg failed, op1 is not constant but not in CGlist"); printdebug("generateNeg failed, op1 is not constant but not in CGlist");
return -1; return -1;
} }
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG));
fprintf(cg_flag, "\tnegl\t%%eax\n"); fprintf(cg_flag, "\tnegl\t%%eax\n");
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg));
return 0; return 0;
@ -453,7 +453,7 @@ int generateNeg(Instruction *inst) {
int generateNot(Instruction *inst) { int generateNot(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) { if (op1 == NULL) {
printdebug("generateNot failed, NULL operand"); printdebug("generateNot failed, NULL operand");
return -1; return -1;
@ -462,7 +462,7 @@ int generateNot(Instruction *inst) {
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) { if (op1CG == NULL) {
printdebug("generateNot failed, op1 is not constant but not in CGlist"); printdebug("generateNot failed, op1 is not constant but not in CGlist");
@ -483,7 +483,7 @@ int generateAssign(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) { if (op1 == NULL) {
printdebug("generateAssign failed, NULL operand"); printdebug("generateAssign failed, NULL operand");
return -1; return -1;
@ -499,15 +499,14 @@ int generateAssign(Instruction *inst) {
fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg)); fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg));
return 0; return 0;
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) { if (op1CG == NULL) {
printf("failed here\n");
printdebug("generateAssign failed, op1 is not constant but not in CGlist"); printdebug("generateAssign failed, op1 is not constant but not in CGlist");
return -1; return -1;
} }
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg)); fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg));
return 0; return 0;
} }
@ -538,7 +537,7 @@ int generateLessThan(Instruction *inst){
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1; return -1;
@ -547,7 +546,7 @@ int generateLessThan(Instruction *inst){
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -560,7 +559,7 @@ int generateLessThan(Instruction *inst){
return -1; return -1;
} }
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG));
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tsetl\t%%al\n"); fprintf(cg_flag, "\tsetl\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg));
@ -576,7 +575,7 @@ int generateEqualTo(Instruction *inst){
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst); TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst)); CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) { if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1; return -1;
@ -585,7 +584,7 @@ int generateEqualTo(Instruction *inst){
if (cg == NULL) { if (cg == NULL) {
cg = addCG(getResult(inst), offset); cg = addCG(getResult(inst), offset);
} }
CGNode *op1CG = findCG(getTN(op1)); CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2)); CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) { if (op1CG == NULL) {
@ -598,7 +597,7 @@ int generateEqualTo(Instruction *inst){
return -1; return -1;
} }
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG)); fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG));
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tsete\t%%al\n"); fprintf(cg_flag, "\tsete\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg));
@ -648,6 +647,7 @@ int generateCopyLeft(Instruction *inst){
int generateAddressOf(Instruction *inst){ int generateAddressOf(Instruction *inst){
return -1; return -1;
} }
int generateParam(Instruction *inst){ int generateParam(Instruction *inst){
TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op1 = getOperand1(inst);
@ -686,5 +686,4 @@ int generateFunctionStart(Instruction *inst) {
fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n");
return 0; return 0;
} }

View File

@ -29,4 +29,8 @@ Instruction *current;
int offset; int offset;
int currentsp; int currentsp;
CGNode *cgList; CGNode *cgList;
Stack* stack;
Stack* TrueList;
Stack* FalseList;

File diff suppressed because it is too large Load Diff

View File

@ -3,398 +3,618 @@
#include "intermediate_code.h" #include "intermediate_code.h"
// TODO: this is here to bring your attention to the comment bellow. Stack * S_Init(){
// check if start is NULL if it is assign it to the start globle variable Stack * s = calloc(1, sizeof(*s));
// otherwise make it next of current and set cur to your instruction. return s;
TNodeOrConst* getOperand1(Instruction* i) {
return i->operand1;
} }
TNodeOrConst* getOperand2(Instruction* i) { void S_Free(Stack *s){
return i->operand2; // since we are not responsible for the values we can just pop until
// NULL
for (void * p = S_Pop(s); p != NULL; p = S_Pop(s));
free(s);
} }
TableNode* getResult(Instruction* i) { void S_Push(Stack * s, void *v, int i) {
return i->result; __Node * n = calloc(1, sizeof(*n));
n->v = v;
n->next = s->n;
s->n = n;
s->w = i;
s->size = s->size + 1;
} }
Op getOp(Instruction* i) { void * S_Pop(Stack *s) {
return i->opcode; if (s == NULL || S_IsEmpty(s)) {
} return NULL;
int getLabel(Instruction* i) {
return i->label;
}
int get_index(Instruction* i) {
return i->index;
}
void set_label(Instruction* i, int label) {
i->label = label;
}
bool isConst(TNodeOrConst* tnc) {
return tnc->d != NODE;
}
TNodeOrConst* tn_or_const(Discriminant d, void* tnc) {
TNodeOrConst* count = calloc(1, sizeof(*count));
count->d = d;
count->tnc_union = calloc(1, sizeof(*count->tnc_union));
switch (d) {
case NODE:
count->tnc_union->node = tnc;
break;
case ADDRESS:
count->tnc_union->address = tnc;
break;
case STRING:
count->tnc_union->string = tnc;
break;
case INTEGER:
count->tnc_union->integer = *(int*)tnc;
break;
case CHARACTER:
count->tnc_union->character = *(char*)tnc;
break;
case BOOLEAN:
count->tnc_union->Boolean = *(uint_least8_t*)tnc;
break;
} }
return count; __Node * node = s->n;
s->n = node->next;
s->size = s->size - 1;
void * r = node->v;
free(node);
return r;
} }
static void emit_helper(void) {
Instruction* inst = calloc(1, sizeof(*inst)); void * S_Peek(Stack *s){
if (begin == NULL) { if (s == NULL || S_IsEmpty(s)) {
begin = current = inst; return NULL;
current->index = 1;
} else {
current->next = inst;
inst->prev = current;
inst->index = current->index + 1;
current = inst;
} }
return s->n->v;
} }
void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2) { bool S_IsEmpty(Stack *s){
emit_helper(); if(s == NULL || s->size == 0) {
current->opcode = op; return true;
// TODO: create temp and remove result from param list
current->result = result;
current->operand1 = arg1;
current->operand2 = arg2;
}
void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg) {
emit_helper();
current->opcode = op;
current->result = result;
current->operand1 = arg;
}
void emit_assignment(TableNode* target, TNodeOrConst* source) {
emit_helper();
current->opcode = E_ASSIGN;
current->result = target;
current->operand1 = source;
}
char* get_string(TNodeOrConst* tc) {
char* s;
switch (tc->d) {
case NODE:
return getName(tc->tnc_union->node);
case ADDRESS:
return strdup("null");
case STRING:
return tc->tnc_union->string;
case INTEGER:
s = calloc(10, sizeof(char));
sprintf(s, "%d", tc->tnc_union->integer);
return s;
case CHARACTER:
s = calloc(2, sizeof(char));
sprintf(s, "%c", tc->tnc_union->character);
return s;
case BOOLEAN:
if (tc->tnc_union->Boolean) {
return strdup("true");
}
return strdup("false");
} }
return false;
} }
void emit_as_file(FILE* out_file, Instruction* i) { int S_Size(Stack *s){
if (i == NULL) { if (s == NULL || S_IsEmpty(s)) {
return; return 0;
} }
switch (i->opcode) { return s->size;
case E_LABEL:
break;
// this is a terrible one to start with
// fprintf(out_file, "%04.d: %d ", i->index, i->label);
case E_ADD:
fprintf(out_file, "%4.d: %s = %s + %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_SUB:
fprintf(out_file, "%4.d: %s = %s - %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_MUL:
fprintf(out_file, "%4.d: %s = %s * %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_DIV:
fprintf(out_file, "%4.d: %s = %s / %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_MOD:
fprintf(out_file, "%4.d: %s = %s %% %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_OR:
fprintf(out_file, "%4.d: %s = %s | %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_AND:
fprintf(out_file, "%4.d: %s = %s & %s\n",
i->index, getName(i->result),
get_string(i->operand1),
get_string(i->operand2));
break;
case E_NEG:
fprintf(out_file, "%4.d: %s = -%s\n",
i->index, getName(i->result),
get_string(i->operand1));
break;
case E_NOT:
fprintf(out_file, "%4.d: %s = !%s\n",
i->index, getName(i->result),
get_string(i->operand1));
break;
case E_ASSIGN:
fprintf(out_file, "%4.d: %s = %s\n",
i->index, getName(i->result),
get_string(i->operand1));
break;
case E_GOTO:
// are we ever going to use this?
// yes we do look at bounds checking
case E_IF_X_TRUE:
fprintf(out_file, "%4.d: if %s goto %d\n",
i->index, get_string(i->operand1),
i->label);
break;
case E_IF_X_FALSE:
fprintf(out_file, "%4.d: if %s false goto %d\n",
i->index, get_string(i->operand1),
i->label);
break;
case E_LESS_THAN:
fprintf(out_file, "%4.d: if %s < %s goto %d\n",
i->index, get_string(i->operand1),
get_string(i->operand2), i->label);
break;
case E_EQUAL_TO:
fprintf(out_file, "%4.d: if %s = %s goto %d\n",
i->index, get_string(i->operand1),
get_string(i->operand2), i->label);
break;
case E_CALL:
fprintf(out_file, "%4.d: call %s %s\n",
i->index, get_string(i->operand1),
get_string(i->operand2));
break;
case E_PARAM:
fprintf(out_file, "%4.d: param %s \n",
i->index, get_string(i->operand1));
break;
case E_RETURN:
case E_INDEX_COPY_RIGHT:
case E_INDEX_COPY_LEFT:
case E_ADDRESS_OF:
case E_DEREF_RIGHT:
case E_DEREF_LEFT:
}
emit_as_file(out_file, i->next);
} }
void emit_label(int label) { void emit_backpatch(Stack * s, int l){
emit_helper(); for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){
current->opcode = E_LABEL; i->label = l;
current->label = label; }
} }
//_______________________________________________________________________
void emit_jump(int label) { char * temp = NULL;
emit_helper();
current->opcode = E_GOTO;
current->label = label;
}
void emit_conditional_jump(Op condition, int label, ...) {
// when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *).
// when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *)
emit_helper();
va_list argptr;
va_start(argptr, label);
current->opcode = condition;
current->label = label;
TNodeOrConst* n1;
TNodeOrConst* n2;
switch (condition) {
case E_IF_X_TRUE:
case E_IF_X_FALSE:
n1 = va_arg(argptr, TNodeOrConst*);
current->operand1 = n1;
break;
case E_LESS_THAN:
case E_EQUAL_TO:
n1 = va_arg(argptr, TNodeOrConst*);
n2 = va_arg(argptr, TNodeOrConst*);
current->operand1 = n1;
current->operand2 = n2;
break;
}
va_end(argptr);
}
void emit_function_start(TNodeOrConst * name) { /*
emit_helper(); TODO: this is here to bring your attention to the comment bellow.
current->opcode = E_LABEL; // I think this is right TODO: ask check if start is NULL if it is assign it to the start globle variable
current->operand1 = name; otherwise make it next of current and set cur to your instruction.
// this is probabaly a func declaration
}
void emit_parameter(TNodeOrConst* param) {
emit_helper();
current->opcode = E_PARAM;
current->operand1 = param;
}
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name) {
emit_helper();
current->opcode = E_CALL;
current->operand1 = tn_or_const(INTEGER, &param_count);
current->operand2 = name;
current->result = result;
}
void emit_return(TNodeOrConst* value) {
emit_helper();
current->opcode = E_RETURN;
current->operand1 = value;
}
void emit_reserve(TableNode* result, TNodeOrConst* size) {
emit_parameter(size);
emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve")));
}
void emit_release(TableNode* pointer) {
emit_parameter(tn_or_const(NODE, pointer));
emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release")));
}
void emit_deref_right() {
return;
}
void emit_deref_left() {
return;
}
void emit_field_access(char* result, char* record, char* field) {
emit_helper();
}
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index) {
emit_helper();
current->opcode;
current->result = result;
current->operand1 = array;
current->operand2 = index;
// TODO: Still don't know what to do with the dimentions
}
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr) {
/*
{[string: 5]
.
.
s:= reserve s(5);
s(0) := 'H';
s(1) := 'e';
.
.
s._0 num of dims Known at compile time
s._1 size Known at run time
s._1 int | 1 byte
+-------+---+---+---+---+---+
| 5 | H | e | l | l | o |
+-------+---+---+---+---+---+
size
^
|
p
s._0 ok
s._1 ok
s._2 not ok
t_0 is index
t_1 = *(int *)p = s._1
if t_0 < 0 GOTO ERROR
if t_0 < s._1 GOTO access array
GOTO ERROR
*/ */
//emit_conditional_jump(E_LESS_THAN, );
//emit_conditional_jump(E_LESS_THAN, ); void emit_push_all(Stack * s){
//emit_jump(); for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){
/* We need a label ERROR to jump to current->next = i;
*/ i->prev = current;
i->index = current->index + 1;
current = i;
current->next = NULL;
}
} }
/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) void emit_detach(){
char * temp_var_gen(){ current = current->prev;
char * ret = calloc(9, sizeof(*ret)); current->next = NULL;
sprintf(ret, "$t%d", temp_count);
temp_count++;
return ret;
} }
*/
void backpatch(Stack *s, int l){
while (!S_IsEmpty(s)){
Instruction * i = S_Pop(s);
set_label(i, l);
}
}
TNodeOrConst * getOperand1(Instruction * i){
return i->operand1;
}
TNodeOrConst * getOperand2(Instruction * i){
return i->operand2;
}
TableNode * getResult(Instruction * i){
return i->result;
}
Op getOp(Instruction * i){
return i->opcode;
}
int getLabel(Instruction * i){
return i->label;
}
int get_index(Instruction * i){
return i->index;
}
void set_label(Instruction * i, int label){
i->label = label;
}
bool isConst(TNodeOrConst * tnc) {
return tnc->d != NODE;
}
TNodeOrConst * tn_or_const(Discriminant d, void * tnc) {
TNodeOrConst * count = calloc(1, sizeof(*count));
count->d = d;
count->tnc_union = calloc(1, sizeof(*count->tnc_union));
switch (d) {
case NODE:
count->tnc_union->node = tnc;
break;
case ADDRESS:
count->tnc_union->address = tnc;
break;
case STRING:
count->tnc_union->string = tnc;
break;
case INTEGER:
count->tnc_union->integer = *(int*)tnc;
break;
case CHARACTER:
count->tnc_union->character = *(char*)tnc;
break;
case BOOLEAN:
count->tnc_union->Boolean = *(uint_least8_t*)tnc;
break;
}
return count;
}
static void emit_helper(void){
Instruction * inst = calloc(1, sizeof(*inst));
if(begin == NULL){
begin = current = inst;
current->index = 1;
} else {
current->next = inst;
inst->prev = current;
inst->index = current->index + 1;
current = inst;
}
}
void emit_binary_op(
Op op,
TableNode * result,
TNodeOrConst * arg1,
TNodeOrConst * arg2
){
emit_helper();
current->opcode = op;
// TODO: create temp and remove result from param list
current->result = result;
current->operand1 = arg1;
current->operand2 = arg2;
}
void emit_goto(int i){
emit_helper();
current->opcode = E_GOTO;
current->label = i;
}
void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){
emit_helper();
current->opcode = op;
current->result = result;
current->operand1 = arg;
}
void emit_assignment(TableNode * target, TNodeOrConst * source){
emit_helper();
current->opcode = E_ASSIGN;
current->result = target;
current->operand1 = source;
}
char * get_string(TNodeOrConst * tc){
char * s;
switch (tc->d) {
case NODE:
return getName(tc->tnc_union->node);
case ADDRESS:
return strdup("null");
case STRING:
return tc->tnc_union->string;
case INTEGER:
s = calloc(10, sizeof(char));
sprintf(s, "%d", tc->tnc_union->integer);
return s;
case CHARACTER:
s = calloc(2, sizeof(char));
sprintf(s, "%c", tc->tnc_union->character);
return s;
case BOOLEAN:
if(tc->tnc_union->Boolean){
return strdup("true");
}
return strdup("false");
}
}
void emit_label(int label){
emit_helper();
current->opcode = E_LABEL;
current->label = label;
}
void emit_jump(int label){
emit_helper();
current->opcode = E_GOTO;
current->label = label;
}
void emit_conditional_jump(Op condition, int label, ...){
// when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *).
// when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *)
emit_helper();
va_list argptr;
va_start(argptr, label);
current->opcode = condition;
current->label = label;
TNodeOrConst * n1;
TNodeOrConst * n2;
switch (condition) {
case E_IF_X_TRUE: case E_IF_X_FALSE:
n1 = va_arg(argptr, TNodeOrConst *);
current->operand1 = n1;
break;
case E_LESS_THAN: case E_EQUAL_TO:
n1 = va_arg(argptr, TNodeOrConst *);
n2 = va_arg(argptr, TNodeOrConst *);
current->operand1 = n1;
current->operand2 = n2;
break;
}
va_end(argptr);
}
void emit_function_start(TableNode * name){
emit_helper();
current->opcode = E_FUNC_START;
current->result = name;
}
void emit_parameter(TNodeOrConst * param){
emit_helper();
current->opcode = E_PARAM;
current->operand1 = param;
}
void emit_function_call(
TableNode * result,
int param_count,
TNodeOrConst * name
){
emit_helper();
current->opcode = E_CALL;
current->operand1 = name;
current->operand2 = tn_or_const(INTEGER, &param_count);
current->result = result;
}
void emit_return(TNodeOrConst * value){
emit_helper();
current->opcode = E_RETURN;
current->operand1 = value;
}
void emit_reserve(TableNode * result, TNodeOrConst * size){
emit_parameter(size);
emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve")));
}
void emit_release(TableNode * pointer){
emit_parameter(tn_or_const(NODE, pointer));
emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release")));
}
void emit_deref_right(TableNode * x, TNodeOrConst * y){
emit_helper();
current->opcode = E_DEREF_RIGHT;
current->result = x;
current->operand1 = y;
}
void emit_deref_left(TableNode * x, TNodeOrConst * y){
emit_helper();
current->opcode = E_DEREF_LEFT;
current->result = x;
current->operand1 = y;
}
void emit_address_of(TableNode * x, TNodeOrConst * y){
emit_helper();
current->opcode = E_ADDRESS_OF;
current->result = x;
current->operand1 = y;
}
void emit_field_access(char* result, char* record, char* field){
emit_helper();
}
void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){
emit_helper();
current->opcode = op;
current->result = result;
current->operand1 = array;
current->operand2 = index;
// TODO: Still don't know what to do with the dimentions
}
void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){
/*
{[string: 5]
.
.
s:= reserve s(5);
s(0) := 'H';
s(1) := 'e';
.
.
s._0 num of dims Known at compile time
s._1 size Known at run time
s._1 int | 1 byte
+-------+---+---+---+---+---+
| 5 | H | e | l | l | o |
+-------+---+---+---+---+---+
size
^
|
p
s._0 ok
s._1 ok
s._2 not ok
t_0 is index
t_1 = *(int *)p = s._1
if t_0 < 0 GOTO ERROR
if t_0 < s._1 GOTO access array
GOTO ERROR
*/
/* We need a label ERROR to jump to
emit_conditional_jump(E_LESS_THAN, );
emit_conditional_jump(E_LESS_THAN, );
emit_jump();
*/
}
// * Implement temp variable generator function that produces unique names (t1, t2, etc.)
int label_gen(){ int label_gen(){
label_count++; label_count++;
return label_count; return label_count;
} }
void emit_as_file(FILE * out_file, Instruction * i){
if (out_file == NULL){
fprintf(stderr, "Error: output file is NULL\n");
return;
}
if(i == NULL){
return;
}
switch(i->opcode){
case E_FUNC_START:
fprintf(out_file,
"%4.d: func : %s\n",
i->index,
getName(i->result)
);
break;
case E_LABEL:
fprintf(out_file,
"%4.d: Label : %d\n",
i->index,
i->label
);
break;
case E_ADD:
fprintf(out_file,
"%4.d: %s = %s + %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_SUB:
fprintf(out_file,
"%4.d: %s = %s - %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_MUL:
fprintf(out_file,
"%4.d: %s = %s * %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_DIV:
fprintf(out_file,
"%4.d: %s = %s / %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_MOD:
fprintf(out_file,
"%4.d: %s = %s %% %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_OR:
fprintf(out_file,
"%4.d: %s = %s | %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_AND:
fprintf(out_file,
"%4.d: %s = %s & %s\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_NEG:
fprintf(out_file,
"%4.d: %s = -%s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
break;
case E_NOT:
fprintf(out_file,
"%4.d: %s = !%s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
break;
case E_ASSIGN:
fprintf(out_file,
"%4.d: %s = %s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
break;
case E_GOTO:
fprintf(out_file,
"%4.d: GOTO : %d\n",
i->index,
i->label
);
break;
case E_IF_X_TRUE:
fprintf(out_file,
"%4.d: if %s GOTO %d\n",
i->index,
get_string(i->operand1),
i->label
);
break;
case E_IF_X_FALSE:
fprintf(out_file,
"%4.d: if %s false GOTO %d\n",
i->index,
get_string(i->operand1),
i->label
);
break;
case E_LESS_THAN:
// this feels wrong I need to TODO: this
fprintf(out_file,
"%4.d: if ( %s < %s ) GOTO %d\n",
i->index,
get_string(i->operand1),
get_string(i->operand2),
i->label
);
break;
case E_EQUAL_TO:
// this feels wrong I need to TODO: this
fprintf(out_file,
"%4.d: if ( %s = %s ) GOTO %d\n",
i->index,
get_string(i->operand1),
get_string(i->operand2),
i->label
);
break;
case E_CALL:
fprintf(out_file,
"%4.d: call : %s %s\n",
i->index,
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_PARAM:
fprintf(out_file,
"%4.d: param %s \n",
i->index,
get_string(i->operand1)
);
break;
case E_RETURN:
fprintf(out_file,
"%4.d: return : %s\n",
i->index,
get_string(i->operand1)
);
break;
case E_INDEX_COPY_RIGHT:
fprintf(out_file,
"%4.d: %s = %s[ %s ]\n",
i->index,
getName(i->result),
get_string(i->operand1),
get_string(i->operand2)
);
break;
case E_INDEX_COPY_LEFT:
fprintf(out_file,
"%4.d: %s[ %s ] = %s\n",
i->index,
getName(i->result),
get_string(i->operand2),
get_string(i->operand1));
break;
case E_ADDRESS_OF:
fprintf(out_file,
"%4.d: %s = &%s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
break;
case E_DEREF_RIGHT:
fprintf(out_file,
"%4.d: %s = *%s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
case E_DEREF_LEFT:
fprintf(out_file,
"%4.d: *%s = %s\n",
i->index,
getName(i->result),
get_string(i->operand1)
);
}
emit_as_file(out_file, i->next);
}
TableNode* getTN(TNodeOrConst* tnc) { TableNode* getTN(TNodeOrConst* tnc) {
if (tnc->d == NODE) { if (tnc->d == NODE) {
return tnc->tnc_union->node; return tnc->tnc_union->node;
} }
return NULL; return NULL;
} }
int getConst(TNodeOrConst* tnc) { int getConst(TNodeOrConst* tnc) {
if (tnc->d == INTEGER) { if (tnc->d == INTEGER) {
return tnc->tnc_union->integer; return tnc->tnc_union->integer;
} }
return -1; return -1;
} }

View File

@ -12,7 +12,35 @@
#include "symbol_table.h" #include "symbol_table.h"
typedef struct Stack Stack;
typedef struct __Node __Node;
typedef struct __Node {
void * v;
__Node * next;
} __Node;
typedef struct Stack {
__Node * n;
int w;
int size;
} Stack;
Stack * S_Init();
void S_Free(Stack *s);
void S_Push(Stack * s, void *v, int i);
void * S_Pop(Stack *s);
void * S_Peek(Stack *s);
bool S_IsEmpty(Stack *s);
int S_Size(Stack *s);
//______________________________________________________________________________________________
typedef union TNConstUnion TNConstUnion;
typedef struct Instruction Instruction;
typedef struct TNodeOrConst TNodeOrConst;
// these are from page 364 // these are from page 364
typedef enum { // these are from page 364 typedef enum { // these are from page 364
E_LABEL = 10000, // this is not in the book E_LABEL = 10000, // this is not in the book
E_FUNC_START, E_FUNC_START,
@ -43,83 +71,104 @@ typedef enum { // these are from page 364
} Op; } Op;
typedef enum { typedef enum {
NODE = 11000, // TableNode NODE = 11000, // TableNode
INTEGER, // int INTEGER, // int
STRING, // char * STRING, // char *
CHARACTER, // char CHARACTER, // char
ADDRESS, // void * ADDRESS, // void *
BOOLEAN // bool BOOLEAN // bool
} Discriminant; } Discriminant;
typedef union { typedef union TNConstUnion {
TableNode* node; TableNode * node;
int integer; int integer;
char* string; char * string;
char character; char character;
void* address; void * address;
bool Boolean; bool Boolean;
} TNConstUnion; } TNConstUnion;
typedef struct { typedef struct TNodeOrConst {
Discriminant d; Discriminant d;
TNConstUnion* tnc_union; TNConstUnion * tnc_union;
} TNodeOrConst; } TNodeOrConst;
typedef struct Instruction Instruction;
typedef struct Instruction { typedef struct Instruction {
Op opcode; Op opcode;
TableNode* result; TableNode * result;
TNodeOrConst* operand1; TNodeOrConst * operand1;
TNodeOrConst* operand2; TNodeOrConst * operand2;
int label; int label;
int index; int index;
Instruction* prev; Instruction * prev;
Instruction* next; Instruction * next;
} Instruction; } Instruction;
// NOTE We are not using this We are using the Stack api
typedef struct TFList { typedef struct TFList {
Instruction* i; Instruction * i;
TFList* next; TFList * next;
} TFList; } TFList;
TNodeOrConst* getOperand1(Instruction* i); // TFList * make_list(Instruction * i);
TNodeOrConst* getOperand2(Instruction* i); // - makelist(i) function to create instruction lists
TableNode* getResult(Instruction* i); // void merge(TFList * l1, TFList * l2);
Op getOp(Instruction* i); // - merge(p1,p2) function to concatenate lists
int getLabel(Instruction* i); // void backpatch(TFList * l, int label);
int get_index(Instruction* i); // - backpatch(p,i) function to fill in jump targets
void set_label(Instruction* i, int label); // void bp_temp(int n);
bool isConst(TNodeOrConst* tnc);
TNodeOrConst* tn_or_const(Discriminant d, void* tnc);
static void emit_helper(void); extern Instruction * begin;
void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2); extern Instruction * current;
void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg); extern int label_count;
void emit_assignment(TableNode* target, TNodeOrConst* source); extern bool code_gen;
char* get_string(TNodeOrConst* tc); extern FILE * ir_flag;
void emit_as_file(FILE* out_file, Instruction* i);
TNodeOrConst * tn_or_const(Discriminant , void * );
void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2);
void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg);
void emit_assignment(TableNode * target, TNodeOrConst * source);
void emit_as_file(FILE * out_file, Instruction * instr_arr);
void emit_label(int label); void emit_label(int label);
void emit_jump(int label); void emit_jump(int label);
void emit_conditional_jump(Op condition, int label, ...); void emit_conditional_jump(Op condition, int label, ...);
void emit_function_start(TNodeOrConst * name);
void emit_parameter(TNodeOrConst* param); void emit_function_start(TableNode* name);
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name); void emit_parameter(TNodeOrConst * param);
void emit_return(TNodeOrConst* value); void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name);
void emit_reserve(TableNode* result, TNodeOrConst* size); void emit_return(TNodeOrConst * value);
void emit_release(TableNode* pointer); void emit_reserve(TableNode * result, TNodeOrConst * size);
void emit_deref_right(); void emit_release(TableNode * pointer);
void emit_deref_left();
void emit_field_access(char* result, char* record, char* field); void emit_field_access(char* result, char* record, char* field);
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index); void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index);
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr); void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr);
int label_gen(); void emit_goto(int i);
void emit_detach();
void emit_push_all(Stack * s);
int getLabel(Instruction * i);
TableNode* getTN(TNodeOrConst* tnc); TableNode* getTN(TNodeOrConst* tnc);
int getConst(TNodeOrConst* tnc); int getConst(TNodeOrConst* tnc);
extern int label_count;
extern Instruction* begin;
extern Instruction* current;
TNodeOrConst * getOperand1(Instruction * i);
TNodeOrConst * getOperand2(Instruction * i);
TableNode * getResult(Instruction * i);
Op getOp(Instruction * i);
int getLabel(Instruction * i);
int get_index(Instruction * i);
void set_label(Instruction * i, int label);
bool isConst(TNodeOrConst * tnc);
int label_gen();
void backpatch(Stack *s, int l);
void emit_backpatch(Stack *s, int l);
extern int offset; extern int offset;
extern int currentsp; extern int currentsp;
extern CGNode* cgList; extern CGNode* cgList;

View File

@ -59,7 +59,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
'{CHAR}' {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;} '{CHAR}' {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;}
\"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;} \"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;}
{COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/} {COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}
_{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,column_number,ACCESS);yylval.integ = atoi(&yytext[1])/*words = strdup("integer")*/;return ACCESS;}
"(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; } "(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; }
")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; } ")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; }
"[" { if(tok_flag != NULL) {print_tok(L_BRACKET);} incr(line_number,column_number,L_BRACKET); return L_BRACKET; } "[" { if(tok_flag != NULL) {print_tok(L_BRACKET);} incr(line_number,column_number,L_BRACKET); return L_BRACKET; }

View File

@ -103,6 +103,7 @@ int run(FILE *alpha) {
int token; int token;
top = cur = init(CreateScope(NULL, 1, 1)); top = cur = init(CreateScope(NULL, 1, 1));
// If file is not found // If file is not found
if (alpha == NULL) { if (alpha == NULL) {
fprintf(stderr, "INPUT FILE NOT FOUND\n"); fprintf(stderr, "INPUT FILE NOT FOUND\n");
@ -126,6 +127,9 @@ int run(FILE *alpha) {
fseek(alpha, 0, SEEK_SET); fseek(alpha, 0, SEEK_SET);
yyin = alpha; yyin = alpha;
stack = S_Init();
TrueList = S_Init();
FalseList = S_Init();
yyparse(); yyparse();
if (tok_flag != NULL) { if (tok_flag != NULL) {
@ -191,7 +195,7 @@ int new_file(char *arg, char *alpha) {
mkdir("./out", 0777); mkdir("./out", 0777);
char *new_basename = calloc(strlen(basename) + 5, sizeof(char)); char *new_basename = calloc(strlen(basename) + 7, sizeof(char));
strcpy(new_basename, "./out/"); strcpy(new_basename, "./out/");
strcat(new_basename, basename); strcat(new_basename, basename);
basename = new_basename; basename = new_basename;
@ -247,7 +251,7 @@ int is_alpha_file(char *alpha, int file_len) {
return 0; // is alpha file return 0; // is alpha file
} }
void insert_code_line(char * error_message, int line_number) { void insert_code_line(char *error_message, int line_number) {
CodeLine *error_line = malloc(sizeof(CodeLine)); CodeLine *error_line = malloc(sizeof(CodeLine));
error_line->line_number = line_number; error_line->line_number = line_number;
error_line->line = malloc(strlen(error_message) + 1); error_line->line = malloc(strlen(error_message) + 1);
@ -259,11 +263,14 @@ void insert_code_line(char * error_message, int line_number) {
int line = error_line->line_number; int line = error_line->line_number;
CodeLine *current = code_head; CodeLine *current = code_head;
while (current != NULL) { while (current != NULL) {
if (current->line_number == line) { if (current->line_number == line) {
CodeLine *next_code_line = current->next; if (current->is_error == false) {
current->next = error_line; CodeLine *next_code_line = current->next;
error_line->next = next_code_line; current->next = error_line;
error_line->next = next_code_line;
}
} }
current = current->next; current = current->next;
} }
@ -331,4 +338,4 @@ char *file_read_line(FILE *fp) {
str[len] = '\0'; str[len] = '\0';
return str; return str;
} }

View File

@ -70,6 +70,9 @@ TableNode *recprime;
TableNode *funtypeprime; TableNode *funtypeprime;
TableNode *undefined; TableNode *undefined;
extern Instruction *begin; extern Instruction *begin;
extern Stack* stack;
extern Stack* TrueList;
extern Stack* FalseList;
int main(int argc, char *argv[]); int main(int argc, char *argv[]);
int check_flag(char *arg, char *alpha); int check_flag(char *arg, char *alpha);
@ -108,4 +111,4 @@ CodeLine *code_head;
char *file_read_line(FILE *fp); char *file_read_line(FILE *fp);
void insert_code_line(char * error_message, int line_number); void insert_code_line(char * error_message, int line_number);
void append_code_line(CodeLine *code_line); void append_code_line(CodeLine *code_line);
void print_code_lines(); void print_code_lines();

View File

@ -5,6 +5,7 @@
Constant_Stack *head = NULL; Constant_Stack *head = NULL;
int temp2_count = 0; int temp2_count = 0;
int temp3_count = 0;
void printdebug_impl(char *file, int line, const char *format, ...) { void printdebug_impl(char *file, int line, const char *format, ...) {
if (DEBUG) { if (DEBUG) {
@ -24,6 +25,12 @@ char *temp_var_gen() {
temp2_count++; temp2_count++;
return ret; return ret;
} }
char *arg_var_gen() {
char *ret = calloc(9, sizeof(*ret));
sprintf(ret, "&%d", temp3_count);
temp3_count++;
return ret;
}
Constant_Stack *Push(TableNode *type, void *value, bool isConst) { Constant_Stack *Push(TableNode *type, void *value, bool isConst) {
if (type == NULL || type == undefined) { if (type == NULL || type == undefined) {
@ -623,6 +630,7 @@ TableNode *getReturn(TableNode *definition) {
"node has NULL additionalinfo. Invalid."); "node has NULL additionalinfo. Invalid.");
return undefined; return undefined;
} }
printdebug("function:%s with return type %s\n",getName(definition),getName(definition->additionalinfo->FunTypeAdInfo->returntype));
return definition->additionalinfo->FunTypeAdInfo->returntype; return definition->additionalinfo->FunTypeAdInfo->returntype;
} }
@ -1208,6 +1216,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) {
} }
for (; entry != NULL; entry = getNextEntry(entry)) { for (; entry != NULL; entry = getNextEntry(entry)) {
if((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL){
continue;
}
if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) {
char *arrayType = (char *)malloc(100); char *arrayType = (char *)malloc(100);
sprintf(arrayType, " %d -> %s", getNumArrDim(entry), sprintf(arrayType, " %d -> %s", getNumArrDim(entry),
@ -1286,7 +1297,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) {
if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) {
char *functiontype = (char *)malloc(100); char *functiontype = (char *)malloc(100);
sprintf(functiontype, " %s", getName(getReturn(entry))); sprintf(functiontype, " %s", getName(getTypeEntry(entry)));
if (parentScopeNum == 0) { if (parentScopeNum == 0) {
st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition"); st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition");
} else { } else {

View File

@ -15,6 +15,8 @@
#define SIZE_CHAR 1 #define SIZE_CHAR 1
#define SIZE_BOOL 1 #define SIZE_BOOL 1
extern FILE *ir_flag;
struct TableNode; struct TableNode;
typedef struct TFList TFList; typedef struct TFList TFList;
typedef struct CGNode CGNode; typedef struct CGNode CGNode;
@ -101,6 +103,7 @@ void printdebug_impl(char *file, int line, const char *format, ...);
printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__)
char *temp_var_gen(); char *temp_var_gen();
char *arg_var_gen();
Constant_Stack *Push(TableNode *type, void *value, bool isConst); Constant_Stack *Push(TableNode *type, void *value, bool isConst);
Constant_Stack *Pop(); Constant_Stack *Pop();
Constant_Stack *Print_Stack(); Constant_Stack *Print_Stack();
@ -165,6 +168,7 @@ extern int column_number;
extern FILE *yyin; extern FILE *yyin;
extern bool DEBUG; extern bool DEBUG;
extern int temp2_count; extern int temp2_count;
extern int temp3_count;
extern TableNode *funprime; extern TableNode *funprime;
extern TableNode *arrayprim; extern TableNode *arrayprim;
extern TableNode *integ; extern TableNode *integ;

View File

@ -55,3 +55,5 @@
#define RELEASE 614 #define RELEASE 614
// comments // comments
#define COMMENT 700 #define COMMENT 700
//Additional tokens
#define ACCESS 801

View File

@ -56,11 +56,11 @@ c(x) := {
entry is the first function called entry is the first function called
*) *)
entry(arg) := { entry(arg) := {
[integer: result; string2int: f; integer: temp] [integer: result; string2int: f; integer: temp; character: char]
temp := a("Hello"); temp := a("Hello");
f := b(temp); f := b(temp);
result := c(f); result := c(f);
if (d(1,2,'c')) if (d(1,2,char))
then { then {
result := 0; result := 0;
} }

View File

@ -45,9 +45,9 @@ selectionSort(data) := {
data(i) := temp; data(i) := temp;
i := i + 1; i := i + 1;
} }
return true; return true;
} }
(* Function definition (* Function definition
entry is the first function called entry is the first function called

View File

@ -0,0 +1,6 @@
type main: string -> integer
function entry: main
entry(arg) := {
return 0;
}

View File

@ -15,7 +15,6 @@ function make_list : list
make_list (a) := { make_list (a) := {
[integer:orig_a; llnode: ret; llnode: curr; llnode: temp] [integer:orig_a; llnode: ret; llnode: curr; llnode: temp]
if (a < 0 | a = 0) then { if (a < 0 | a = 0) then {
return null; return null;
} else { } else {
@ -73,8 +72,8 @@ entry (arg) := {
w := reserve w; w := reserve w;
w.x := 5; w.x := 5;
w.y := 7; w.y := 7;
result := bar1(w); (* result := bar1(w); *)
result := bar2(5,7); result := bar2(5,7);
return 0; return 0;
} }

View File

@ -0,0 +1,80 @@
type main: string -> integer
function entry: main
type rec: [integer: x; integer: y]
type T1: integer -> integer
type T2: rec -> integer
type llnode: [llnode: prev; integer: val; llnode: next]
type list: integer -> llnode
function foo : T1
function bar1 : T2
function bar2 : T2
function make_list : list
make_list (a) := {
[integer:orig_a; llnode: ret; llnode: curr; llnode: temp]
if (a < 0 | a = 0) then {
return null;
} else {
ret := reserve ret;
ret.prev := null;
ret.next := null;
ret.val := a;
while (0 < a) {
temp := reserve temp;
temp.prev := null;
temp.next := null;
temp.val := ret.val;
if (a = orig_a) then {
ret.next := temp;
temp.prev := ret;
curr := temp;
} else {
curr.next := temp;
temp.prev := curr;
curr := temp;
}
a := a - 1;
}
return ret;
}
}
foo (x) := {
return x * x;
}
bar1(a,b) := {
return a * b;
}
bar2(r,s) := {
if (r < s) then {
while (!(r < s)) {
r := r + 1;
}
} else {
[integer: x]
x := 0;
while (x < 10) {
r := r + s;
}
}
return r * s;
}
entry (arg) := {
[ integer: result ; rec: w; llnode: li; boolean: b]
li := make_list(6, 7);
result := foo(5);
w := reserve w;
w.x := 5;
w.y := 7;
result := bar1(w);
result := bar2(5,7);
return 'a';
}

View File

@ -0,0 +1,25 @@
type rec: [character: x; integer: y]
type T2: rec -> integer
type main: string -> integer
function entry: main
function bar: T2
bar (r,s) := {
return 0;
}
entry (arg) := {
[ integer: result ; rec: w]
if ( result = result ) then {
if ( result < w.y ) then {
result := 8;
} else {
result := 9;
}(* *)
} else {
result := bar('c', 7);
}
return 0;
}

View File

@ -0,0 +1,27 @@
type rec: [character: x; integer: y]
type T2: rec -> integer
type main: string -> integer
function entry: main
function bar: T2
bar (r,s) := {
return 0;
}
entry (arg) := {
[ integer: result ; rec: w]
while ( result = result ) {
result := result + 8;
if ( result < w.y ) then {
while (true) {
result := 8;
}
} else {
result := 9;
}
result := bar('c', 7);
}
return 0;
}

View File

@ -12,7 +12,12 @@ bar (r,s) := {
entry (arg) := { entry (arg) := {
[ integer: result ; rec: w] [ integer: result ; rec: w]
result := bar(1,2); while ( result = result ) {
while ( result < w.y ) {
result := 8;
}
result := 9;
}
result := bar('c', 7); result := bar('c', 7);
return 0; return 0;
} }