Code:
/* called when I hit a numeric constant i.e. a number */
nodeType *con(numNode cnum) {
nodeType *ptr;
if ((ptr = malloc(sizeof(nodeType))) == NULL)
yyerror("out of memory");
ptr->num.type = cnum.type;
ptr->type = cnum.type;
if (cnum.type == intType) {
ptr->num.ival = cnum.ival;
}
else
ptr->num.fval = cnum.fval;
return ptr;
}
/* called when I encounter a variable name */
nodeType *id(symNode *sym) {
nodeType *ptr;
char *cp;
int len;
char temp[30];
typeEnum typ;
if ((ptr = malloc(sizeof(nodeType))) == NULL)
yyerror("out of memory");
typ = symType;
ptr->id.type = sym->type;
ptr->type = typ;
len = strlen(sym->name);
len = (len > 29) ? 29 : len; //prevent overflow (just in case)
sprintf(ptr->id.name, "%-*.*s", len, len, sym->name);
ptr->type = symType;
typ = ptr->id.type;
if (typ == intType)
ptr->id.ival = sym->ival;
else
ptr->id.fval = sym->fval;
return ptr;
}
/*
called when the statement is reduced opSign would be like '+' or IF (#defined to a num) nops is the number of operands
*/
nodeType *opr(long opSign, int nops, ...) {
va_list ap;
size_t size;
int i;
nodeType *ptr;
size = sizeof(opNode) + ((nops) * sizeof(nodeType*));
if ((ptr = malloc(size)) == NULL) {
yyerror("out of memory");
return NULL;
}
ptr->type = opType;
ptr->op.value = opSign;
ptr->op.nops = nops;
va_start(ap, nops);
for (i = 0; i < nops; i++) {
ptr->op.oprs[i] = va_arg(ap, nodeType*);
}
va_end(ap);
return ptr;
}
/* this is the last to execute (parse tree is completely built) before I free the memory this is where the segfault happens */
int ex(nodeType *p) {
int lbl1, lbl2;
char cmd[50];
char jmpCmd[5];
int inc;
int val;
if (!p) return 0;
switch(p->type) {
case intType :
sprintf(cmd, "\tli $t%d, %d", p->reg,p->num.ival);
add_cmd(cmd);
break;
case symType :
if (p->id.type == intType) {
sprintf(cmd, "\tlw $t%d, %s", p->reg, p->id.name);
add_cmd(cmd);
}
break;
case opType :
val = (p->op.value == IF) ? 0 : 1;
switch (p->op.oprs[val]->op.value) {
case LT : sprintf(jmpCmd, "bge"); break;
case LTE: sprintf(jmpCmd, "bgt"); break;
case GT : sprintf(jmpCmd, "ble"); break;
case GTE: sprintf(jmpCmd, "blt"); break;
case EQL: sprintf(jmpCmd, "bneq"); break;
case NOTEQL: sprintf(jmpCmd, "beq"); break;
}
switch(p->op.value) {
case FOR :
sprintf(cmd, "_LFOR%03d:", lbl1 = lblcnt++);
add_cmd(cmd);
sprintf(cmd, "\tli $t4, %d", p->op.oprs[1]->num.ival);
add_cmd(cmd);
sprintf(cmd, "\tsw $t4, %s", p->op.oprs[0]->id.name);
add_cmd(cmd);
sprintf(cmd, "\tli $s1, %d", p->op.oprs[2]->num.ival);
add_cmd(cmd);
sprintf(cmd, "\tlw $s0, %s", p->op.oprs[0]->id.name);
add_cmd(cmd);
sprintf(cmd, "\tbgt $s0, $s1, _EFOR%03d", lbl2 = lblcnt++);
add_cmd(cmd);
ex(p->op.oprs[3]);
inc = (p->op.nops == 5) ? p->op.oprs[4]->num.ival : 1;
sprintf(cmd, "\tli $t5, %d", inc);
add_cmd(cmd);
sprintf(cmd, "\tlw $s0, %s", p->op.oprs[0]->id.name);
add_cmd(cmd);
sprintf(cmd, "\tadd $s2, $s0, $t5");
add_cmd(cmd);
sprintf(cmd, "\tsw $s2, %s", p->op.oprs[0]->id.name);
add_cmd(cmd);
sprintf(cmd, "\tble $s2, $s1 _LFOR%03d", lbl1);
add_cmd(cmd);
sprintf(cmd, "_EFOR%03d:", lbl2);
add_cmd(cmd);
break;
case REPEAT :
sprintf(cmd, "_LR%03d:", lbl1 = lblcnt++);
add_cmd(cmd);
ex(p->op.oprs[0]);
ex(p->op.oprs[1]);
sprintf(cmd, "\t%s $t2, $t3, _LR%03d", jmpCmd, lbl1);
add_cmd(cmd);
break;
case IF :
ex(p->op.oprs[0]);
if (p->op.nops == 3) {
sprintf(cmd, "\t%s $t2,$t3,_L%03d", jmpCmd, lbl1 = lblcnt++);
add_cmd(cmd);
ex(p->op.oprs[1]);
sprintf(cmd, "\tj _L%03d", lbl2 = lblcnt++);
add_cmd(cmd);
sprintf(cmd, "_L%03d:", lbl1);
add_cmd(cmd);
ex(p->op.oprs[2]);
sprintf(cmd, "_L%03d:", lbl2);
add_cmd(cmd);
} else {
sprintf(cmd, "\t%s L%03d $t2 $t3", jmpCmd, lbl1 = lblcnt++);
add_cmd(cmd);
ex(p->op.oprs[1]);
sprintf(cmd, "L%03d:", lbl1);
add_cmd(cmd);
}
break;
case ASSIGNMNT :
p->op.oprs[1]->reg=0;
ex(p->op.oprs[1]);
sprintf(cmd, "\tsw $t0, %s", p->op.oprs[0]->id.name);
add_cmd(cmd);
break;
default :
if (p->op.value < 100) { //math expressions
p->op.oprs[0]->reg=1;
p->op.oprs[1]->reg=2;
} else { //relational expressions
p->op.oprs[0]->reg=2;
p->op.oprs[1]->reg=3;
}
ex(p->op.oprs[0]);
ex(p->op.oprs[1]);
/* ASCII Equilavants: + 43, - 45, * 42, / 47, % 37 */
switch (p->op.value) {
case 43 : sprintf(cmd, "\tadd $t0, $t1, $t2"); add_cmd(cmd); break;
case 45 : sprintf(cmd, "\tsub $t0, $t1, $t2"); add_cmd(cmd); break;
case 42 : sprintf(cmd, "\tmul $t0, $t1, $t2"); add_cmd(cmd); break;
case 47 : sprintf(cmd, "\tdiv $t0, $t1, $t2"); add_cmd(cmd); break;
case 37 : sprintf(cmd, "\tdiv $t1, $t2\n\tmfhi $t0"); add_cmd(cmd); break;
}
}
break;
}
return 1;
}
If it is a memory allocation error maybe it is in opr?