/*****************************************************************************/
/*                                                                           */
/*                                exprdefs.h                                 */
/*                                                                           */
/*                        Expression tree definitions                        */
/*                                                                           */
/*                                                                           */
/*                                                                           */
/* (C) 1998-2012, Ullrich von Bassewitz                                      */
/*                Roemerstrasse 52                                           */
/*                D-70794 Filderstadt                                        */
/* EMail:         uz@cc65.org                                                */
/*                                                                           */
/*                                                                           */
/* This software is provided 'as-is', without any expressed or implied       */
/* warranty.  In no event will the authors be held liable for any damages    */
/* arising from the use of this software.                                    */
/*                                                                           */
/* Permission is granted to anyone to use this software for any purpose,     */
/* including commercial applications, and to alter it and redistribute it    */
/* freely, subject to the following restrictions:                            */
/*                                                                           */
/* 1. The origin of this software must not be misrepresented; you must not   */
/*    claim that you wrote the original software. If you use this software   */
/*    in a product, an acknowledgment in the product documentation would be  */
/*    appreciated but is not required.                                       */
/* 2. Altered source versions must be plainly marked as such, and must not   */
/*    be misrepresented as being the original software.                      */
/* 3. This notice may not be removed or altered from any source              */
/*    distribution.                                                          */
/*                                                                           */
/*****************************************************************************/



#ifndef EXPRDEFS_H
#define EXPRDEFS_H



/*****************************************************************************/
/*                                   Data                                    */
/*****************************************************************************/



/* Expression type masks */
#define EXPR_TYPEMASK           0xC0
#define EXPR_BINARYNODE         0x00
#define EXPR_UNARYNODE          0x40
#define EXPR_LEAFNODE           0x80

/* Type of expression nodes */
#define EXPR_NULL               0x00    /* Internal error or NULL node */

/* Leaf node codes */
#define EXPR_LITERAL            (EXPR_LEAFNODE | 0x01)
#define EXPR_SYMBOL             (EXPR_LEAFNODE | 0x02)
#define EXPR_SECTION            (EXPR_LEAFNODE | 0x03)
#define EXPR_SEGMENT            (EXPR_LEAFNODE | 0x04)  /* Linker only */
#define EXPR_MEMAREA            (EXPR_LEAFNODE | 0x05)  /* Linker only */
#define EXPR_ULABEL             (EXPR_LEAFNODE | 0x06)  /* Assembler only */

/* Binary operations, left and right hand sides are valid */
#define EXPR_PLUS               (EXPR_BINARYNODE | 0x01)
#define EXPR_MINUS              (EXPR_BINARYNODE | 0x02)
#define EXPR_MUL                (EXPR_BINARYNODE | 0x03)
#define EXPR_DIV                (EXPR_BINARYNODE | 0x04)
#define EXPR_MOD                (EXPR_BINARYNODE | 0x05)
#define EXPR_OR                 (EXPR_BINARYNODE | 0x06)
#define EXPR_XOR                (EXPR_BINARYNODE | 0x07)
#define EXPR_AND                (EXPR_BINARYNODE | 0x08)
#define EXPR_SHL                (EXPR_BINARYNODE | 0x09)
#define EXPR_SHR                (EXPR_BINARYNODE | 0x0A)
#define EXPR_EQ                 (EXPR_BINARYNODE | 0x0B)
#define EXPR_NE                 (EXPR_BINARYNODE | 0x0C)
#define EXPR_LT                 (EXPR_BINARYNODE | 0x0D)
#define EXPR_GT                 (EXPR_BINARYNODE | 0x0E)
#define EXPR_LE                 (EXPR_BINARYNODE | 0x0F)
#define EXPR_GE                 (EXPR_BINARYNODE | 0x10)
#define EXPR_BOOLAND            (EXPR_BINARYNODE | 0x11)
#define EXPR_BOOLOR             (EXPR_BINARYNODE | 0x12)
#define EXPR_BOOLXOR            (EXPR_BINARYNODE | 0x13)
#define EXPR_MAX                (EXPR_BINARYNODE | 0x14)
#define EXPR_MIN                (EXPR_BINARYNODE | 0x15)

/* Unary operations, right hand side is empty */
#define EXPR_UNARY_MINUS        (EXPR_UNARYNODE | 0x01)
#define EXPR_NOT                (EXPR_UNARYNODE | 0x02)
#define EXPR_SWAP               (EXPR_UNARYNODE | 0x03)
#define EXPR_BOOLNOT            (EXPR_UNARYNODE | 0x04)
#define EXPR_BANK               (EXPR_UNARYNODE | 0x05)

#define EXPR_BYTE0              (EXPR_UNARYNODE | 0x08)
#define EXPR_BYTE1              (EXPR_UNARYNODE | 0x09)
#define EXPR_BYTE2              (EXPR_UNARYNODE | 0x0A)
#define EXPR_BYTE3              (EXPR_UNARYNODE | 0x0B)
#define EXPR_WORD0              (EXPR_UNARYNODE | 0x0C)
#define EXPR_WORD1              (EXPR_UNARYNODE | 0x0D)
#define EXPR_FARADDR            (EXPR_UNARYNODE | 0x0E)
#define EXPR_DWORD              (EXPR_UNARYNODE | 0x0F)
#define EXPR_NEARADDR           (EXPR_UNARYNODE | 0x10)



/* The expression node itself */
typedef struct ExprNode ExprNode;
struct ExprNode {
    unsigned char           Op;         /* Operand/Type */
    ExprNode*               Left;       /* Left leaf */
    ExprNode*               Right;      /* Right leaf */
    struct ObjData*         Obj;        /* Object file reference (linker) */
    union {
        long                IVal;       /* If this is a int value */
        struct SymEntry*    Sym;        /* If this is a symbol */
        unsigned            SecNum;     /* If this is a section and Obj != 0 */
        unsigned            ImpNum;     /* If this is an import and Obj != 0 */
        struct Import*      Imp;        /* If this is an import and Obj == 0 */
        struct MemoryArea*  Mem;        /* If this is a memory area */
        struct Segment*     Seg;        /* If this is a segment */
        struct Section*     Sec;        /* If this is a section and Obj == 0 */
    } V;
};



/* Macros to determine the expression type */
#define EXPR_NODETYPE(Op)       ((Op) & EXPR_TYPEMASK)
#define EXPR_IS_LEAF(Op)        (EXPR_NODETYPE (Op) == EXPR_LEAFNODE)
#define EXPR_IS_UNARY(Op)       (EXPR_NODETYPE (Op) == EXPR_UNARYNODE)
#define EXPR_IS_BINARY(OP)      (EXPR_NODETYPE (Op) == EXPR_BINARYNODE)



/*****************************************************************************/
/*                                   Code                                    */
/*****************************************************************************/



void DumpExpr (const ExprNode* Expr, const ExprNode* (*ResolveSym) (const struct SymEntry*));
/* Dump an expression tree to stdout */



/* End of exprdefs.h */

#endif
