/* l2xisdcl.c LTX2X declaration analysis */
/* Written by: Peter Wilson, CUA
[email protected] */
/* This code is partly based on algorithms presented by Ronald Mak in */
/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
#include <stdio.h>
#include "l2xicmon.h"
#include "l2xierr.h"
#include "l2xiscan.h"
#include "l2xisymt.h"
#include "l2xiidbg.h"
/* EXTERNALS */
extern int line_number;
extern TOKEN_CODE token;
/* GLOBALS */
char buffer[MAX_PRINT_LINE_LENGTH];
char *defn_names[] = {
#define dfntc(a, b) b,
#include "l2xidftc.h"
#undef dfntc
};
char *form_names[] = {
#define fotc(a, b, c, d) d,
#define sotc(a, b, c, d)
#define sftc(a, b, c, d) d,
#include "l2xisftc.h"
#undef fotc
#undef sotc
#undef sftc
};
/* ANALYSIS */
/***************************************************************************/
/* analyze_const_defn(idp) Analyze a constant definition */
analyze_const_defn(idp)
SYMTAB_NODE_PTR idp; /* constant id */
{
char *bp;
if (DEBUG < Danalyze) return;
/* the name */
sprintf(buffer, ">> id = %s\n", idp->name);
debug_print(buffer);
sprintf(buffer, ">> address = %d\n", idp);
/* definition and value */
sprintf(buffer, ">> defn = %s, value = ", defn_names[idp->defn.key]);
bp = buffer + strlen(buffer);
if ((idp->typep == integer_typep) || (idp->typep->form == ENUM_FORM))
sprintf(bp, "%d\n", idp->defn.info.constant.value.integer);
else if (idp->typep == real_typep)
sprintf(bp, "%g\n", idp->defn.info.constant.value.real);
else if (idp->typep->form == ARRAY_FORM) /* ????????????????????????? */
sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp);
else if (idp->typep->form == STRING_FORM)
sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp);
debug_print(buffer);
/* and type. careful as an enum type will get into an infinite loop */
if (idp->typep->form != ENUM_FORM) analyze_type(idp->typep, FALSE);
} /* end analyze_const_defn */
/***************************************************************************/
/***************************************************************************/
/* analyze_type_defn(idp) Analyze a type definition */
analyze_type_defn(idp)
SYMTAB_NODE_PTR idp; /* id */
{
char *bp;
if (DEBUG < Danalyze) return;
/* the type's name, definition ... */
sprintf(buffer, ">>id = %s\n", idp->name);
debug_print(buffer);
sprintf(buffer, ">> address = %d\n", idp);
debug_print(buffer);
sprintf(buffer, ">> defn = %s\n", defn_names[idp->defn.key]);
/* print_line(buffer); */
debug_print(buffer);
/* and type */
analyze_type(idp->typep, TRUE);
} /* end analyze_type_defn */
/***************************************************************************/
/***************************************************************************/
/* analyze_type(tp, verbose_flag) Analyze a type definition */
analyze_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
char *bp;
if (DEBUG < Danalyze) return;
if (tp == NULL) return;
/* the form, byte size (and name) */
sprintf(buffer, ">> form = %s, size = %d bytes, type id = ",
form_names[tp->form], tp->size);
bp = buffer + strlen(buffer);
if (tp->type_idp != NULL)
sprintf(bp, "%s\n", tp->type_idp->name);
else {
sprintf(bp, "<unnamed type>\n");
verbose_flag = TRUE;
}
debug_print(buffer);
/* do the appropriate analysus */
switch (tp->form) {
case ENUM_FORM: {
analyze_enum_type(tp, verbose_flag);
break;
}
case SUBRANGE_FORM: {
analyze_subrange_type(tp, verbose_flag);
break;
}
case ARRAY_FORM: {
analyze_array_type(tp, verbose_flag);
break;
}
case STRING_FORM: {
verbose_flag = TRUE;
analyze_string_type(tp, verbose_flag);
break;
}
case BOUND_FORM: {
analyze_bound_type(tp, verbose_flag);
break;
}
case ENTITY_FORM: {
analyze_entity_type(tp, verbose_flag);
break;
}
case BAG_FORM:
case LIST_FORM:
case SET_FORM: {
analyze_bls_type(tp, verbose_flag);
break;
}
default: {
break;
}
} /* end switch */
} /* end analyze_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_enum_type(tp, verbose_flag) Analyze an enumeration type */
analyze_enum_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
/* loop to analyze each enum constant as a constant defn */
debug_print(">> -- Enum Constants --\n");
for (idp = tp->info.enumeration.const_idp; idp != NULL; idp = idp->next) {
analyze_const_defn(idp);
}
} /* end analyze_enum_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_subrange_type(tp, verbose_flag) Analyze a subrange type */
analyze_subrange_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
sprintf(buffer, ">> min value = %d, max value = %d\n",
tp->info.subrange.min, tp->info.subrange.max);
debug_print(buffer);
debug_print(">> -- Range Type -- \n");
analyze_type(tp->info.subrange.range_typep, FALSE);
} /* end analyze_subrange_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_bound_type(tp, verbose_flag) Analyze a bound type */
analyze_bound_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
sprintf(buffer, ">> min value = %d, max value = %d\n",
tp->info.bound.min, tp->info.bound.max);
debug_print(buffer);
debug_print(">> -- Bound Type -- \n");
analyze_type(tp->info.bound.bound_typep, FALSE);
} /* end analyze_bound_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_array_type(tp, verbose_flag) Analyze an array type */
analyze_array_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
sprintf(buffer, ">> element count = %d\n",
tp->info.array.elmt_count);
debug_print(buffer);
sprintf(buffer, ">> index limits = %d to %d\n",
tp->info.array.min_index, tp->info.array.max_index);
debug_print(buffer);
debug_print(">> -- INDEX TYPE -- \n");
analyze_type(tp->info.array.index_typep, FALSE);
debug_print(">> -- ELEMENT TYPE -- \n");
analyze_type(tp->info.array.elmt_typep, FALSE);
} /* end analyze_array_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_bls_type(tp, verbose_flag) Analyze a bag, etc type */
analyze_bls_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
sprintf(buffer, ">> element count = %d\n",
tp->info.dynagg.elmt_count);
debug_print(buffer);
sprintf(buffer, ">> index limits = %d to %d\n",
tp->info.dynagg.min_index, tp->info.dynagg.max_index);
debug_print(buffer);
debug_print(">> -- INDEX TYPE -- \n");
analyze_type(tp->info.dynagg.index_typep, FALSE);
debug_print(">> -- ELEMENT TYPE -- \n");
analyze_type(tp->info.dynagg.elmt_typep, FALSE);
} /* end analyze_bls_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_string_type(tp, verbose_flag) Analyze a string type */
analyze_string_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
sprintf(buffer, ">> maximum length = %d\n",
tp->info.string.max_length);
debug_print(buffer);
sprintf(buffer, ">> length = %d\n",
tp->info.string.length);
debug_print(buffer);
return;
} /* end analyze_string_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_entity_type(tp, verbose_flag) Analyze an entity type */
analyze_entity_type(tp, verbose_flag)
TYPE_STRUCT_PTR tp; /* pointer to type structure */
BOOLEAN verbose_flag; /* TRUE for verbose analysis */
{
SYMTAB_NODE_PTR idp; /* id */
if (DEBUG < Danalyze) return;
if (!verbose_flag) return;
/* loop to analyze each attribute as a variable decl */
debug_print(">> -- Attributes -- \n");
for (idp = tp->info.entity.attribute_symtab; idp != NULL; idp = idp->next) {
analyze_var_decl(idp);
}
} /* end analyze_entity_type */
/***************************************************************************/
/***************************************************************************/
/* analyze_var_decl(idp) Analyze a variable declaration */
analyze_var_decl(idp)
SYMTAB_NODE_PTR idp; /* id */
{
if (DEBUG < Danalyze) return;
/* the name, definition and offset */
sprintf(buffer, ">> id = %s\n", idp->name);
debug_print(buffer);
sprintf(buffer, ">> address = %d\n", idp);
debug_print(buffer);
sprintf(buffer, ">> defn = %s, offset = %d\n",
defn_names[idp->defn.key], idp->defn.info.data.offset);
/* print_line(buffer); */
debug_print(buffer);
/* and type */
analyze_type(idp->typep, FALSE);
} /* end analyze_var_decl */
/***************************************************************************/
/***************************************************************************/
/* analyze_block(code_segment) a dummy procedure */
analyze_block(code_segment)
char *code_segment;
{
return;
} /* end analyze_block */
/***************************************************************************/
/***************************************************************************/
/* analyze_routine_header(rtn_idp) a dummy procedure */
analyze_routine_header(rtn_idp)
SYMTAB_NODE_PTR rtn_idp;
{
return;
} /* end analyze_routine_header */
/***************************************************************************/
/***************************************************************************/