diff --git a/include/Defs.h b/include/Defs.h index 78d6dee..41e6133 100644 --- a/include/Defs.h +++ b/include/Defs.h @@ -27,6 +27,7 @@ enum TokenTypes { LI_EOF, + LI_EQUAL, // = AR_PLUS, // Arithmetic + AR_MINUS, // Arithmetic - @@ -40,7 +41,6 @@ enum TokenTypes { CMP_LTE, // <= CMP_GTE, // => - LI_EQUAL, // = LI_INT, // Integer literal LI_SEMIC, // ; @@ -84,7 +84,8 @@ enum TokenTypes { */ 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_MULTIPLY, // Multiply two numbers. OP_DIVIDE, // Divide two numbers. @@ -96,7 +97,6 @@ enum SyntaxOps { OP_LESSE, // Less 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_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. 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_SCALE, // We have a pointer that needs to be scaled! @@ -125,6 +124,7 @@ enum SyntaxOps { struct ASTNode { int Operation; // SyntaxOps Index int ExprType; // Value->IntValue's DataType + int RVal; // True if this node is an Rval, false if Lval struct ASTNode* Left; struct ASTNode* Middle; struct ASTNode* Right; @@ -307,7 +307,9 @@ int AsDiv(int Left, int Right); int AsLdVar(int ID); int AsStrVar(int Register, int ID); + int AsDeref(int Reg, int Type); +int AsStrDeref(int Register1, int Register2, int Type); int AsAddr(int ID); void AsNewSymb(int ID); @@ -350,4 +352,7 @@ struct ASTNode* ParseIdentifier(void); struct ASTNode* IfStatement(); struct ASTNode* WhileStatement(); -struct ASTNode* ForStatement(); \ No newline at end of file +struct ASTNode* ForStatement(); + + +void DumpTree(struct ASTNode* node, int level); \ No newline at end of file diff --git a/src/Dump.c b/src/Dump.c new file mode 100644 index 0000000..9c1c632 --- /dev/null +++ b/src/Dump.c @@ -0,0 +1,95 @@ + +/*************/ +/*GEMWIRE */ +/* ERYTHRO*/ +/*************/ + +#include +#include + +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); + } + +} \ No newline at end of file