Add code for printing the AST tree after generation
This commit is contained in:
parent
764f89bb88
commit
d8abe6fec0
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
enum TokenTypes {
|
enum TokenTypes {
|
||||||
LI_EOF,
|
LI_EOF,
|
||||||
|
LI_EQUAL, // =
|
||||||
|
|
||||||
AR_PLUS, // Arithmetic +
|
AR_PLUS, // Arithmetic +
|
||||||
AR_MINUS, // Arithmetic -
|
AR_MINUS, // Arithmetic -
|
||||||
|
@ -40,7 +41,6 @@ enum TokenTypes {
|
||||||
CMP_LTE, // <=
|
CMP_LTE, // <=
|
||||||
CMP_GTE, // =>
|
CMP_GTE, // =>
|
||||||
|
|
||||||
LI_EQUAL, // =
|
|
||||||
LI_INT, // Integer literal
|
LI_INT, // Integer literal
|
||||||
LI_SEMIC, // ;
|
LI_SEMIC, // ;
|
||||||
|
|
||||||
|
@ -84,7 +84,8 @@ enum TokenTypes {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum SyntaxOps {
|
enum SyntaxOps {
|
||||||
OP_ADD = 1, // Add two numbers.
|
OP_ASSIGN = 1, // Assign an l-value
|
||||||
|
OP_ADD, // Add two numbers.
|
||||||
OP_SUBTRACT, // Subtract two numbers.
|
OP_SUBTRACT, // Subtract two numbers.
|
||||||
OP_MULTIPLY, // Multiply two numbers.
|
OP_MULTIPLY, // Multiply two numbers.
|
||||||
OP_DIVIDE, // Divide two numbers.
|
OP_DIVIDE, // Divide two numbers.
|
||||||
|
@ -96,7 +97,6 @@ enum SyntaxOps {
|
||||||
OP_LESSE, // Less than or Equal to?
|
OP_LESSE, // Less than or Equal to?
|
||||||
OP_GREATE, // Greater than or Equal to?
|
OP_GREATE, // Greater than or Equal to?
|
||||||
|
|
||||||
OP_ASSIGN, // Assign an l-value
|
|
||||||
|
|
||||||
OP_ADDRESS, // Fetch the address of a var
|
OP_ADDRESS, // Fetch the address of a var
|
||||||
OP_DEREF, // Get the value of the address in a pointer
|
OP_DEREF, // Get the value of the address in a pointer
|
||||||
|
@ -104,7 +104,6 @@ enum SyntaxOps {
|
||||||
TERM_INTLITERAL, // Integer Literal. This is a virtual operation, so it's a terminal.
|
TERM_INTLITERAL, // Integer Literal. This is a virtual operation, so it's a terminal.
|
||||||
|
|
||||||
REF_IDENT, // Reference (read) an identifier (variable).
|
REF_IDENT, // Reference (read) an identifier (variable).
|
||||||
LV_IDENT, // Write an identifier in the form of an l-value.
|
|
||||||
|
|
||||||
OP_WIDEN, // Something contains a type that needs to be casted up
|
OP_WIDEN, // Something contains a type that needs to be casted up
|
||||||
OP_SCALE, // We have a pointer that needs to be scaled!
|
OP_SCALE, // We have a pointer that needs to be scaled!
|
||||||
|
@ -125,6 +124,7 @@ enum SyntaxOps {
|
||||||
struct ASTNode {
|
struct ASTNode {
|
||||||
int Operation; // SyntaxOps Index
|
int Operation; // SyntaxOps Index
|
||||||
int ExprType; // Value->IntValue's DataType
|
int ExprType; // Value->IntValue's DataType
|
||||||
|
int RVal; // True if this node is an Rval, false if Lval
|
||||||
struct ASTNode* Left;
|
struct ASTNode* Left;
|
||||||
struct ASTNode* Middle;
|
struct ASTNode* Middle;
|
||||||
struct ASTNode* Right;
|
struct ASTNode* Right;
|
||||||
|
@ -307,7 +307,9 @@ int AsDiv(int Left, int Right);
|
||||||
int AsLdVar(int ID);
|
int AsLdVar(int ID);
|
||||||
int AsStrVar(int Register, int ID);
|
int AsStrVar(int Register, int ID);
|
||||||
|
|
||||||
|
|
||||||
int AsDeref(int Reg, int Type);
|
int AsDeref(int Reg, int Type);
|
||||||
|
int AsStrDeref(int Register1, int Register2, int Type);
|
||||||
int AsAddr(int ID);
|
int AsAddr(int ID);
|
||||||
|
|
||||||
void AsNewSymb(int ID);
|
void AsNewSymb(int ID);
|
||||||
|
@ -351,3 +353,6 @@ struct ASTNode* ParseIdentifier(void);
|
||||||
struct ASTNode* IfStatement();
|
struct ASTNode* IfStatement();
|
||||||
struct ASTNode* WhileStatement();
|
struct ASTNode* WhileStatement();
|
||||||
struct ASTNode* ForStatement();
|
struct ASTNode* ForStatement();
|
||||||
|
|
||||||
|
|
||||||
|
void DumpTree(struct ASTNode* node, int level);
|
95
src/Dump.c
Normal file
95
src/Dump.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
|
||||||
|
/*************/
|
||||||
|
/*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 REF_IDENT:
|
||||||
|
if(node->Right)
|
||||||
|
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\n"); return;
|
||||||
|
case OP_SCALE: fprintf(stdout, "OP_SCALE %d\n", Symbols[node->Value.Size]); return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DieDecimal("Unknown Dump Operator", node->Operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user