/* %Z%%M% %I% %E% */ /* * Copyright (c) 1992, 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 routines for manipulating routine_ref's: */ #ifndef FILE_DEFS_H #include "file_defs.h" #endif #ifndef HEAP_EXPORTS_H #include "heap_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef MODULE_TYPES_H #include "module_types.h" #endif #ifndef MSG_EXPORTS_H #include "msg_exports.h" #endif #ifndef OUT_EXPORTS_H #include "out_exports.h" #endif #ifndef ROUTINE_DEFS_H #include "routine_defs.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 VECTOR_DEFS_H #include "vector_defs.h" #endif /* * routine_ref_equal(routine_ref1, routine_ref2) * This routine will return 1 if "routine_ref1" is equal to * "routine_ref2". They are equal if they have the same name and * type reference name. */ int routine_ref_equal( Routine_ref routine_ref1, Routine_ref routine_ref2) { Type_ref type_ref1; Type_ref type_ref2; assert(routine_ref1 != (Routine_ref)0); assert(routine_ref2 != (Routine_ref)0); if (!strequal(routine_ref1->name, routine_ref2->name)) { return 0; } type_ref1 = routine_ref1->type_ref; type_ref2 = routine_ref2->type_ref; if (!type_ref_equal(type_ref1, type_ref2)) { return 0; } return 1; } /* * routine_ref_hash(routine_ref) * This routine will return a hash value for "routine_ref". */ int routine_ref_hash( Routine_ref routine_ref) { int hash; hash = strhash(routine_ref->name); hash += type_ref_hash(routine_ref->type_ref); return hash; } /* * routine_ref_insert(routine_table, routine_name, type_ref, position) * This routine will insert "routine_name"@"type_ref" into "routine_table". * The result routine reference object is returned. */ Routine_ref routine_ref_insert( Routine_table routine_table, Str routine_name, Type_ref type_ref, int position) { Routine_entry entry_key; Routine_entry entry; Routine_ref ref; Type_proto type_proto; Type_tables type_tables; entry_key = routine_table->entry_key; entry_key->routine_name = routine_name; entry_key->type_name = type_ref->name; entry = table_lookup(Routine_entry, Routine_entry, routine_table->entry_table, entry_key); type_tables = routine_table->type_tables; if (entry == (Routine_entry)0) { Type_refs type_refs_empty; msg_out(routine_table->msg, position, "%s%@ does not exist", routine_name, type_ref); type_refs_empty = type_refs_empty_create(type_tables); type_proto = type_proto_create(Type_proto_procedure, type_refs_empty, type_refs_empty, type_refs_empty, type_refs_empty, type_signals_empty_create(type_tables), type_needs_empty_create(type_tables), 0, type_tables); entry = routine_entry_insert(routine_table, routine_name, type_ref, type_proto, position, 0); } type_proto = entry->type_proto; if (type_proto_is_parameterized(type_proto)) { if (type_refs_size(type_proto->params) == type_refs_size(type_ref->parameters)) { type_proto = type_proto_replace(entry->type_proto, entry->type_proto->params, type_ref->parameters, routine_table->type_tables); } else { msg_out(routine_table->msg, position, "Routine passed %d parameters instead of %d", type_refs_size(type_ref->parameters), type_refs_size(type_proto->params)); } } ref = heap_allocate(routine_table->heap, Routine_ref); ref->name = routine_name; ref->type_ref = type_ref; ref->constant = 0; ref->routine_entry = entry; ref->type_proto = type_proto; assert(table_insert(Routine_ref, Routine_ref, routine_table->ref_table, ref, ref) == 0); vec_append(Routine_ref, entry->routine_refs, ref); return ref; } /* * routine_ref_lookup(routine_table, routine_name, type_ref, position) * This routine will lookup and return the routine reference for * "routine_name"@"type_ref" from "routine_table". (Routine_ref)0 * is returned if "routine_name"@"type_name" can not be found. */ Routine_ref routine_ref_lookup( Routine_table routine_table, Str routine_name, Type_ref type_ref, int position) { Routine_entry entry; Routine_entry entry_key; Routine_ref ref; Routine_ref ref_key; ref_key = routine_table->ref_key; ref_key->name = routine_name; ref_key->type_ref = type_ref; ref = table_lookup(Routine_ref, Routine_ref, routine_table->ref_table, ref_key); if (ref == (Routine_ref)0) { entry_key = routine_table->entry_key; entry_key->routine_name = routine_name; entry_key->type_name = type_ref->name; entry = table_lookup(Routine_entry, Routine_entry, routine_table->entry_table, entry_key); if (entry != (Routine_entry)0) { ref = routine_ref_insert(routine_table, routine_name, type_ref, position); } } return ref; } /* * routine_ref_print(routine_ref, out_file) * This routine will print "routine_ref" to "out_file" in human * readable form. */ LOCAL void routine_ref_print( Routine_ref routine_ref, Stdio out_file) { out(out_file, "routine %s%@ ", routine_ref->name, routine_ref->type_ref); type_proto_print(routine_ref->type_proto, 1, out_file); } #ifndef lint /* * routine_ref_show(routine_ref) * This routine will print out "routine_ref". */ void routine_ref_show( Routine_ref routine_ref) { routine_ref_print(routine_ref, stdout); } #endif /* lint */ /* * routine_refs_dump(routine_table, out_file) * This routine will dump the routine refs from "routine_table" to * "out_file" in a human readable form. */ void routine_refs_dump( Routine_table routine_table, Stdio out_file) { Routine_ref ref; Vec(Routine_ref) refs; out(out_file, "Routine References Table:\n"); refs = table_value_list_extract(Routine_ref, Routine_ref, routine_table->ref_table); VEC_LOOP(Routine_ref, refs, ref) { routine_ref_print(ref, out_file); } out(out_file, "\n"); }