stepcode/include/express/type.h

312 lines
12 KiB
C

#ifndef TYPE_H
#define TYPE_H
/** **********************************************************************
** Module: Type \file type.h
** Description: This module implements the type abstraction. It is
** rather unpleasant, since this abstraction is quite well suited
** to an object-oriented environment with inheritance.
**
************************************************************************/
/*
* This software was developed by U.S. Government employees as part of
* their official duties and is not subject to copyright.
*
* $Log: type.h,v $
* Revision 1.14 1997/09/19 18:25:10 dar
* small fix - removed multiple include
*
* Revision 1.13 1997/01/21 19:17:11 dar
* made C++ compatible
*
* Revision 1.12 1994/11/10 19:20:03 clark
* Update to IS
*
* Revision 1.11 1994/05/11 19:51:05 libes
* numerous fixes
*
* Revision 1.10 1993/10/15 18:48:24 libes
* CADDETC certified
*
* Revision 1.8 1993/03/19 20:43:45 libes
* add is_enum macro
*
* Revision 1.7 1993/01/21 19:48:25 libes
* fix bug in TYPEget_base_type
*
* Revision 1.6 1993/01/19 22:16:09 libes
* *** empty log message ***
*
* Revision 1.5 1992/09/16 18:23:45 libes
* added some functions for easier access to base types
*
* Revision 1.4 1992/08/18 17:12:41 libes
* rm'd extraneous error messages
*
* Revision 1.3 1992/06/08 18:06:24 libes
* prettied up interface to print_objects_when_running
*/
/*************/
/* constants */
/*************/
#define TYPE_NULL (Type)0
/** since we can't evaluate true size of many aggregates,
* prepare to grow them by chunks of this size */
#define AGGR_CHUNK_SIZE 30
/** these are all orthogonal types */
enum type_enum {
unknown_ = 0, /**< 0 catches uninit. errors */
special_, /**< placeholder, given meaning by it's owner, such as Type_Dont_Care, Type_Bad, Type_User_Def */
runtime_, /**< cannot be further determined until runtime */
integer_,
real_,
string_,
binary_,
boolean_,
logical_,
/* formals-only */
number_,
generic_,
/* aggregates */
aggregate_, /**< as a formal */
array_,
bag_,
set_,
list_,
last_aggregate_,/**< not real, just for easier computation */
oneof_,
/** while they are really used for different purposes, it might be worth considering collapsing entity_ and entity_list_ */
entity_, /**< single entity */
entity_list_, /**< linked list of entities */
enumeration_,
select_,
reference_, /**< something only defined by a base type, i.e., a type reference */
query_,
op_, /**< something with an operand */
inverse_, /**< is? an inverse */
identifier_, /**< simple identifier in an expression */
attribute_, /**< attribute reference (i.e., expr->u.variable) */
derived_, /**< ?*/
funcall_, /**< a function call and actual parameters */
self_
};
/*****************/
/* packages used */
/*****************/
#include <sc_export.h>
#include "expbasic.h" /* get basic definitions */
#include "symbol.h"
#include "object.h"
/************/
/* typedefs */
/************/
typedef struct TypeHead_ * TypeHead;
typedef struct TypeBody_ * TypeBody;
typedef enum type_enum TypeType;
/* provide a replacement for Class */
typedef enum type_enum Class_Of_Type;
typedef enum type_enum Class;
#define OBJget_class(typ) ((typ)->u.type->body->type)
#define CLASSinherits_from TYPEinherits_from
/****************/
/* modules used */
/****************/
#include "dict.h"
#include "entity.h"
#include "expr.h"
#include "scope.h"
/***************************/
/* hidden type definitions */
/***************************/
struct TypeHead_ {
Type head; /**< if we are a defined type this is who we point to */
struct TypeBody_ * body; /**< true type, ignoring defined types */
#if 0
/* if we are concerned about memory (over time) uncomment this and */
/* other references to refcount in parser and TYPEresolve. It is */
/* explained in TYPEresolve. */
int refcount;
#endif
};
struct TypeBody_ {
#if 1
struct TypeHead_ * head; /**< for debugging only */
#endif
enum type_enum type; /**< bits describing this type, int, real, etc */
struct {
unsigned unique : 1;
unsigned optional : 1;
unsigned fixed : 1;
unsigned shared : 1; /**< type is shared */
unsigned repeat : 1; /**< Expression is the number of repetitions of the previous Expression
* 10303-11:2004 production #203
* element = expression [ ':' repetition ] .
* TODO exp2cxx and exp2py do not use this! Are all use cases handled by libexppp?
*/
unsigned var : 1; /** denotes variable marked 'VAR' - i.e. one where changes are propagated back to the caller */
unsigned encoded : 1; /**< encoded string */
} flags;
Type base; /**< underlying base type if any can also contain true type if this type is a type reference */
Type tag; /**< optional tag */
/* a lot of the stuff below can be unionized */
Expression precision;
Linked_List list; /**< used by select_types and composed types, such as for a list of entities in an instance */
Expression upper;
Expression lower;
struct Scope_ * entity; /**< only used by entity types */
};
/********************/
/* global variables */
/********************/
/* Very commonly-used read-only types */
/* non-constant versions probably aren't necessary? */
extern SC_EXPRESS_EXPORT Type Type_Bad;
extern SC_EXPRESS_EXPORT Type Type_Unknown;
extern SC_EXPRESS_EXPORT Type Type_Dont_Care;
extern SC_EXPRESS_EXPORT Type Type_Runtime; /**< indicates that this object can't be
calculated now but must be deferred
until (the mythical) runtime */
extern SC_EXPRESS_EXPORT Type Type_Binary;
extern SC_EXPRESS_EXPORT Type Type_Boolean;
extern SC_EXPRESS_EXPORT Type Type_Enumeration;
extern SC_EXPRESS_EXPORT Type Type_Expression;
extern SC_EXPRESS_EXPORT Type Type_Aggregate;
extern SC_EXPRESS_EXPORT Type Type_Repeat;
extern SC_EXPRESS_EXPORT Type Type_Integer;
extern SC_EXPRESS_EXPORT Type Type_Number;
extern SC_EXPRESS_EXPORT Type Type_Real;
extern SC_EXPRESS_EXPORT Type Type_String;
extern SC_EXPRESS_EXPORT Type Type_String_Encoded;
extern SC_EXPRESS_EXPORT Type Type_Logical;
extern SC_EXPRESS_EXPORT Type Type_Set;
extern SC_EXPRESS_EXPORT Type Type_Attribute;
extern SC_EXPRESS_EXPORT Type Type_Entity;
extern SC_EXPRESS_EXPORT Type Type_Funcall;
extern SC_EXPRESS_EXPORT Type Type_Generic;
extern SC_EXPRESS_EXPORT Type Type_Identifier;
extern SC_EXPRESS_EXPORT Type Type_Oneof;
extern SC_EXPRESS_EXPORT Type Type_Query;
extern SC_EXPRESS_EXPORT Type Type_Self;
extern SC_EXPRESS_EXPORT Type Type_Set_Of_String;
extern SC_EXPRESS_EXPORT Type Type_Set_Of_Generic;
extern SC_EXPRESS_EXPORT Type Type_Bag_Of_Generic;
extern SC_EXPRESS_EXPORT struct freelist_head TYPEHEAD_fl;
extern SC_EXPRESS_EXPORT struct freelist_head TYPEBODY_fl;
extern SC_EXPRESS_EXPORT Error ERROR_corrupted_type;
/******************************/
/* macro function definitions */
/******************************/
#define TYPEHEAD_new() (struct TypeHead_ *)MEM_new(&TYPEHEAD_fl)
#define TYPEHEAD_destroy(x) MEM_destroy(&TYPEHEAD_fl,(Freelist *)(Generic)x)
#define TYPEBODY_new() (struct TypeBody_ *)MEM_new(&TYPEBODY_fl)
#define TYPEBODY_destroy(x) MEM_destroy(&TYPEBODY_fl,(Freelist *)(Generic)x)
#define TYPEis(t) ((t)->u.type->body->type)
#define TYPEis_identifier(t) ((t)->u.type->body->type == identifier_)
#define TYPEis_logical(t) ((t)->u.type->body->type == logical_)
#define TYPEis_boolean(t) ((t)->u.type->body->type == boolean_)
#define TYPEis_real(t) ((t)->u.type->body->type == real_)
#define TYPEis_integer(t) ((t)->u.type->body->type == integer_)
#define TYPEis_string(t) ((t)->u.type->body->type == string_)
#define TYPEis_expression(t) ((t)->u.type->body->type == op_)
#define TYPEis_oneof(t) ((t)->u.type->body->type == oneof_)
#define TYPEis_entity(t) ((t)->u.type->body->type == entity_)
#define TYPEis_enumeration(t) ((t)->u.type->body->type == enumeration_)
#define TYPEis_aggregate(t) ((t)->u.type->body->base)
#define TYPEis_aggregate_raw(t) ((t)->u.type->body->type == aggregate_)
#define TYPEis_array(t) ((t)->u.type->body->type == array_)
#define TYPEis_select(t) ((t)->u.type->body->type == select_)
#define TYPEis_reference(t) ((t)->u.type->body->type == reference_)
#define TYPEis_unknown(t) ((t)->u.type->body->type == unknown_)
#define TYPEis_runtime(t) ((t)->u.type->body->type == runtime_)
#define TYPEis_shared(t) ((t)->u.type->body->flags.shared)
#define TYPEis_optional(t) ((t)->u.type->body->flags.optional)
#define TYPEis_encoded(t) ((t)->u.type->body->flags.encoded)
#define TYPEget_symbol(t) (&(t)->symbol)
#define TYPEget_head(t) ((t)->u.type->head)
#define TYPEput_head(t,h) ((t)->u.type->head = (h))
#define TYPEget_body(t) ((t)->u.type->body)
#define TYPEput_body(t,h) ((t)->u.type->body = (h))
#define TYPEget_type(t) ((t)->u.type->body->type)
#define TYPEget_base_type(t) ((t)->u.type->body->base)
#define TYPEput_name(type,n) ((type)->symbol.name = (n))
#define TYPEget_name(type) ((type)->symbol.name)
#define TYPEget_where(t) ((t)->where)
#define TYPEput_where(t,w) (((t)->where) = w)
#define ENT_TYPEget_entity(t) ((t)->u.type->body->entity)
#define ENT_TYPEput_entity(t,ent) ((t)->u.type->body->entity = ent)
#define COMP_TYPEget_items(t) ((t)->u.type->body->list)
#define COMP_TYPEput_items(t,lis) ((t)->u.type->body->list = (lis))
#define COMP_TYPEadd_items(t,lis) LISTadd_all((t)->u.type->body->list, (lis));
#define ENUM_TYPEget_items(t) ((t)->symbol_table)
#define TYPEget_optional(t) ((t)->u.type->body->flags.optional)
#define TYPEget_unique(t) ((t)->u.type->body->flags.unique)
#define SEL_TYPEput_items(type,list) COMP_TYPEput_items(type, list)
#define SEL_TYPEget_items(type) COMP_TYPEget_items(type)
#define AGGR_TYPEget_upper_limit(t) ((t)->u.type->body->upper?(t)->u.type->body->upper:LITERAL_INFINITY)
#define AGGR_TYPEget_lower_limit(t) ((t)->u.type->body->lower?(t)->u.type->body->lower:LITERAL_ZERO)
#define TYPEget_enum_tags(t) ((t)->symbol_table)
#define TYPEget_clientData(t) ((t)->clientData)
#define TYPEput_clientData(t,d) ((t)->clientData = (d))
/***********************/
/* function prototypes */
/***********************/
extern SC_EXPRESS_EXPORT Type TYPEcreate_partial PROTO( ( struct Symbol_ *, Scope ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate PROTO( ( enum type_enum ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate_from_body_anonymously PROTO( ( TypeBody ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate_name PROTO( ( struct Symbol_ * ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate_nostab PROTO( ( struct Symbol_ *, Scope, char ) );
extern SC_EXPRESS_EXPORT TypeBody TYPEBODYcreate PROTO( ( enum type_enum ) );
extern SC_EXPRESS_EXPORT void TYPEinitialize PROTO( ( void ) );
extern SC_EXPRESS_EXPORT void TYPEcleanup PROTO( ( void ) );
extern SC_EXPRESS_EXPORT bool TYPEinherits_from PROTO( ( Type, enum type_enum ) );
extern SC_EXPRESS_EXPORT Type TYPEget_nonaggregate_base_type PROTO( ( Type ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_type PROTO( ( Type, Scope, struct Symbol_ * ) );
extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_tag PROTO( ( Type, Scope, struct Symbol_ * ) );
#endif /* TYPE_H */