]> git.sur5r.net Git - cc65/blobdiff - src/cc65/exprnode.c
Working on the backend
[cc65] / src / cc65 / exprnode.c
index c802fcf39c9fabe439d840505421f89e2b6346d3..a5cf4aef1761fe81bf6112ca354565eb6dc4142d 100644 (file)
 
 
 
+/* common */
+#include "check.h"
+
+/* cc65 */
+#include "error.h"
 #include "exprnode.h"
 
 
@@ -52,6 +57,8 @@ ExprNode* InitExprNode (ExprNode* E, nodetype_t NT, type* Type,
     E->NT         = NT;
     E->Type       = Type;
     E->LValue     = LValue;
+    E->IVal       = 0;
+    E->FVal       = 0.0;
 
     /* Initialize the expression list in the node */
     InitCollection (&E->List);
@@ -141,7 +148,7 @@ void SetRightNode (ExprNode* Root, ExprNode* Right)
 struct SymEntry* GetNodeSym (ExprNode* N)
 /* Get the symbol entry for a NT_SYM node */
 {
-    return GetItem (N, IDX_SYM);
+    return (struct SymEntry*) GetItem (N, IDX_SYM);
 }
 
 
@@ -154,4 +161,321 @@ void SetNodeSym (ExprNode* N, struct SymEntry* Sym)
 
 
 
+int IsLeafNode (const ExprNode* E)
+/* Return true if this is a leaf node */
+{
+    return (E->NT & NT_MASK_LEAF) == NT_LEAF;
+}
+
+
+
+int IsBranchNode (const ExprNode* E)
+/* Return true if this is a branch node */
+{
+    return (E->NT & NT_MASK_LEAF) == NT_BRANCH;
+}
+
+
+
+void DumpExpr (FILE* F, const ExprNode* E)
+/* Dump an expression in UPN notation to the given file */
+{
+    if (IsLeafNode (E)) {
+
+       /* Operand */
+       switch (E->NT) {
+
+           case NT_SYM:
+               /* Symbol */
+               fprintf (F, "SYM ");
+               break;
+
+           case NT_CONST:
+               /* A constant of some sort */
+               if (IsClassInt (E->Type)) {
+                   fprintf (F, "%0*lX ", SizeOf (E->Type), E->IVal);
+               } else if (IsClassFloat (E->Type)) {
+                   fprintf (F, "%f ", E->FVal);
+               } else {
+                   Internal ("Unknown type for NT_CONST");
+               }
+               break;
+
+           case NT_ASM:
+               /* Inline assembler */
+               fprintf (F, "ASM ");
+               break;
+
+           case NT_REG_A:
+               /* A register */
+               fprintf (F, "REG_A ");
+               break;
+
+           case NT_REG_X:
+               /* X register */
+               fprintf (F, "REG_X ");
+               break;
+
+           case NT_REG_Y:
+               /* Y register */
+               fprintf (F, "REG_Y ");
+               break;
+
+           case NT_REG_AX:
+               /* AX register */
+               fprintf (F, "REG_AX ");
+               break;
+
+           case NT_REG_EAX:
+               /* EAX register */
+               fprintf (F, "REG_EAX ");
+               break;
+
+           default:
+               Internal ("Unknown node type: %04X", E->NT);
+               break;
+
+       }
+
+    } else {
+
+       unsigned I, Count;
+
+       /* Dump the operands */
+       switch (E->NT & NT_MASK_LIST) {
+
+           case NT_LIST_EXPR:
+               Count = CollCount (&E->List);
+               for (I = 0; I < Count; ++I) {
+                   DumpExpr (F, (const ExprNode*) CollConstAt (&E->List, I));
+               }
+               break;
+
+           default:
+               Internal ("Operator with LIST != NT_LIST_EXPR");
+
+       }
+
+       /* Dump the operator */
+       switch (E->NT) {
+
+           case NT_ARRAY_SUBSCRIPT:
+               /* Array subscript */
+               fprintf (F, "[] ");
+               break;
+
+           case NT_STRUCT_ACCESS:
+               /* Access of a struct field */
+               fprintf (F, ". ");
+               break;
+
+           case NT_STRUCTPTR_ACCESS:
+               /* Access via struct ptr */
+               fprintf (F, "-> ");
+               break;
+
+           case NT_FUNCTION_CALL:
+               /* Call a function */
+               fprintf (F, "CALL ");
+               break;
+
+           case NT_TYPECAST:
+               /* A cast */
+               fprintf (F, "CAST ");
+               break;
+
+           case NT_ADDRESS:
+               /* Address operator (&) */
+               fprintf (F, "ADDR ");
+               break;
+
+           case NT_INDIRECT:
+               /* Indirection operator (*) */
+               fprintf (F, "FETCH ");
+               break;
+
+           case NT_UNARY_MINUS:
+               /* - */
+               fprintf (F, "NEG ");
+               break;
+
+           case NT_COMPLEMENT:
+               /* ~ */
+               fprintf (F, "~ ");
+               break;
+
+           case NT_BOOL_NOT:
+               /* ! */
+               fprintf (F, "! ");
+               break;
+
+           case NT_PLUS:
+               /* + */
+               fprintf (F, "+ ");
+               break;
+
+           case NT_MINUS:
+               /* - */
+               fprintf (F, "- ");
+               break;
+
+           case NT_MUL:
+               /* * */
+               fprintf (F, "* ");
+               break;
+
+           case NT_DIV:
+               /* / */
+               fprintf (F, "/ ");
+               break;
+
+           case NT_SHL:
+               /* << */
+               fprintf (F, "<< ");
+               break;
+
+           case NT_SHR:
+               /* >> */
+               fprintf (F, ">> ");
+               break;
+
+           case NT_AND:
+               /* & */
+               fprintf (F, "& ");
+               break;
+
+           case NT_OR:
+               /* | */
+               fprintf (F, "| ");
+               break;
+
+           case NT_XOR:
+               /* ^ */
+               fprintf (F, "^ ");
+               break;
+
+           case NT_TERNARY:
+               /* ?: */
+               fprintf (F, "?: ");
+               break;
+
+           case NT_ASSIGN:
+               /* = */
+               fprintf (F, "= ");
+               break;
+
+           case NT_PLUS_ASSIGN:
+               /* += */
+               fprintf (F, "+= ");
+               break;
+
+           case NT_MINUS_ASSIGN:
+               /* -= */
+               fprintf (F, "-= ");
+               break;
+
+           case NT_MUL_ASSIGN:
+               /* *= */
+               fprintf (F, "*= ");
+               break;
+
+           case NT_DIV_ASSIGN:
+               /* /= */
+               fprintf (F, "/= ");
+               break;
+
+           case NT_SHL_ASSIGN:
+               /* <<= */
+               fprintf (F, "<<= ");
+               break;
+
+           case NT_SHR_ASSIGN:
+               /* >>= */
+               fprintf (F, ">>= ");
+               break;
+
+           case NT_AND_ASSIGN:
+               /* &= */
+               fprintf (F, "&= ");
+               break;
+
+           case NT_OR_ASSIGN:
+               /* |= */
+               fprintf (F, "|= ");
+               break;
+
+           case NT_XOR_ASSIGN:
+               /* ^= */
+               fprintf (F, "^= ");
+               break;
+
+           case NT_PRE_DEC:
+               /* -- */
+               fprintf (F, "<-- ");
+               break;
+
+           case NT_POST_DEC:
+               /* -- */
+               fprintf (F, "--> ");
+               break;
+
+           case NT_PRE_INC:
+               /* ++ */
+               fprintf (F, "<++ ");
+               break;
+
+           case NT_POST_INC:
+               /* ++ */
+               fprintf (F, "++> ");
+               break;
+
+           case NT_BOOL_OR:
+               /* || */
+               fprintf (F, "|| ");
+               break;
+
+           case NT_BOOL_AND:
+               /* && */
+               fprintf (F, "&& ");
+               break;
+
+           case NT_EQ:
+               /* == */
+               fprintf (F, "== ");
+               break;
+
+           case NT_NE:
+               /* != */
+               fprintf (F, "!= ");
+               break;
+
+           case NT_LT:
+               /* < */
+               fprintf (F, "< ");
+               break;
+
+           case NT_LE:
+               /* <= */
+               fprintf (F, "<= ");
+               break;
+
+           case NT_GT:
+               /* > */
+               fprintf (F, "> ");
+               break;
+
+           case NT_GE:
+               /* >= */
+               fprintf (F, ">= ");
+               break;
+
+           default:
+               Internal ("Unknown node type: %04X", E->NT);
+               break;
+
+       }
+    }
+}
+
+