X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fexprnode.c;h=8bffe688fcc09c4d3955017c30cb85665af1d6be;hb=923ae328a53d95390815c73b390165e85c06af01;hp=d8bc2eda02a50c16f5ecb5482bb1737305256619;hpb=2bcb747b585b1a6baef6a1f49ca7f4c965fd78c1;p=cc65 diff --git a/src/cc65/exprnode.c b/src/cc65/exprnode.c index d8bc2eda0..8bffe688f 100644 --- a/src/cc65/exprnode.c +++ b/src/cc65/exprnode.c @@ -33,6 +33,11 @@ +/* common */ +#include "check.h" + +/* cc65 */ +#include "error.h" #include "exprnode.h" @@ -43,14 +48,433 @@ -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; + + } + } }