]> git.sur5r.net Git - cc65/blobdiff - src/cc65/exprnode.c
Fixed a bug
[cc65] / src / cc65 / exprnode.c
index d8bc2eda02a50c16f5ecb5482bb1737305256619..8bffe688fcc09c4d3955017c30cb85665af1d6be 100644 (file)
 
 
 
+/* common */
+#include "check.h"
+
+/* cc65 */
+#include "error.h"
 #include "exprnode.h"
 
 
 
 
 
-void InitExprNode (ExprNode* E)
+ExprNode* InitExprNode (ExprNode* E, nodetype_t NT, type* Type,
+                       int LValue, struct ExprHeap* Owner)
 /* Initialize a new expression node */
 {
-    E->Left    = 0;
-    E->Right   = 0;
-    E->NT      = NT_NONE;
-    E->Type    = 0;
-    E->LValue  = 0;
+    /* Intialize basic data */
+    E->MData.Owner = Owner;
+    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);
+
+    /* Return the node just initialized */
+    return E;
+}
+
+
+
+void* GetItem (ExprNode* N, unsigned Index)
+/* Return one of the items from the nodes item list */
+{
+    return CollAt (&N->List, Index);
+}
+
+
+
+void AppendItem (ExprNode* N, void* Item)
+/* Append an item to the nodes item list */
+{
+    CollAppend (&N->List, Item);
+}
+
+
+
+void SetItem (ExprNode* N, void* Item, unsigned Index)
+/* Set a specific node item. The item list is filled with null pointers as
+ * needed.
+ */
+{
+    if (Index >= CollCount (&N->List)) {
+       /* Fill up with NULL pointers */
+               while (Index >= CollCount (&N->List)) {
+           CollAppend (&N->List, 0);
+       }
+       /* Append the new item */
+       CollAppend (&N->List, Item);
+    } else {
+       /* There is an item with this index, replace it */
+       CollReplace (&N->List, Item, Index);
+    }
+}
+
+
+
+ExprNode* GetNode (ExprNode* N, unsigned Index)
+/* Get one of the sub-nodes from the list */
+{
+    return GetNode (N, Index);
+}
+
+
+
+ExprNode* GetLeftNode (ExprNode* N)
+/* Get the left sub-node from the list */
+{
+    return GetNode (N, IDX_LEFT);
+}
+
+
+
+void SetLeftNode (ExprNode* Root, ExprNode* Left)
+/* Set the left node in Root */
+{
+    SetItem (Root, Left, IDX_LEFT);
+}
+
+
+
+ExprNode* GetRightNode (ExprNode* N)
+/* Get the right sub-node from the list */
+{
+    return GetNode (N, IDX_RIGHT);
+}
+
+
+
+void SetRightNode (ExprNode* Root, ExprNode* Right)
+/* Set the right node in Root */
+{
+    SetItem (Root, Right, IDX_RIGHT);
+}
+
+
+
+struct SymEntry* GetNodeSym (ExprNode* N)
+/* Get the symbol entry for a NT_SYM node */
+{
+    return (struct SymEntry*) GetItem (N, IDX_SYM);
+}
+
+
+
+void SetNodeSym (ExprNode* N, struct SymEntry* Sym)
+/* Set the symbol entry in a NT_SYM node */
+{
+    SetItem (N, Sym, IDX_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;
+
+       }
+    }
 }