97 lines
3.5 KiB
C
97 lines
3.5 KiB
C
|
|
/*************/
|
|
/*GEMWIRE */
|
|
/* ERYTHRO*/
|
|
/*************/
|
|
|
|
#include <Defs.h>
|
|
#include <Data.h>
|
|
|
|
static int GenerateSrg() {
|
|
static int srgId = 1;
|
|
return srgId++;
|
|
}
|
|
|
|
void DumpTree(struct ASTNode* node, int level) {
|
|
int Lfalse, Lstart, Lend;
|
|
|
|
// Handle weirdo loops and conditions first.
|
|
switch(node->Operation) {
|
|
case OP_IF:
|
|
Lfalse = GenerateSrg();
|
|
for(int i = 0; i < level; i++)
|
|
fprintf(stdout, " ");
|
|
fprintf(stdout, "IF");
|
|
if(node->Right) {
|
|
Lend = GenerateSrg();
|
|
fprintf(stdout, ", end label %d", Lend);
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
DumpTree(node->Left, level + 2);
|
|
DumpTree(node->Middle, level + 2);
|
|
|
|
if(node->Right)
|
|
DumpTree(node->Right, level + 2);
|
|
|
|
return;
|
|
case OP_LOOP:
|
|
Lstart = GenerateSrg();
|
|
for(int i = 0; i < level; i++)
|
|
fprintf(stdout, " ");
|
|
fprintf(stdout, "LOOP starts at %d\n", Lstart);
|
|
Lend = GenerateSrg();
|
|
DumpTree(node->Left, level + 2);
|
|
DumpTree(node->Right, level + 2);
|
|
return;
|
|
}
|
|
|
|
// If current node is a compound, we treat it as if we didn't just enter a loop.
|
|
if(node->Operation == OP_COMP)
|
|
level = -2;
|
|
|
|
if(node->Left)
|
|
DumpTree(node->Left, level + 2);
|
|
|
|
if(node->Right)
|
|
DumpTree(node->Right, level + 2);
|
|
|
|
// The meat of this operation!
|
|
for(int i = 0; i < level; i++)
|
|
fprintf(stdout, " ");
|
|
|
|
switch (node->Operation){
|
|
case OP_COMP: fprintf(stdout, "\n\n"); return;
|
|
case OP_FUNC: fprintf(stdout, "OP_FUNC %s\n", Symbols[node->Value.ID].Name); return;
|
|
case OP_ADD: fprintf(stdout, "OP_ADD\n"); return;
|
|
case OP_SUBTRACT: fprintf(stdout, "OP_SUBTRACT\n"); return;
|
|
case OP_MULTIPLY: fprintf(stdout, "OP_MULTIPLY\n"); return;
|
|
case OP_DIVIDE: fprintf(stdout, "OP_DIVIDE\n"); return;
|
|
case OP_EQUAL: fprintf(stdout, "OP_EQUAL\n"); return;
|
|
case OP_INEQ: fprintf(stdout, "OP_INEQ\n"); return;
|
|
case OP_LESS: fprintf(stdout, "OP_LESS\n"); return;
|
|
case OP_GREAT: fprintf(stdout, "OP_GREAT\n"); return;
|
|
case OP_LESSE: fprintf(stdout, "OP_LESSE\n"); return;
|
|
case OP_GREATE: fprintf(stdout, "OP_GREATE\n"); return;
|
|
case TERM_INTLITERAL: fprintf(stdout, "TERM_INTLITERAL %d\n", node->Value.IntValue); return;
|
|
case TERM_STRLITERAL: fprintf(stdout, "TERM_STRLITERAL rval L%d\n", node->Value.IntValue); return;
|
|
case REF_IDENT:
|
|
if(node->RVal)
|
|
fprintf(stdout, "REF_IDENT rval %s\n", Symbols[node->Value.ID].Name);
|
|
else
|
|
fprintf(stdout, "REF_IDENT %s\n", Symbols[node->Value.ID].Name);
|
|
return;
|
|
case OP_ASSIGN: fprintf(stdout, "OP_ASSIGN\n"); return;
|
|
case OP_WIDEN: fprintf(stdout, "OP_WIDEN\n"); return;
|
|
case OP_RET: fprintf(stdout, "OP_RET\n"); return;
|
|
case OP_CALL: fprintf(stdout, "OP_CALL %s\n", Symbols[node->Value.ID].Name); return;
|
|
case OP_ADDRESS: fprintf(stdout, "OP_ADDRESS %s\n", Symbols[node->Value.ID].Name); return;
|
|
case OP_DEREF:
|
|
fprintf(stdout, "OP_DEREF %s\n", node->RVal ? "rval" : ""); return;
|
|
case OP_SCALE: fprintf(stdout, "OP_SCALE %s\n", TypeNames[node->Value.Size]); return;
|
|
|
|
default:
|
|
DieDecimal("Unknown Dump Operator", node->Operation);
|
|
}
|
|
|
|
} |