/* %Z%%M% %I% %E% */ /* * Copyright (c) 1992, 1993, 1995, 2000 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 code for converting between expression tree format * to call tree format: */ #ifndef CALL_DEFS_H #include "call_defs.h" #endif #ifndef FLAGS_DEFS_H #include "flags_defs.h" #endif #ifndef GENERATE_DEFS_H #include "generate_defs.h" #endif #ifndef HEAP_EXPORTS_H #include "heap_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef NEED_EXPORTS_H #include "need_exports.h" #endif #ifndef ROUTINE_DEFS_H #include "routine_defs.h" #endif #ifndef STR_EXPORTS_H #include "str_exports.h" #endif #ifndef STRVEC_EXPORTS_H #include "strvec_exports.h" #endif #ifndef TABLE_EXPORTS_H #include "table_exports.h" #endif #ifndef TYPE_DEFS_H #include "type_defs.h" #endif #ifndef VECTOR_DEFS_H #include "vector_defs.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_CTYPE_H #include "unix_ctype.h" #endif #ifndef UNIX_UNISTD_H #include "unix_unistd.h" #endif #ifdef OLD LOCAL void generate_def_new_convert(Type_def, Routine, Convert); LOCAL void type_def_access_convert(Type_def, Convert); LOCAL void type_def_address_get_convert(Type_def, Routine, Convert); LOCAL void type_def_copy_convert(Type_def, Routine, Convert); LOCAL void type_def_equal_convert(Type_def, Routine, Convert); LOCAL void type_def_erase_convert(Type_def, Routine, Convert); LOCAL void type_def_hash_convert(Type_def, Routine, Convert); LOCAL void type_def_input_convert(Type_def, Routine, Convert); LOCAL void type_def_output_convert(Type_def, Routine, Convert); LOCAL void type_def_print_convert(Type_def, Routine, Convert); LOCAL void type_def_struct_convert(Type_def, Routine, Convert); /* * type_def_access_convert(routine, convert) */ LOCAL void type_def_access_convert( Type_def type_def, Convert convert) { Need_table need_table; Str type_name; assert_fail(); if (type_ref_is_paramterized(type_def->type_ref)) { return; } type_name = type_def->name; need_table = convert->routine->need_table; switch (type_def->kind) { case Type_kind_record: { Type_field field; Str field_name; Str field_type; Type_fields fields; Str name; Str var_name; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { /* Generate the get routine: */ field_name = field->name; field_type = field->type_ref->name; } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_name; Str tag_field_type; Type_variant variant; variant = type_def->value.variant; /* Generate tag field access routine: */ tag_field = variant->tag_field; tag_field_name = tag_field->name; tag_field_type = tag_field->type_ref->name; fields = variant->fields; VEC_LOOP(Type_field, fields, field) { /* Generate the set routine: */ field_name = field->name; field_type = field->type_ref->name; } break; } } } /* * type_def_copy_convert(routine, convert) */ void type_def_copy_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Str field_name; Str field_type; Type_fields fields; #ifdef BROKEN fields = type_def->value.record->fields; size = vec_size(Type_field, fields); for (index = 0; index < size; index++) { field = vec_fetch(Type_field, fields, index); if (!type_ref_is_parameterized(field->type_ref)) { continue; } type_proto = type_proto_create(Type_proto_procedure, type_refs_empty, parameter->type_refs, type_refs_empty, type_refs_empty, type_signals_empty_create(type_tables), type_needs_empty_create(type_tables), 0, type_tables); need_table_routine_insert(need_table, "erase", parameter, type_proto, parameters); } #endif /* BROKEN */ break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variables: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; fields = variant->fields; VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } /* Output the return statement: */ break; } } } /* * type_def_equal_convert(routine, convert) */ void type_def_equal_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Str field_name; Type_fields fields; int index; Str name; int size; fields = type_def->value.record->fields; size = vec_size(Type_field, fields); for (index = 0; index < size; index++) { field = vec_fetch(Type_field, fields, index); field_name = field->name; name = field->type_ref->name; } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variable: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; /* Output the switch statement: */ fields = variant->fields; VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } break; } default: assert_fail(); } } /* * type_def_erase_convert(Routine, convert) */ void type_def_erase_convert( Type_def type_def, Routine routine, Convert convert) { Need_table need_table; Type_tables type_tables; Type_refs type_refs_empty; need_table = routine->need_table; type_tables = convert->type_tables; type_refs_empty = convert->type_refs_empty; switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Type_fields fields; Type_ref type_ref; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { type_ref = field->type_ref; if (!type_refs_is_parameterized(type_ref)) { assert_fail(); need_table_object_insert(need_table, "??", type_ref, type_ref, 0); } } break; } default: assert_fail(); } } /* * type_def_hash_convert(Routine, convert) * This routine will generate the hash routine for "type_def" * using "gen". */ void type_def_hash_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Str field_name; Type_fields fields; int index; Str name; int size; fields = type_def->value.record->fields; size = vec_size(Type_field, fields); for (index = 0; index < size; index++) { field = vec_fetch(Type_field, fields, index); field_name = field->name; name = field->type_ref->name; } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variable: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; /* Output the switch statement: */ fields = variant->fields; VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } break; } default: assert_fail(); } } /* * type_def_initial_object_convert(Routine, convert) * This routine will generate the initial object(s) for "type_def" * using "gen". */ void type_def_initial_object_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: { int index; Type_item item; Str item_name; Vec(Type_item) items; int size; items = type_def->value.enumeration->items; size = vec_size(Type_item, items); for (index = 0; index < size; index++) { item = vec_fetch(Type_item, items, index); item_name = item->name; } break; } case Type_kind_record: break; case Type_kind_variant: break; } } /* * type_def_input_convert(Routine, convert) * This routine will generate the input routine for "type_def" * using "gen". */ void type_def_input_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Type_fields fields; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variables: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; /* Output the switch statement: */ fields = variant->fields; VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } break; } default: assert_fail(); } } /* * type_def_needs_parameter_block(type_def) * This routine will return a 1 if any field in "type_def" is * parameterized; otherwise, 0 is returned. */ LOCAL int type_def_needs_parameter_block( Type_def type_def) { assert_fail(); if (!type_ref_is_parameterized(type_def->type_ref)) { return 0; } switch (type_def->kind) { case Type_kind_record: { Type_field field; Type_fields fields; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { if (type_refs_is_parameter(field->type_ref)) { return 1; } } break; } default: assert_fail(); } return 0; } #endif /* OLD */ /* * generate_allocate_convert(type_def, routine, convert) */ LOCAL void generate_allocate_convert( Type_def type_def, Routine routine, Convert convert) { Type_ref type_ref; Type_proto type_proto; Type_refs type_refs_empty; Type_tables type_tables; type_tables = convert->type_tables; type_refs_empty = type_refs_empty_create(type_tables); type_ref = type_def->type_ref; type_proto = type_proto_create(Type_proto_procedure, type_ref->parameters, type_ref->type_refs, type_refs_empty, type_refs_empty, type_signals_empty_create(type_tables), type_needs_empty_create(type_tables), 0, type_tables); if (type_ref_is_parameterized(type_ref)) { need_table_routine_insert(routine->need_table, "erase", type_ref, type_proto); } } /* * generate_new_convert(type_def, routine, convert) */ LOCAL void generate_new_convert( Type_def type_def, Routine routine, Convert convert) { Type_ref type_ref; Type_proto type_proto; Type_refs type_refs_empty; Type_tables type_tables; type_tables = convert->type_tables; type_refs_empty = type_refs_empty_create(type_tables); type_ref = type_def->type_ref; type_proto = type_proto_create(Type_proto_procedure, type_ref->parameters, type_ref->type_refs, type_refs_empty, type_refs_empty, type_signals_empty_create(type_tables), type_needs_empty_create(type_tables), 0, type_tables); if (type_ref_is_parameterized(type_ref)) { need_table_routine_insert(routine->need_table, "erase", type_ref, type_proto); } } #ifdef OLD /* * type_def_output_convert(Routine, convert) * This routine will generate the output routine for "type_def" * using "gen". */ void type_def_output_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: break; case Type_kind_record: { Type_field field; Type_fields fields; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variable: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; /* Output the switch statement: */ fields = variant->fields; VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } break; } default: assert_fail(); } } /* * type_def_print_convert(Routine, convert) * This routine will generate the print routine for "type_def" * using "gen". */ void type_def_print_convert( Type_def type_def, Routine routine, Convert convert) { Str type_name; assert_fail(); type_name = type_def->name; switch (type_def->kind) { case Type_kind_enumeration: { Type_item item; Vec(Type_item) items; items = type_def->value.enumeration->items; VEC_LOOP(Type_item, items, item){ } break; } case Type_kind_record: { Type_field field; Type_fields fields; int index; int size; fields = type_def->value.record->fields; VEC_LOOP(Type_field, fields, field) { } size = vec_size(Type_field, fields); for (index = 0; index < size; index++) { field = vec_fetch(Type_field, fields, index); } break; } case Type_kind_variant: { Type_field field; Str field_name; Str field_type; Type_fields fields; Type_field tag_field; Str tag_field_type; Type_variant variant; /* Output the local variable: */ variant = type_def->value.variant; tag_field = variant->tag_field; tag_field_type = tag_field->type_ref->name; fields = variant->fields; VEC_LOOP(Type_field, fields, field) { } /* We should be more careful to get a stable tag and value! */ /* Output the switch statement: */ VEC_LOOP(Type_field, fields, field) { field_name = field->name; field_type = field->type_ref->name; } break; } default: assert_fail(); } } #endif /* OLD */ /* * generate_routines_convert(type_def, convert) * This routien will generate all of the access routines for "type_def" * using "gen". */ void generate_routines_convert( Type_def type_def, Convert convert) { Generate generate; Vec(Generate) generates; Routine routine; Routine_entry routine_entry; generates = type_def->generates; VEC_LOOP(Generate, generates, generate) { routine_entry = routine_entry_lookup(convert->routine_table, generate_unparse(generate->kind), type_def->type_ref->name, -1); if ((routine_entry != (Routine_entry)0) && (routine_entry->routine != (Routine)0)) { generate->routine = routine_entry->routine; } } switch (type_def->kind) { case Type_kind_enumeration: VEC_LOOP(Generate, generates, generate) { routine = generate->routine; switch (generate->kind) { case Generate_allocate: break; case Generate_copy: break; case Generate_equal: break; case Generate_hash: break; case Generate_identical: break; case Generate_input: break; case Generate_integer_convert: break; case Generate_new: break; case Generate_output: break; case Generate_print: break; case Generate_save: break; case Generate_unsigned_convert: break; default: assert_fail(); } } break; case Type_kind_record: case Type_kind_variant: VEC_LOOP(Generate, generates, generate) { routine = generate->routine; switch (generate->kind) { case Generate_address_get: break; case Generate_allocate: generate_allocate_convert(type_def, routine, convert); break; case Generate_copy: break; case Generate_erase: break; case Generate_equal: break; case Generate_hash: break; case Generate_identical: break; case Generate_input: break; case Generate_new: generate_new_convert(type_def, routine, convert); break; case Generate_output: break; case Generate_print: break; case Generate_save: break; default: assert_fail(); } } break; case Type_kind_external: break; default: assert_fail(); } }