This commit is contained in:
Partho
2025-04-29 22:42:28 -04:00
parent e45f0663f1
commit 0b727c06fc
3 changed files with 0 additions and 1009 deletions

614
src/CG.c
View File

@ -1,614 +0,0 @@
int generate(){
offset = 0;
Instruction *i = begin;
while (i != NULL) {
switch(getOp(i)) {
case E_LABEL:
generateLabel(i);
break;
case E_ADD:
generateAdd(i);
break;
case E_SUB:
generateSub(i);
break;
case E_MUL:
generateMult(i);
break;
case E_DIV:
generateDiv(i);
break;
case E_MOD:
generateMod(i);
break;
case E_OR:
generateOr(i);
break;
case E_AND:
generateAnd(i);
break;
case E_NEG:
generateNeg(i);
break;
case E_NOT:
generateNot(i);
break;
case E_ASSIGN:
generateAssign(i);
break;
case E_GOTO:
generateGoto(i);
break;
case E_IF_X_TRUE:
generateIfTrue(i);
break;
case E_IF_X_FALSE:
generateIfFalse(i);
break;
case E_LESS_THAN:
generateLessThan(i);
break;
case E_EQUAL_TO:
generateEqualTo(i);
break;
case E_CALL:
generateCall(i);
break;
case E_PARAM:
generateParam(i);
break;
case E_RETURN:
generateReturn(i);
break;
case E_INDEX_COPY_RIGHT:
generateCopyRight(i);
break;
case E_INDEX_COPY_LEFT:
generateCopyLeft(i);
break;
case E_ADDRESS_OF:
generateAddressOf(i);
break;
default:
;
}
i = i->next;
}
return -1;
}
CGNode *getNextCG(CGNode *cg) {
if (cg == NULL) {
return NULL;
}
return cg->next;
}
int getAddress(CGNode *cg) {
if (cg == NULL) {
return -1;
}
return currentsp - cg->address;
}
TableNode *getTNofCG(CGNode *cg) {
if (cg == NULL) {
return NULL;
}
return cg->tn;
}
CGNode *findCG(TableNode *tn) {
CGNode *cg = cgList;
while (cg != NULL) {
if (getTNofCG(cg) == tn) {
return cg;
}
cg = getNextCG(cg);
}
return NULL;
}
CGNode *addCG(TableNode *tn, int sp) {
CGNode *cg = calloc(1, sizeof(CGNode));
cg->tn = tn;
offset += getPrimSize(getTypeEntry(tn));
cg->address = offset;
cg->next = cgList;
cgList = cg;
return cg;
}
int generateLabel(Instruction *inst) {
fprintf(cg_flag, ".L%d:\n", getLabel(inst));
return 0;
}
int generateAdd(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateAdd failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op1));
if (op1CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1)));
return -1;
}
if (op2CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG));
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\taddl\t%%edx, %%eax\n");
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg));
return 0;
}
int generateSub(Instruction *instruction) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(instruction);
TNodeOrConst *op2 = getOperand2(instruction);
CGNode *cg = findCG(getResult(instruction));
if (op1 == NULL || op2 == NULL) {
printdebug("generateSub failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(instruction), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateSub failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\n", getAddress(op1CG));
fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg));
return 0;
}
int generateMult(Instruction *inst){
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateMult failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateMult failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG));
fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG));
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg));
return 0;
}
int generateDiv(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateDiv failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateDiv failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
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, "\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
return 0;
}
int generateMod(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateMod failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateMod failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
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, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack
fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder)
return 0;
}
int generateOr(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("generateOr failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateOr failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
int label = label_gen();
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, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
fprintf(cg_flag, "\tje\t.L%dor3\n", label);
fprintf(cg_flag, ".L%dor2:\n", label);
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
fprintf(cg_flag, "\tjmp\t.L%dor4\n", label);
fprintf(cg_flag, ".L%dor3:\n", label);
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
fprintf(cg_flag, ".L%dor4:\n", label);
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
return 0;
}
int generateAnd(Instruction *inst) {
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateAnd failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
int label = label_gen();
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, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
fprintf(cg_flag, "\tje\t.L%dor2\n", label);
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
fprintf(cg_flag, "\tjmp\t.L%dor3\n", label);
fprintf(cg_flag, ".L%dor2:\n", label);
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
fprintf(cg_flag, ".L%dor3:\n", label);
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
return 0;
}
int generateNeg(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateNeg failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) {
printdebug("generateNeg failed, op1 is not constant but not in CGlist");
return -1;
}
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG));
fprintf(cg_flag, "\tnegl\t%%eax\n");
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg));
return 0;
}
int generateNot(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateNot failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) {
printdebug("generateNot failed, op1 is not constant but not in CGlist");
return -1;
}
fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG));
fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n");
fprintf(cg_flag, "\tsetne\t%%al\n");
fprintf(cg_flag, "\txorl\t$1, %%eax\n");
fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg));
return 0;
}
int generateAssign(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateAssign failed, NULL operand");
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
//add option for constant assignment (should be easy)
if (isConst(op1) == true) {
fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg));
return 0;
}
CGNode *op1CG = findCG(getTN(op1));
if (op1CG == NULL) {
printf("failed here\n");
printdebug("generateAssign failed, op1 is not constant but not in CGlist");
return -1;
}
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));
return 0;
}
int generateGoto(Instruction *instruction){
return -1;
}
int generateCondGoto(Instruction *instruction) {
return -1;
}
int generateIfTrue(Instruction *instruction){
return -1;
// might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case
}
int generateIfFalse(Instruction *instruction){
return -1;
}
int generateLessThan(Instruction *inst){
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
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, "\tsetl\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg));
return 0;
}
int generateEqualTo(Instruction *inst){
/*
Both immediate:
One immediate:
Neither immediate:
*/
TNodeOrConst *op1 = getOperand1(inst);
TNodeOrConst *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1;
}
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
return -1;
}
if (op2CG == NULL) {
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
return -1;
}
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, "\tsete\t%%al\n");
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg));
return 0;
}
int generateCall(Instruction *instruction){
return -1;
//will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg
}
int generateReturn(Instruction *instruction){
return -1;
//will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value
}
int generateCopyRight(Instruction *instruction){
return -1;
}
int generateCopyLeft(Instruction *instruction){
return -1;
}
int generateAddressOf(Instruction *instruction){
return -1;
}
int generateParam(Instruction *instruction){
//need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated
return -1;
}

395
src/IR.c
View File

@ -1,395 +0,0 @@
// TODO: this is here to bring your attention to the comment bellow.
// check if start is NULL if it is assign it to the start globle variable
// otherwise make it next of current and set cur to your instruction.
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_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_as_file(FILE * out_file, Instruction * i){
if(i == NULL){
return;
}
switch(i->opcode){
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){
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(int name){
emit_helper();
current->opcode = E_LABEL; // I think this is right TODO: ask
current->label = name;
// this is probabaly a func decleration
}
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, );
//emit_jump();
/* We need a label ERROR to jump to
*/
}
/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.)
char * temp_var_gen(){
char * ret = calloc(9, sizeof(*ret));
sprintf(ret, "$t%d", temp_count);
temp_count++;
return ret;
}
*/
int label_gen(){
label_count++;
return label_count;
}
TableNode* getTN(TNodeOrConst * tnc){
if(tnc->d == NODE){
return tnc->tnc_union->node;
}
return NULL;
}
//we must fix this
int getConst(TNodeOrConst * tnc){
if(tnc->d == INTEGER){
return tnc->tnc_union->integer;
}
return -1;
}

Binary file not shown.