312 lines
12 KiB
C
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 */
|