/*
    Clif - A C-like Interpreter Framework
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 T. Hruz, L. Koren
    1998 L. Koren

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

/*
 * parser.h
 *
 * Definition of parser's variables.
 */


#ifndef _PARSER_H
#define _PARSER_H

static int param_flag = 0;	/* Flag during parsing of parameters. */
static int atom_type_flag = 0;	/* Flag of type - pointer, atom. */

struct var_s
{
  char *adr;
  int offset;
  char *name;
} variable[256];		/* Structure of the absolute address
				   or offset of the actual variable in
				   l_value and its name. */
static int it_is_in_case = 0;   /* Flag if the integer constant is */
				/* a label. */
static char *jmp1;		/* Pointer to the beginning of code in */
				/* for loop. */
				/* It is an address between the expr1 */
				/* and the expr2. (See manual). */

/* Flag for the first subscript. It needs special action. */
static int subscript_flag[256];

static int is_address = 0;	/* Flag for unary_expression address
				   operand. */


/* Flag for structure or union field. True if it the field is not the
   first one (e.g. a.b.c); false for first one (e.g. a.b). */
static int struct_union_field[256];

static char *or_jmp[256], *and_jmp[256]; /* They are used for
					    backpatching of && and ||
					    expressions.  */

int main_defined;		/* Set if main is defined. */

static int initialize_only;	/* Set when there is a need for
				   initialization of variables.  */

static int full_bracketing;	/* Flag for proper code generation for
				   fully  bracketed initialization. */

static int aggregate_memory_size[256]; /* Each subtype is remembered
					  during initialization and
					  checked if it has the right
					  number of initializers. if
					  not, they are completed by
					  zeros. */

#define TYPE_CLEAR subscript_flag[set] = 0;\
struct_union_field[set] = 0;\
type_ac[set] = 0; type_com[set--] = NULL; \
if (0 > set) \
  error_message (5003);

#define SET_ADDRESS variable[set].adr = NULL;	\
variable[set].offset = 0;

#define FUNCTION_PROLOGUE GEN_PUSHb; GENCODE;\
GEN_PUSHt; GENCODE;\
GEN_MOVt; GENCODE;\
GEN_MOVbs; GENCODE;

#define FUNCTION_EPILOGUE GEN_MOVsb; GENCODE;\
GEN_POPt; GENCODE;\
GEN_POPb; GENCODE;\
GEN_RET; GENCODE;

#define DELETE_SUBSCRIPT while (-1 != dim[poc])\
dim[poc--] = -1;

#define OFFSET_LAST_ADD 				\
if (variable[set].offset || variable[set].adr != NULL) 	\
{ 							\
  struct_union_field[set] > 0 ? 			\
    struct_union_field[set]-- : 			\
    struct_union_field[set]; 				\
  if (struct_union_field[set]) 				\
    { 							\
      GEN_ADDi; GENCODE; 				\
    } 							\
  struct_union_field[set] = 0; 				\
}

#define OFFSET_LAST_ADD_ARRAY			\
if (struct_union_field[set])			\
  {						\
    GEN_ADDi; GENCODE; 				\
  }						\
struct_union_field[set] = 0;

#define ERROR_P if (error_count)		\
                  break;

#define MOV_P (((struct OPERAND_0_mi *)last_instr)->major == MOV)

#define POPA_P (((struct OPERAND_0_mi *)last_instr)->major == POPA)

#define PUSHA_P (((struct OPERAND_0_ma *)last_instr)->major == PUSHA)

#define RESET_CODE_GENERATION_BEGINNING					\
kodp = kodp1; pc = kodp; current_instr = kodp; last_instr = kodp;

#define SET_CODE_GENERATION_BEGINNING		\
kodp1 = kodp; pc = kodp;

#endif /* _PARSER_H */
