/* %Z%%M% %I% %E% */ /* * Copyright (c) 1992, 1993, 1995 by Wayne C. Gramlich. * All rights reserved. * * Permission to use, copy, modify, distribute, and sell this software * for any purpose is hereby granted without fee provided that the above * copyright notice and this permission are retained. The author makes * no representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */ /* * This file contains the routines for manipulating Type_ref's and Type_refs's. */ #ifndef GEN_DEFS_H #include "gen_defs.h" #endif #ifndef HEAP_EXPORTS_H #include "heap_exports.h" #endif #ifndef LIBC_EXPORTS_H #include "libc_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef OUT_EXPORTS_H #include "out_exports.h" #endif #ifndef STR_EXPORTS_H #include "str_exports.h" #endif #ifndef TABLE_EXPORTS_H #include "table_exports.h" #endif #ifndef TYPE_DEFS_H #include "type_defs.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_CTYPE_H #include "unix_ctype.h" #endif #ifndef VECTOR_DEFS_H #include "vector_defs.h" #endif LOCAL int type_ref_compare(Type_ref, Type_ref, int); LOCAL int type_ref_is_in(Type_ref, Type_ref); LOCAL void type_ref_needed(Type_ref, Type_tables); LOCAL Type_ref_table type_ref_table_create(Heap); LOCAL void type_ref_table_dump(Type_ref_table, Stdio); LOCAL int type_refs_contains_parameter(Type_refs); LOCAL Type_refs type_refs_table_lookup(Type_ref_table); Type_tables type_tables_global; /* * Type_ref routines: */ /* * type_ref_compare(type_ref1, type_ref2, zilch) * This routine is returns <0, 0, or >0 depending upon whether * "type_ref1" is less than, equal to, or greater than "type_ref2". */ /* ARGSUSED */ LOCAL int type_ref_compare( Type_ref type_ref1, Type_ref type_ref2, int zilch) { int result; result = strcmp(type_ref1->name, type_ref2->name); if (result != 0) { return result; } result = type_refs_compare(type_ref1->parameters, type_ref2->parameters, 0); return result; } /* * type_ref_contains_parameter(type_ref) * This routine will return 1 if "type_ref" contains any parameterized * types. */ int type_ref_contains_parameter( Type_ref type_ref) { return type_ref_is_parameter(type_ref) || type_refs_contains_parameter(type_ref->parameters); } /* * type_ref_create(name, type_tables) * This routine will create and return a new type reference object * with a name of "name" using "type_tables". */ Type_ref type_ref_create( Str name, Type_tables type_tables) { Type_ref type_ref; type_ref = type_ref_parameters_create(name, type_refs_empty_create(type_tables), type_tables); return type_ref; } /* * type_ref_equal(type_ref1, type_ref2) * This routine will return 1 if "type_ref1" equals "type_ref2" and * 0 otherwise. */ int type_ref_equal( Type_ref type_ref1, Type_ref type_ref2) { return (type_ref_compare(type_ref1, type_ref2, 0) == 0); } /* * type_ref_gen(type_ref, gen) * This routine will output a type reference data structure for "type_ref" * to "gen". */ void type_ref_gen( Type_ref type_ref, Gen gen) { Type_refs parameters; int size; if (type_ref->generated) { return; } type_ref->generated = 1; parameters = type_ref->parameters; size = type_refs_size(parameters); if (size == 0) { gen_out(gen, "static type___reference %m__type__reference =\n", type_ref); gen_out(gen, "%\t{%\", 0, (type___reference **)0};\n", 1, type_ref->name); } else { type_refs_gen(parameters, gen); gen_out(gen, "static type___reference %m__type__reference = \n", type_ref); gen_out(gen, "%\t{%\", %d, %M__type__references};\n", 1, type_ref->name, size, parameters); } } /* * type_ref_hash(type_ref) * This routine will return a hash value for "type_ref". */ int type_ref_hash( Type_ref type_ref) { return (strhash(type_ref->name) + type_refs_hash(type_ref->parameters)); } /* * type_ref_is_in(type_ref, target_type_ref) * This routine will return 1 if "type_ref" occurs" anywhere in * "target_type_ref"; otherwise, 0 is returned. */ LOCAL int type_ref_is_in( Type_ref type_ref, Type_ref target_type_ref) { Type_ref parameter; Type_refs parameters; if (type_ref_equal(type_ref, target_type_ref)) { return 1; } parameters = target_type_ref->parameters; TYPE_REFS_LOOP(parameters, parameter) { if (type_ref_is_in(type_ref, parameter)) { return 1; } } return 0; } /* * type_ref_needed(type_ref, type_tables) * This routine will mark "type_ref" as needed in the output file. */ LOCAL void type_ref_needed( Type_ref type_ref, Type_tables type_tables) { if (!type_ref->needed) { type_ref->needed = 1; if (type_ref_is_routine(type_ref)) { Type_proto type_proto; type_proto = type_proto_from_type_ref(type_ref, type_tables); type_proto_needed(type_proto, type_tables); } type_refs_needed(type_ref->parameters, type_tables); } } /* * type_ref_is_parameter(type_ref) * This routine will return 1 if "type_ref" is a parameter type. */ int type_ref_is_parameter( Type_ref type_ref) { return isdigit(type_ref->name[0]); } /* * type_ref_is_parameterized(type_ref) * This routine will return 1 if "type_ref" has any parameters. */ int type_ref_is_parameterized( Type_ref type_ref) { return !type_refs_is_empty(type_ref->parameters); } /* * type_ref_is_routine(type_ref) * This routine will return 1 if "type_ref" is a routine procedure * variable type and 0 otherwise. */ int type_ref_is_routine( Type_ref type_ref) { return (strncmp(type_ref->name, "anonymous__", 11) == 0); } /* * type_ref_mangle(type_ref, out_file) * This routine will print out a mangled version of "type_ref" * to "out_file". */ void type_ref_mangle( Type_ref type_ref, Stdio out_file) { Str name; name = type_ref->name; out(out_file, type_ref_is_parameter(type_ref) ? "_%s": "%s", name); if (!type_refs_is_empty(type_ref->parameters)) { out(out_file, "__"); type_refs_mangle(type_ref->parameters, 1, out_file); } } /* * type_ref_print(type_ref, out_file) * This routine will print "type_ref" to "out_file". */ void type_ref_print( Type_ref type_ref, Stdio out_file) { Type_refs parameters; if (type_ref_is_parameter(type_ref)) { out(out_file, "PARAMETER_%s", type_ref->name); /* * Sigh, the code generator use %r to output routine types. * These types have to have the form `anonymousN' rather than * the expanded form. When you are having problems figuring * out anonymous types, reinsert the code below to improve the * error message. */ #ifdef PROBLEM } else if (type_ref_is_routine(type_ref)) { Type_proto type_proto; extern Type_tables type_tables_global; type_proto = type_proto_from_type_ref(type_ref, type_tables_global); out(out_file, "{"); type_proto_print(type_proto, -1, out_file); out(out_file, "}"); #endif /* PROBLEM */ } else { out(out_file, "%s", type_ref->name); } parameters = type_ref->parameters; if (!type_refs_is_empty(parameters)) { out(out_file, "["); type_refs_print(parameters, out_file); out(out_file, "]"); } } /* * type_ref_parameters_create(name, parameters, type_tables) * This routine will create and return a new type reference with * a name of "name" and parameters of "parameters" using "type_tables". */ Type_ref type_ref_parameters_create( Str name, Type_refs parameters, Type_tables type_tables) { Heap heap; Table(Type_ref, Type_ref) ref_table; Type_ref type_ref; Type_ref type_ref_key; Type_refs type_refs_key; Type_ref_table type_ref_table; /* Temporary: */ assert(!strequal(name, "unsigned__keyword")); type_ref_table = type_tables->type_ref_table; type_ref_key = type_ref_table->type_ref_key; type_ref_key->name = name; type_ref_key->parameters = parameters; ref_table = type_ref_table->ref_table; type_ref = table_lookup(Type_ref, Type_ref, ref_table, type_ref_key); if (type_ref == (Type_ref)0) { heap = type_ref_table->heap; type_ref = heap_allocate(heap, Type_ref); type_ref->generated = 0; type_ref->name = strdupl(name, heap); type_ref->needed = 0; type_ref->parameters = parameters; assert(table_insert(Type_ref, Type_ref, ref_table, type_ref, type_ref) == 0); type_refs_key = type_ref_table->type_refs_key; assert(vec_empty(Type_ref, type_refs_key->type_refs)); vec_append(Type_ref, type_refs_key->type_refs, type_ref); type_ref->type_refs = type_refs_table_lookup(type_ref_table); } else { assert(type_ref == type_refs_fetch(type_ref->type_refs, 0)); } return type_ref; } /* * type_ref_read(in_file, heap, type_tables) * This routine will read in and return a Type_ref from "in_file" using * "heap". */ Type_ref type_ref_read( Stdio in_file, Heap heap, Type_tables type_tables) { Str name; Type_ref type_ref; int is_routine; assert(type_tables != (Type_tables)0); out_marker_read(in_file, "type_ref"); is_routine = fgetc(in_file); if (is_routine) { Type_proto type_proto; type_proto = type_proto_read(in_file, heap, type_tables); type_ref = type_proto->type_ref; } else { Type_refs parameters; name = strread(in_file, heap); parameters = type_refs_read(in_file, heap, type_tables); type_ref = type_ref_parameters_create(name, parameters, type_tables); } return type_ref; } /* * type_ref_replace(type_ref, old_type_refs, new_type_refs, type_tables) * This routine will replace all occurances of "old_type_refs" with * "new_type_refs" for "type_ref" and return the resulting type * reference. */ Type_ref type_ref_replace( Type_ref type_ref, Type_refs old_type_refs, Type_refs new_type_refs, Type_tables type_tables) { int index; Type_ref old_type_ref; Type_refs parameters; int size; /* Do any needed substitution: */ if (type_ref_is_routine(type_ref)) { Type_proto type_proto; type_proto = type_proto_from_type_ref(type_ref, type_tables); type_proto = type_proto_replace(type_proto, old_type_refs, new_type_refs, type_tables); type_ref = type_proto->type_ref; } else { size = type_refs_size(old_type_refs); assert(type_refs_size(new_type_refs) == size); for (index = 0; index < size; index++) { old_type_ref = type_refs_fetch(old_type_refs, index); if (type_ref_equal(type_ref, old_type_ref)) { return type_refs_fetch(new_type_refs, index); } } parameters = type_ref->parameters; if (type_refs_is_empty(parameters)) { return type_ref; } parameters = type_refs_replace(parameters, old_type_refs, new_type_refs, type_tables); type_ref = type_ref_parameters_create(type_ref->name, parameters, type_tables); } return type_ref; } #ifndef lint /* * type_ref_show(type_ref) * This routine is used for debugging an displays "type_ref" to * standard out. */ void type_ref_show( Type_ref type_ref) { type_ref_print(type_ref, stdout); (void)printf("\n"); } #endif /* lint */ /* * type_ref_string(type_ref, heap) * This routine will return the ANSI-C type string assocaited with * "type_ref" allocated from "heap". */ Str type_ref_string( Type_ref type_ref, Heap heap) { return type_translate(type_ref->name, heap); } /* * type_ref_write(type_ref, out_file, type_tables) * This routine will write "type_ref" to "out_file". */ void type_ref_write( Type_ref type_ref, Stdio out_file, Type_tables type_tables) { assert(type_tables != (Type_tables)0); out_marker_write(out_file, "type_ref"); if (type_ref_is_routine(type_ref)) { Type_proto type_proto; type_proto = type_proto_from_type_ref(type_ref, type_tables); (void)fputc(1, out_file); type_proto_write(type_proto, out_file, type_tables); } else { (void)fputc(0, out_file); (void)strwrite(type_ref->name, out_file); type_refs_write(type_ref->parameters, out_file, type_tables); } } /* * type_ref_table_create(heap) * This routine will return a new type reference table allocated from * "heap". */ LOCAL Type_ref_table type_ref_table_create( Heap heap) { Table(Type_ref, Type_ref) ref_table; Table(Type_refs, Type_refs) refs_table; Type_ref_table type_ref_table; ref_table = table_create(Type_ref, Type_ref, 100, type_ref_equal, type_ref_hash, (Type_ref)0, heap); refs_table = table_create(Type_refs, Type_refs, 100, type_refs_equal, type_refs_hash, (Type_refs)0, heap); type_ref_table = heap_allocate(heap, Type_ref_table); type_ref_table->heap = heap; type_ref_table->multiple = 0; type_ref_table->ref_table = ref_table; type_ref_table->refs_table = refs_table; type_ref_table->type_ref_key = heap_allocate(heap, Type_ref); type_ref_table->type_refs_key = heap_allocate(heap, Type_refs); type_ref_table->type_refs_key->type_refs =vec_create(Type_ref, heap); type_ref_table->empty = type_refs_table_lookup(type_ref_table); return type_ref_table; } /* * type_ref_table_dump(type_ref_table, out_file) * This routine will dump the contents of the "type_ref_table" to * "out_file" */ LOCAL void type_ref_table_dump( Type_ref_table type_ref_table, Stdio out_file) { Type_ref type_ref; Vec(Type_ref) type_ref_list; Type_refs type_refs; Vec(Type_refs) type_refs_list; /* Dump the type reference table: */ type_ref_list = table_value_list_extract(Type_ref, Type_ref, type_ref_table->ref_table); vec_sort(Type_ref, type_ref_list, type_ref_compare, 0); out(out_file, "Type Reference Table:\n"); VEC_LOOP(Type_ref, type_ref_list, type_ref) { type_ref_print(type_ref, out_file); out(out_file, "\n"); } out(out_file, "\n"); /* Dump the type reference list table: */ type_refs_list = table_value_list_extract(Type_refs, Type_refs, type_ref_table->refs_table); vec_sort(Type_refs, type_refs_list, type_refs_compare, 0); out(out_file, "type_refs_table:\n"); VEC_LOOP(Type_refs, type_refs_list, type_refs) { out(out_file, "{"); type_refs_print(type_refs, out_file); out(out_file, "}\n"); } out(out_file, "\n"); } /* * Type_refs routines: */ /* * type_refs_append(type_refs, type_ref, type_tables) * This routine will return a type_reference list that constists of * "type_refs" concatonated with "type_ref". */ Type_refs type_refs_append( Type_refs type_refs, Type_ref type_ref, Type_tables type_tables) { Type_refs type_refs_key; Type_ref_table type_ref_table; type_ref_table = type_tables->type_ref_table; type_refs_key = type_ref_table->type_refs_key; assert(vec_empty(Type_ref, type_refs_key->type_refs)); vec_vec_append(Type_ref, type_refs_key->type_refs, type_refs->type_refs); vec_append(Type_ref, type_refs_key->type_refs, type_ref); type_refs = type_refs_table_lookup(type_ref_table); return type_refs; } /* * type_refs_compare(type_refs1, type_refs2, zilch) * This routine is returns <0, 0, or >0 depending upon whether * "type_refs1" is less than, equal to, or greater than "type_refs2". */ /* ARGSUSED */ int type_refs_compare( Type_refs type_refs1, Type_refs type_refs2, int zilch) { int index; int result; int size1; int size2; Type_ref type_ref1; Type_ref type_ref2; size1 = vec_size(Type_ref, type_refs1->type_refs); size2 = vec_size(Type_ref, type_refs2->type_refs); result = size1 - size2; if (result != 0) { return result; } for (index = 0; index < size1; index++) { type_ref1 = vec_fetch(Type_ref, type_refs1->type_refs, index); type_ref2 = vec_fetch(Type_ref, type_refs2->type_refs, index); result = type_ref_compare(type_ref1, type_ref2, 0); if (result != 0) { return result; } } return result; } /* * type_refs_concat(type_refs1, type_refs2, type_tables) * This routine will return a concatonation of "type_refs1" and * "type_refs2". */ Type_refs type_refs_concat( Type_refs type_refs1, Type_refs type_refs2, Type_tables type_tables) { Type_refs type_refs; Type_refs type_refs_key; Type_ref_table type_ref_table; type_ref_table = type_tables->type_ref_table; type_refs_key = type_ref_table->type_refs_key; assert(vec_empty(Type_ref, type_refs_key->type_refs)); vec_vec_append(Type_ref, type_refs_key->type_refs, type_refs1->type_refs); vec_vec_append(Type_ref, type_refs_key->type_refs, type_refs2->type_refs); type_refs = type_refs_table_lookup(type_ref_table); return type_refs; } /* * type_refs_empty_create(type_tables) * This routine will create and return an empty type reference list. */ Type_refs type_refs_empty_create( Type_tables type_tables) { return type_tables->type_ref_table->empty; } /* * type_refs_equal(type_refs1, type_refs2) * This routine will return 1 if "type_refs1" is equal to "type_refs2" * and 0 otherwise. */ int type_refs_equal( Type_refs type_refs1, Type_refs type_refs2) { return (type_refs_compare(type_refs1, type_refs2, 0) == 0); } /* * type_refs_fetch(type_refs, index) * This routine will return the "index"'th type reference from "type_refs". */ Type_ref type_refs_fetch( Type_refs type_refs, int index) { return vec_fetch(Type_ref, type_refs->type_refs, index); } /* * type_refs_gen(type_refs, gen) * This routine will generate a static data structure containing * "type_refs" to "gen". */ void type_refs_gen( Type_refs type_refs, Gen gen) { Type_ref type_ref; if (type_refs->list_generated) { return; } type_refs->list_generated = 1; TYPE_REFS_LOOP(type_refs, type_ref) { type_ref_gen(type_ref, gen); } gen_out(gen, "static type___reference *%M__type__references[%d] = {\n", type_refs, type_refs_size(type_refs)); TYPE_REFS_LOOP(type_refs, type_ref) { gen_out(gen, "%\t&%m__type__reference,\n", 1, type_ref); } gen_out(gen, "};\n"); } /* * type_refs_hash(type_refs) * This routine will return a hash value for "type_refs". */ int type_refs_hash( Type_refs type_refs) { int hash; Type_ref type_ref; hash = 0; TYPE_REFS_LOOP(type_refs, type_ref) { hash += type_ref_hash(type_ref); } return hash; } /* * type_refs_needed(type_refs, type_tables) * This routine will mark each type reference in "type_refs" as * needed in the final output file. */ void type_refs_needed( Type_refs type_refs, Type_tables type_tables) { Type_ref type_ref; TYPE_REFS_LOOP(type_refs, type_ref) { type_ref_needed(type_ref, type_tables); } } /* * type_refs_is_empty(type_refs) * This routine will return 1 if "type_refs" is empty and 0 otherwise. */ int type_refs_is_empty( Type_refs type_refs) { return (type_refs->type_refs->size == 0); } #ifdef OLD /* * type_refs_is_in(type_refs, target_type_ref) * This routine will return 1 if any type_reference in "type_refs" occurs * anywhere in "type_ref"; otherwise, 0 is returned. */ int type_refs_is_in( Type_refs type_refs, Type_ref target_type_ref) { Type_ref type_ref; TYPE_REFS_LOOP(type_refs, type_ref) { if (type_ref_is_in(type_ref, target_type_ref)) { return 1; } } return 0; } /* * type_refs_is_one_of(type_refs, target_type_ref) * This routine will return 1 if "type_ref" is one of the type references * in "type_refs"; otherwise, 0 is returned. */ int type_refs_is_one_of( Type_refs type_refs, Type_ref target_type_ref) { Type_ref type_ref; TYPE_REFS_LOOP(type_refs, type_ref) { if (type_ref_equal(type_ref, target_type_ref)) { return 1; } } return 0; } #endif /* OLD */ /* * type_refs_contains_parameter(type_refs) * This routine 1 if any type reference in "type_refs" is a parameterized * type. */ LOCAL int type_refs_contains_parameter( Type_refs type_refs) { Type_ref type_ref; TYPE_REFS_LOOP(type_refs, type_ref) { if (type_ref_contains_parameter(type_ref)) { return 1; } } return 0; } /* * type_refs_keyword_print(list, gen, keyword, indent) * This routine will print "keyword", indented by "indent", followed by * a comma separated version of "list" to "gen". */ void type_refs_keyword_print( Type_refs list, Stdio out_file, Str keyword, int indent) { if (!type_refs_is_empty(list)) { out(out_file, "%\t%s ", indent, keyword); type_refs_print(list, out_file); out(out_file, "\n"); } } /* * type_refs_lop(type_refs, type_tables) * This routine will return the type reference list corresponding to * "type_refs" with the first type reference removed. */ Type_refs type_refs_lop( Type_refs type_refs, Type_tables type_tables) { Type_refs type_refs_key; Type_ref_table type_ref_table; type_ref_table = type_tables->type_ref_table; type_refs_key = type_ref_table->type_refs_key; assert(vec_empty(Type_ref, type_refs_key->type_refs)); vec_vec_append(Type_ref, type_refs_key->type_refs, type_refs->type_refs); vec_delete(Type_ref, type_refs_key->type_refs, 0); type_refs = type_refs_table_lookup(type_ref_table); return type_refs; } /* * type_refs_mangle(type_refs, level, out_file) * This routine will print out a mangled version of "type_refs" * to "out_file". */ void type_refs_mangle( Type_refs type_refs, int level, Stdio out_file) { int index; Type_ref type_ref; int size; size = type_refs_size(type_refs); for (index = 0; index < size; index++) { type_ref = type_refs_fetch(type_refs, index); if (index == 0) { if (type_ref_is_parameter(type_ref)) { out(out_file, "_"); } } else { out(out_file, "__"); } if (level > 0) { out(out_file, "%d_", level); } out(out_file, "%s", type_ref->name); if (!type_refs_is_empty(type_ref->parameters)) { out(out_file, "__"); type_refs_mangle(type_ref->parameters, level + 1, out_file); } } } /* * type_refs_multiple_needed(type_refs, type_tables) * This will mark "type_refs" as being needed for mutiple return type. */ void type_refs_multiple_needed( Type_refs type_refs, Type_tables type_tables) { assert(type_refs_size(type_refs) > 1); if (type_refs->multiple < 0) { type_refs->multiple = type_tables->type_ref_table->multiple++; } } /* * type_refs_multiple_gen(type_tables, gen) * This routine will output a typedef for each type reference * list in "type_tables" that is needed for a multiple return * using "gen". */ void type_refs_multiple_gen( Type_tables type_tables, Gen gen) { Heap heap; int index; int size; Type_ref type_ref; Type_refs type_refs; Vec(Type_refs) type_refs_list; heap = gen->heap; type_refs_list = table_value_list_extract(Type_refs, Type_refs, type_tables->type_ref_table->refs_table); VEC_LOOP(Type_refs, type_refs_list, type_refs) { if (type_refs->multiple < 0) { continue; } gen_out(gen, "typedef struct {\n"); size = type_refs_size(type_refs); for (index = 0; index < size; index++) { type_ref = type_refs_fetch(type_refs, index); gen_out(gen, "%\t%s x%d;\n", 1, type_ref_string(type_ref, heap), index); } gen_out(gen, "} type__multiple__%d;\n", type_refs->multiple); } } /* * type_refs_multiple_string(type_refs, heap) * This routine return the ANSI-C type corresponding to "type_refs" * allocated using "heap". */ Str type_refs_multiple_string( Type_refs type_refs, Heap heap) { Type_ref type_ref; switch (type_refs_size(type_refs)) { case 0: return "void"; case 1: type_ref = type_refs_fetch(type_refs, 0); return type_ref_string(type_ref, heap); default: assert(type_refs->multiple >= 0); return strprintf(heap, "type__multiple__%d", type_refs->multiple); } /* NOTREACHED */ } /* * type_refs_print(type_refs, out_file) * This routine will print "type_refs" to "out_file". */ void type_refs_print( Type_refs type_refs, Stdio out_file) { int index; int size; Type_ref type_ref; size = type_refs->type_refs->size; for (index = 0; index < size; index++) { if (index != 0) { out(out_file, ", "); } type_ref = vec_fetch(Type_ref, type_refs->type_refs, index); type_ref_print(type_ref, out_file); } } /* * type_refs_read(in_file, heap, type_tables) * This routine will read in and return list of type references from * "in_file" allocated from "heap". */ Type_refs type_refs_read( Stdio in_file, Heap heap, Type_tables type_tables) { int size; Type_ref type_ref; Type_refs type_refs; Type_ref_table type_ref_table; out_marker_read(in_file, "type_refs"); type_ref_table = type_tables->type_ref_table; type_refs = type_ref_table->empty; size = out_count_read(in_file); while (size -- > 0) { type_ref = type_ref_read(in_file, heap, type_tables); type_refs = type_refs_append(type_refs, type_ref, type_tables); } return type_refs; } /* * type_refs_replace(type_refs, old_type_refs, new_type_refs, type_tables) * This routine will replace all occurances of "old_type_refs" with * "new_type_refs" for each type reference in "type_refs" and * return the resulting list. */ Type_refs type_refs_replace( Type_refs type_refs, Type_refs old_type_refs, Type_refs new_type_refs, Type_tables type_tables) { Type_ref type_ref; Type_refs result_type_refs; Type_ref_table type_ref_table; type_ref_table = type_tables->type_ref_table; result_type_refs = type_ref_table->empty; TYPE_REFS_LOOP(type_refs, type_ref) { type_ref = type_ref_replace(type_ref, old_type_refs, new_type_refs, type_tables); result_type_refs = type_refs_append(result_type_refs, type_ref, type_tables); } return result_type_refs; } #ifndef lint /* * type_refs_show(type_refs) * This routine is used for debugging and prints "type_refs" to * standard out. */ void type_refs_show( Type_refs type_refs) { (void)printf("{"); type_refs_print(type_refs, stdout); (void)printf("}\n"); } #endif /* lint */ /* * type_refs_size(type_refs) * This routine will return the number of type references in "type_refs". */ int type_refs_size( Type_refs type_refs) { return type_refs->type_refs->size; } #ifdef OLD /* * type_refs_store(type_refs, index, type_ref, type_tables) * This routine will return the type reference list that results from * substituting "type_ref" for the "index"'th type reference in * "type_refs". */ Type_refs type_refs_store( Type_refs type_refs, int index, Type_ref type_ref, Type_tables type_tables) { Type_refs type_refs_key; Type_ref_table type_ref_table; type_ref_table = type_tables->type_ref_table; type_refs_key = type_ref_table->type_refs_key; assert(vec_empty(Type_ref, type_refs_key->type_refs)); vec_vec_append(Type_ref, type_refs_key->type_refs, type_refs->type_refs); vec_store(Type_ref, type_refs_key->type_refs, index, type_ref); type_refs = type_refs_table_lookup(type_ref_table); return type_refs; } #endif /* OLD */ /* * type_refs_write(type_refs, out_file) * This routine will write "type_refs" to "out_file". */ void type_refs_write( Type_refs type_refs, Stdio out_file, Type_tables type_tables) { Type_ref type_ref; out_marker_write(out_file, "type_refs"); out_count_write(out_file, vec_size(Type_ref, type_refs->type_refs)); TYPE_REFS_LOOP(type_refs, type_ref) { type_ref_write(type_ref, out_file, type_tables); } } /* * type_refs_table_lookup(type_ref_table) * This routine will return an immutable copy of * "type_ref_table"->type_refs_key. */ LOCAL Type_refs type_refs_table_lookup( Type_ref_table type_ref_table) { Heap heap; Table(Type_refs, Type_refs) refs_table; Type_refs type_refs; Type_refs type_refs_key; Type_refs new_type_refs; refs_table = type_ref_table->refs_table; type_refs_key = type_ref_table->type_refs_key; type_refs = table_lookup(Type_refs, Type_refs, refs_table, type_refs_key); if (type_refs == (Type_refs)0) { heap = type_ref_table->heap; new_type_refs = heap_allocate(heap, Type_refs); new_type_refs->type_refs = vec_create(Type_ref, heap); vec_vec_append(Type_ref, new_type_refs->type_refs, type_refs_key->type_refs); new_type_refs->list_generated = 0; new_type_refs->multiple = -1; assert(table_insert(Type_refs, Type_refs, refs_table, new_type_refs, new_type_refs) == 0); type_refs = new_type_refs; } vec_trim(Type_ref, type_refs_key->type_refs, 0); return type_refs; } /* * Type_tables routines: */ /* * type_tables_create(heap) * This routine will create and return all of the various type tables * allocated from "heap". */ Type_tables type_tables_create( Heap heap) { Type_tables type_tables; Type_ref_table type_ref_table; type_ref_table = type_ref_table_create(heap); type_tables = heap_allocate(heap, Type_tables); type_tables->type_def_table = type_def_table_create(heap); type_tables->type_need_table = type_need_table_create(type_ref_table, heap); type_tables->type_proto_table = type_proto_table_create(type_ref_table, heap); type_tables->type_ref_table = type_ref_table; type_tables->type_signal_table = type_signal_table_create(type_ref_table, heap); type_tables_global = type_tables; return type_tables; } /* * type_tables_dump(type_tables, out_file) * This routine will dump each type table in "type_tables" out to * "out_file" in a human readable form. */ void type_tables_dump( Type_tables type_tables, Stdio out_file) { type_ref_table_dump(type_tables->type_ref_table, out_file); type_need_table_dump(type_tables->type_need_table, out_file); type_signal_table_dump(type_tables->type_signal_table, out_file); type_proto_table_dump(type_tables->type_proto_table, out_file); }