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

View File

@ -47,7 +47,7 @@ int generate(){
break;
case E_IF_X_TRUE:
generateIfTrue(i);
break;
break;
case E_IF_X_FALSE:
generateIfFalse(i);
break;
@ -148,7 +148,7 @@ int generateAdd(Instruction *inst) {
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;
@ -157,8 +157,8 @@ int generateAdd(Instruction *inst) {
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -186,7 +186,7 @@ int generateSub(Instruction *instruction) {
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;
@ -195,7 +195,7 @@ int generateSub(Instruction *instruction) {
if (cg == NULL) {
cg = addCG(getResult(instruction), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -223,7 +223,7 @@ int generateMult(Instruction *inst){
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;
@ -259,7 +259,7 @@ int generateDiv(Instruction *inst) {
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;
@ -268,7 +268,7 @@ int generateDiv(Instruction *inst) {
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
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, "\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
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result
return 0;
}
@ -297,7 +297,7 @@ int generateMod(Instruction *inst) {
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;
@ -312,12 +312,12 @@ int generateMod(Instruction *inst) {
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
@ -334,7 +334,7 @@ int generateOr(Instruction *inst) {
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;
@ -343,7 +343,7 @@ int generateOr(Instruction *inst) {
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -358,22 +358,22 @@ int generateOr(Instruction *inst) {
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, "\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, ".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, ".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, "\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;
}
@ -386,7 +386,7 @@ int generateAnd(Instruction *inst) {
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;
@ -395,7 +395,7 @@ int generateAnd(Instruction *inst) {
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -409,27 +409,27 @@ int generateAnd(Instruction *inst) {
}
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, "\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, "\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, ".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, "\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;
}
int generateNeg(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateNeg failed, NULL operand");
return -1;
@ -438,14 +438,14 @@ int generateNeg(Instruction *inst) {
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, "\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;
@ -453,7 +453,7 @@ int generateNeg(Instruction *inst) {
int generateNot(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateNot failed, NULL operand");
return -1;
@ -462,7 +462,7 @@ int generateNot(Instruction *inst) {
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");
@ -483,7 +483,7 @@ int generateAssign(Instruction *inst) {
TNodeOrConst *op1 = getOperand1(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL) {
printdebug("generateAssign failed, NULL operand");
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));
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%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;
}
@ -538,7 +537,7 @@ int generateLessThan(Instruction *inst){
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;
@ -547,7 +546,7 @@ int generateLessThan(Instruction *inst){
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -560,7 +559,7 @@ int generateLessThan(Instruction *inst){
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, "\tsetl\t%%al\n");
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 *op2 = getOperand2(inst);
CGNode *cg = findCG(getResult(inst));
if (op1 == NULL || op2 == NULL) {
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
return -1;
@ -585,7 +584,7 @@ int generateEqualTo(Instruction *inst){
if (cg == NULL) {
cg = addCG(getResult(inst), offset);
}
CGNode *op1CG = findCG(getTN(op1));
CGNode *op2CG = findCG(getTN(op2));
if (op1CG == NULL) {
@ -598,7 +597,7 @@ int generateEqualTo(Instruction *inst){
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, "\tsete\t%%al\n");
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){
return -1;
}
int generateParam(Instruction *inst){
TNodeOrConst *op1 = getOperand1(inst);
@ -686,5 +686,4 @@ int generateFunctionStart(Instruction *inst) {
fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n");
return 0;
}

View File

@ -29,4 +29,8 @@ Instruction *current;
int offset;
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"
// 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;
Stack * S_Init(){
Stack * s = calloc(1, sizeof(*s));
return s;
}
TNodeOrConst* getOperand2(Instruction* i) {
return i->operand2;
void S_Free(Stack *s){
// 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) {
return i->result;
void S_Push(Stack * s, void *v, int i) {
__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) {
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;
void * S_Pop(Stack *s) {
if (s == NULL || S_IsEmpty(s)) {
return NULL;
}
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));
if (begin == NULL) {
begin = current = inst;
current->index = 1;
} else {
current->next = inst;
inst->prev = current;
inst->index = current->index + 1;
current = inst;
void * S_Peek(Stack *s){
if (s == NULL || S_IsEmpty(s)) {
return NULL;
}
return s->n->v;
}
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");
bool S_IsEmpty(Stack *s){
if(s == NULL || s->size == 0) {
return true;
}
return false;
}
void emit_as_file(FILE* out_file, Instruction* i) {
if (i == NULL) {
return;
int S_Size(Stack *s){
if (s == NULL || S_IsEmpty(s)) {
return 0;
}
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);
return s->size;
}
void emit_label(int label) {
emit_helper();
current->opcode = E_LABEL;
current->label = label;
void emit_backpatch(Stack * s, int l){
for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){
i->label = l;
}
}
//_______________________________________________________________________
void emit_jump(int label) {
emit_helper();
current->opcode = E_GOTO;
current->label = label;
}
char * temp = NULL;
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();
current->opcode = E_LABEL; // I think this is right TODO: ask
current->operand1 = name;
// 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
/*
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.
*/
//emit_conditional_jump(E_LESS_THAN, );
//emit_conditional_jump(E_LESS_THAN, );
//emit_jump();
/* We need a label ERROR to jump to
*/
void emit_push_all(Stack * s){
for (Instruction * i = S_Pop(s); i; i = S_Pop(s)){
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.)
char * temp_var_gen(){
char * ret = calloc(9, sizeof(*ret));
sprintf(ret, "$t%d", temp_count);
temp_count++;
return ret;
void emit_detach(){
current = current->prev;
current->next = NULL;
}
*/
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(){
label_count++;
return label_count;
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) {
if (tnc->d == NODE) {
return tnc->tnc_union->node;
}
return NULL;
}
if (tnc->d == NODE) {
return tnc->tnc_union->node;
}
return NULL;
}
int getConst(TNodeOrConst* tnc) {
if (tnc->d == INTEGER) {
return tnc->tnc_union->integer;
}
return -1;
}
int getConst(TNodeOrConst* tnc) {
if (tnc->d == INTEGER) {
return tnc->tnc_union->integer;
}
return -1;
}

View File

@ -12,7 +12,35 @@
#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
typedef enum { // these are from page 364
E_LABEL = 10000, // this is not in the book
E_FUNC_START,
@ -43,83 +71,104 @@ typedef enum { // these are from page 364
} Op;
typedef enum {
NODE = 11000, // TableNode
INTEGER, // int
STRING, // char *
CHARACTER, // char
ADDRESS, // void *
BOOLEAN // bool
NODE = 11000, // TableNode
INTEGER, // int
STRING, // char *
CHARACTER, // char
ADDRESS, // void *
BOOLEAN // bool
} Discriminant;
typedef union {
TableNode* node;
int integer;
char* string;
char character;
void* address;
bool Boolean;
typedef union TNConstUnion {
TableNode * node;
int integer;
char * string;
char character;
void * address;
bool Boolean;
} TNConstUnion;
typedef struct {
Discriminant d;
TNConstUnion* tnc_union;
typedef struct TNodeOrConst {
Discriminant d;
TNConstUnion * tnc_union;
} TNodeOrConst;
typedef struct Instruction Instruction;
typedef struct Instruction {
Op opcode;
TableNode* result;
TNodeOrConst* operand1;
TNodeOrConst* operand2;
int label;
int index;
Op opcode;
TableNode * result;
TNodeOrConst * operand1;
TNodeOrConst * operand2;
int label;
int index;
Instruction* prev;
Instruction* next;
Instruction * prev;
Instruction * next;
} Instruction;
// NOTE We are not using this We are using the Stack api
typedef struct TFList {
Instruction* i;
TFList* next;
Instruction * i;
TFList * next;
} TFList;
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);
TNodeOrConst* tn_or_const(Discriminant d, void* tnc);
static void emit_helper(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);
char* get_string(TNodeOrConst* tc);
void emit_as_file(FILE* out_file, Instruction* i);
// TFList * make_list(Instruction * i);
// - makelist(i) function to create instruction lists
// void merge(TFList * l1, TFList * l2);
// - merge(p1,p2) function to concatenate lists
// void backpatch(TFList * l, int label);
// - backpatch(p,i) function to fill in jump targets
// void bp_temp(int n);
extern Instruction * begin;
extern Instruction * current;
extern int label_count;
extern bool code_gen;
extern FILE * ir_flag;
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_jump(int label);
void emit_conditional_jump(Op condition, int label, ...);
void emit_function_start(TNodeOrConst * name);
void emit_parameter(TNodeOrConst* param);
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name);
void emit_return(TNodeOrConst* value);
void emit_reserve(TableNode* result, TNodeOrConst* size);
void emit_release(TableNode* pointer);
void emit_deref_right();
void emit_deref_left();
void emit_function_start(TableNode* name);
void emit_parameter(TNodeOrConst * param);
void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name);
void emit_return(TNodeOrConst * value);
void emit_reserve(TableNode * result, TNodeOrConst * size);
void emit_release(TableNode * pointer);
void emit_field_access(char* result, char* record, char* field);
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index);
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr);
int label_gen();
void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index);
void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr);
void emit_goto(int i);
void emit_detach();
void emit_push_all(Stack * s);
int getLabel(Instruction * i);
TableNode* getTN(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 currentsp;
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;}
\"{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;*/}
_{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(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; }

View File

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

View File

@ -70,6 +70,9 @@ TableNode *recprime;
TableNode *funtypeprime;
TableNode *undefined;
extern Instruction *begin;
extern Stack* stack;
extern Stack* TrueList;
extern Stack* FalseList;
int main(int argc, char *argv[]);
int check_flag(char *arg, char *alpha);
@ -108,4 +111,4 @@ CodeLine *code_head;
char *file_read_line(FILE *fp);
void insert_code_line(char * error_message, int line_number);
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;
int temp2_count = 0;
int temp3_count = 0;
void printdebug_impl(char *file, int line, const char *format, ...) {
if (DEBUG) {
@ -24,6 +25,12 @@ char *temp_var_gen() {
temp2_count++;
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) {
if (type == NULL || type == undefined) {
@ -623,6 +630,7 @@ TableNode *getReturn(TableNode *definition) {
"node has NULL additionalinfo. Invalid.");
return undefined;
}
printdebug("function:%s with return type %s\n",getName(definition),getName(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)) {
if((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL){
continue;
}
if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) {
char *arrayType = (char *)malloc(100);
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) {
char *functiontype = (char *)malloc(100);
sprintf(functiontype, " %s", getName(getReturn(entry)));
sprintf(functiontype, " %s", getName(getTypeEntry(entry)));
if (parentScopeNum == 0) {
st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition");
} else {

View File

@ -15,6 +15,8 @@
#define SIZE_CHAR 1
#define SIZE_BOOL 1
extern FILE *ir_flag;
struct TableNode;
typedef struct TFList TFList;
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__)
char *temp_var_gen();
char *arg_var_gen();
Constant_Stack *Push(TableNode *type, void *value, bool isConst);
Constant_Stack *Pop();
Constant_Stack *Print_Stack();
@ -165,6 +168,7 @@ extern int column_number;
extern FILE *yyin;
extern bool DEBUG;
extern int temp2_count;
extern int temp3_count;
extern TableNode *funprime;
extern TableNode *arrayprim;
extern TableNode *integ;

View File

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

View File

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

View File

@ -45,9 +45,9 @@ selectionSort(data) := {
data(i) := temp;
i := i + 1;
}
return true;
return true;
}
(* Function definition
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) := {
[integer:orig_a; llnode: ret; llnode: curr; llnode: temp]
if (a < 0 | a = 0) then {
return null;
} else {
@ -73,8 +72,8 @@ entry (arg) := {
w := reserve w;
w.x := 5;
w.y := 7;
result := bar1(w);
(* result := bar1(w); *)
result := bar2(5,7);
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) := {
[ integer: result ; rec: w]
result := bar(1,2);
while ( result = result ) {
while ( result < w.y ) {
result := 8;
}
result := 9;
}
result := bar('c', 7);
return 0;
}
}