/*
    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.

*/
/*
 * type.h
 *
 * Internal compiler representation of types.
 */

#ifndef TYPE_H
#define TYPE_H

#define INTERNAL_TYPE(SYMBOL, VALUE) SYMBOL=VALUE,

enum intern_arit_class {
  INTERNAL_TYPE(UNUSED_AC, 0)
  INTERNAL_TYPE(VID, 0x1)	/* Void */
  INTERNAL_TYPE(CHR, 0x2)	/* Char */
  INTERNAL_TYPE(SHORT_AC, 0x4)	/* Short */
  INTERNAL_TYPE(INTEGER, 0x8)	/* Integer */
  INTERNAL_TYPE(LONG_AC, 0x10)	/* Long */
  INTERNAL_TYPE(FLT, 0x20)	/* Float */
  INTERNAL_TYPE(DOUB, 0x40)	/* Double */
  INTERNAL_TYPE(SIGNED_AC, 0x80) /* Signed */
  INTERNAL_TYPE(UNSIGNED_AC, 0x100) /* Unsigned */

  LAST_AND_UNUSED_ARIT_CLASS
};

#define PAR 512			/* Formal parameter. */
#define VAR 768			/* Local variable. */

enum intern_func_class {
  INTERNAL_TYPE(SIMPLE, 1024)
  INTERNAL_TYPE(ARRAY, 1025)
  INTERNAL_TYPE(LIB, 1026)
  INTERNAL_TYPE(TYPE, 1027)	/* Flag for typedef. */
  INTERNAL_TYPE(POINTER, 1028)	/* Pointer flag. */
  INTERNAL_TYPE(STRUCT_FC, 1029) /* Structure flag. */
  INTERNAL_TYPE(UNION_FC, 1030)	/* Union flag. */
  INTERNAL_TYPE(ENUM_FC, 1031)	/* Enum flag. */
  INTERNAL_TYPE(LOCAL, 2048)	/* Local functions or variables. */
  INTERNAL_TYPE(REMOTE_F, 2049)	/* Remote functions. */

  LAST_AND_UNUSED_FUNC_CLASS
};

#define YES 2050
#define NOT_DEFINED -2		/* Not defined range for arrays. */

                    /* 
		     * Global types 
		     */
enum global_type {
#define GLOBAL_TYPE(SYMBOL, VALUE) SYMBOL=VALUE,

  GLOBAL_TYPE(INTEGERS, 1280)	/* Simple integer */
  GLOBAL_TYPE(UINTEGERS, 1281)
  GLOBAL_TYPE(LINTEGERS, 1282)
  GLOBAL_TYPE(LUINTEGERS, 1283)
  GLOBAL_TYPE(SINTEGERS, 1284)
  GLOBAL_TYPE(SUINTEGERS, 1285)
  GLOBAL_TYPE(DOUBS, 1286)	/* Simple double */
  GLOBAL_TYPE(LDOUBS, 1287)
  GLOBAL_TYPE(FLTS, 1288)	/* Simple float */
  GLOBAL_TYPE(CHRS, 1289)	/* Simple char */
  GLOBAL_TYPE(SCHRS, 1290)
  GLOBAL_TYPE(UCHRS, 1291)
  GLOBAL_TYPE(INTEGERAR, 1536)    /* Array of integers */
  GLOBAL_TYPE(DOUBAR, 1537)       /* Array of doubles */
  GLOBAL_TYPE(FLTAR, 1538)        /* Array of floats */
  GLOBAL_TYPE(CHRAR, 1539)        /* Array of chars */

  LAST_AND_UNUSED_GLOBAL_TYPE
#undef GLOBAL_TYPE
};

enum type_qual {
#define TYPE_QUAL(SYMBOL, VALUE) SYMBOL=VALUE,

  TYPE_QUAL(CONST_TQ, 4096)
  TYPE_QUAL(VOLATILE_TQ, 4097)
  TYPE_QUAL(UNDEF_TQ, 4098)

  LAST_AND_UNUSED_TYPE_QUAL
#undef TYPE_QUAL
};

enum storage_class_specifier {
#define SC_SPEC(SYMBOL, VALUE) SYMBOL=VALUE,
  SC_SPEC(TYPEDEF_SC, 8192)
  SC_SPEC(EXTERN_SC, 8193)
  SC_SPEC(EXPORT_SC, 8194)
  SC_SPEC(STATIC_SC, 8195)
  SC_SPEC(AUTO_SC, 8196)
  SC_SPEC(REGISTER_SC, 8197)
  SC_SPEC(UNSPEC_SC, 8198)

  LAST_AND_UNUSED_SC_SPEC
#undef SC_SPEC
};


#define POINTER_P(a) (POINTER == (a)->attribute.function_class)
#define STRUCT_P(a) (STRUCT_FC == (a)->attribute.function_class)
#define UNION_P(a) (UNION_FC == (a)->attribute.function_class)
#define ENUM_P(a) (ENUM_FC == (a)->attribute.function_class)
#define ARRAY_P(a) (ARRAY == (a)->attribute.function_class)
#define SIMPLE_P(a) (SIMPLE == (a)->attribute.function_class)
#define LOCAL_P(a) (LOCAL == (a)->attribute.function_class)
#define REMOTE_P(a) (REMOTE_F == (a)->attribute.function_class)

#define TYPEDEF_P(type) 					\
(TYPEDEF_SC == (type)->attribute.storage_class_specifier)
#define EXTERN_P(type)						\
  (EXTERN_SC == (type)->attribute.storage_class_specifier)
#define EXPORT_P(type)						\
  (EXPORT_SC == (type)->attribute.storage_class_specifier)
#define STATIC_P(type)						\
  (STATIC_SC == (type)->attribute.storage_class_specifier)
#define AUTO_P(type)						\
  (AUTO_SC == (type)->attribute.storage_class_specifier)
#define REGISTER_P(type)					\
  (REGISTER_SC == (type)->attribute.storage_class_specifier)
#define UNSPEC_P(type)						\
  (UNSPEC_SC == (type)->attribute.storage_class_specifier)

#define VOID_P(type) (VID & (type)->attribute.arit_class)
#define CHAR_P(type) (CHR & (type)->attribute.arit_class)
#define SHORT_P(type) (SHORT_AC & (type)->attribute.arit_class)
#define INTEGER_P(type) (INTEGER & (type)->attribute.arit_class)
#define LONG_P(type) (LONG_AC & (type)->attribute.arit_class)
#define FLOAT_P(type) (FLT & (type)->attribute.arit_class)
#define DOUBLE_P(type) (DOUB & (type)->attribute.arit_class)
#define SIGNED_P(type) (SIGNED_AC & (type)->attribute.arit_class)
#define UNSIGNED_P(type) (UNSIGNED_AC & (type)->attribute.arit_class)
#define UNUSED_P(type) (UNUSED_AC == (type)->attribute.arit_class)

#define TYPES_EQ_P(type1, type2) \
((type1)->attribute.arit_class & (type2)->attribute.arit_class)

#define CONST_P(type) (CONST_TQ == (type)->attribute.type_qualifier)
#define UNDEF_P(type) (UNDEF_TQ == (type)->attribute.type_qualifier)

#endif /* TYPE_H */
