/*
 * ACME - a crossassembler for producing 6502/65c02/65816 code.
 * Copyright (C) 1998 Marco Baye
 * Have a look at "acme.c" for further info
 */

/*
 * ALU definitions
 */

#ifndef alu_H
#define alu_H

#include "platform.h"
#include <math.h>

/*
 * Value flags
 */

/* There is an unclosed parenthese left */
#define MVALUE_PARENTH  (1u << 5)
/* There wasn't given any value at all */
#define MVALUE_NONE     (1u << 4)
/* Value is defined (if this is cleared, the value will be zero) */
#define MVALUE_DEFINED  (1u << 3)
/* Value was defined even when first used */
#define MVALUE_UNSURE   (1u << 2)
/* Size of value */
#define MVALUE_SIZE     (3u << 0)
static int ffValue = 0; /* Value flags (returned by valueparser) */

/* Sizes (unspecified, 1 byte, 2 bytes, 3 bytes) */
#define MVALUESIZE_UK   (0u << 0)
#define MVALUESIZE_08   (1u << 0)
#define MVALUESIZE_16   (2u << 0)
#define MVALUESIZE_24   (3u << 0)

/*
 * Operator priorities (must be > 0)
 *
 * PRIO_NOT        13   !v      Bitwise NOT             (also NOT)
 * PRIO_POWEROF    12   v^w     To the power of
 * PRIO_NEGATE     11   -v      Negate
 * PRIO_MULTIPLY   10   v*w     Multiply
 * PRIO_DIVIDE     10   v/w     Integer-Divide
 * PRIO_MODULO     10   v%w     Remainder of IntDiv     (also MOD)
 * PRIO_ADD         9   v+w     Add
 * PRIO_SUBTRACT    9   v-w     Subtract
 * PRIO_SL          8   v<<w    Shift left              (also ASL, LSL)
 * PRIO_LSR         8   v>>w    Logical shift right     (also LSR)
 * PRIO_LOWBYTEOF   7   <v      Lowbyte  of
 * PRIO_HIGHBYTEOF  7   >v      Highbyte of
 * PRIO_BANKBYTEOF  7   ^v      Bankbyte of
 * PRIO_LE          6   v<=w    Lower or equal
 * PRIO_LT          6   v<w     Lower than
 * PRIO_GE          6   v>=w    Higher or equal
 * PRIO_GT          6   v>w     Higher than
 * PRIO_NOTEQUAL    5   v!=w    Not equal               (also <> and ><)
 * PRIO_EQUALS      4   v=w     Equals
 * PRIO_AND         3   v&w     Bitwise AND             (also AND)
 * PRIO_EXOR        2           Bitwise exclusive-OR    (also EOR, XOR)
 * PRIO_OR          1   v|w     Bitwise OR              (also OR)
 */

#define PRIO_NOT        13
#define PRIO_POWEROF    12
#define PRIO_NEGATE     11
#define PRIO_MULTIPLY   10
#define PRIO_DIVIDE     10
#define PRIO_MODULO     10
#define PRIO_ADD         9
#define PRIO_SUBTRACT    9
#define PRIO_SL          8
#define PRIO_LSR         8
#define PRIO_LOWBYTEOF   7
#define PRIO_HIGHBYTEOF  7
#define PRIO_BANKBYTEOF  7
#define PRIO_LE          6
#define PRIO_LT          6
#define PRIO_GE          6
#define PRIO_GT          6
#define PRIO_NOTEQUAL    5
#define PRIO_EQUALS      4
#define PRIO_AND         3
#define PRIO_EXOR        2
#define PRIO_OR          1

#define PRIO_SUBVALUE    0
/*
 * When inside parentheses, the valueparser does not need to care about
 * operators outside, so this last value has to be the *smallest* (not the
 * biggest as one might think).
 */

/*
 * Operator handles
 *
 * Unary operators don't have handles; they are always processed immediately.
 * Because of this, there are no HOP_NOT, HOP_NEG, HOP_LOW, HOP_HIGH and
 * HOP_BANK values in the following list.
 * There is no HOP_ASR either, because this operation is no longer supported.
 */

enum {
  HOP_ADD     ,
  HOP_AND     ,
  HOP_DIVIDE  ,
  HOP_EQUALS  ,
  HOP_EXOR    ,
  HOP_GE      ,
  HOP_GT      ,
  HOP_LE      ,
  HOP_LSR     ,
  HOP_LT      ,
  HOP_MODULO  ,
  HOP_MULTIPLY,
  HOP_NONE    ,
  HOP_NOTEQUAL,
  HOP_OR      ,
  HOP_POWEROF ,
  HOP_SL      ,
  HOP_SUBTRACT,
  HOP_RIGHTPARENTHESIS
};

/*
 * Prototypes
 */
static int   VP_SizeBits = 0;/* SizeBits and its bit values (for typecast) */
#define SIZEBITUK       1
#define SIZEBIT08       2
#define SIZEBIT16       4
#define SIZEBIT24       8
static int   hOp_Now;/* Handle of last operator read. Because of the operators'
priorities it is sometimes necessary to re-parse an operator that has been read
once before. Because re-reading multi-character operators (like NOT, AND, OR)
requires ugly programming, this variable stores the last operator's handle.*/
static int   nLevel;/* Recursion depth of value parser */
static Value FN_ALU_GetValue_Liberal(int);
static Value FN_ALU_GetValue_Medium(void);
static Value FN_ALU_GetValue_Strict(void);
static Value FN_ALU_PVR(int);
static int   FN_ALU_PVR_GetOp(void);
static Value FN_ALU_ReadSublevelValue(void);
static Value FN_ALU_ReadProgramCounter(void);
static Value FN_ALU_ReadLocalLabel(void);
static Value FN_ALU_ReadGlobalOrNOT(void);
static int   FN_ALU_PVR_LT(void);
static int   FN_ALU_PVR_HT(void);
static int   FN_ALU_PVR_EM(void);
static int   FN_ALU_PVR_KZ(void);
static Value FN_ALU_ReadCharValue(void);
static Value FN_ALU_ReadBinaryValue(void);
static Value FN_ALU_ReadHexadecimalValue(void);
static Value FN_ALU_ReadOctalValue(void);
static Value FN_ALU_ReadDecimalValue(void);
static Value FN_ALU_GetLabelValue(Sixteen, int);

#endif
