diff: runtime clean-ups

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Nov 9 20:11:09 AEDT 1998


Fix the code in the runtime so that `mmake check_headers' succeeds.

runtime/*.h:
	Add #include statements to make all the header files
	self-contained.

runtime/mercury_table.h:
runtime/mercury_table.c:
	Delete these empty files.
	For some reason zs left these files as empty instead of deleting
	them when he renamed the module as mercury_hash_table.{h,c}.

runtime/mercury_table_builtins.h:
runtime/mercury_table_enum.h:
runtime/mercury_table_any.h:
runtime/mercury_table_type_info.h:
runtime/mercury_table_builtins.c:
runtime/mercury_table_enum.c:
runtime/mercury_table_any.c:
runtime/mercury_table_type_info.c:
runtime/mercury_tabling.h:
runtime/mercury_tabling.c:
	Avoid a circular dependency problem (mercury_tabling.h
	depended on mercury_table_*.h which in turn depended on
	mercury_tabling.h) by moving all the tabling code into
	a single module mercury_tabling.{h,c}.
	The new module is a total of 1100 lines of code,
	which is not too large IMHO.

	Also improve the documentation a little.

Index: runtime/mercury_accurate_gc.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_accurate_gc.h,v
retrieving revision 1.8
diff -u -r1.8 mercury_accurate_gc.h
--- mercury_accurate_gc.h	1998/07/22 07:52:22	1.8
+++ mercury_accurate_gc.h	1998/11/09 08:30:14
@@ -13,6 +13,8 @@
 **	supporting code).
 */
 
+#include "mercury_types.h"
+
 /*---------------------------------------------------------------------------*/
 
 /*
Index: runtime/mercury_agc_debug.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_agc_debug.h,v
retrieving revision 1.1
diff -u -r1.1 mercury_agc_debug.h
--- mercury_agc_debug.h	1998/07/22 07:52:25	1.1
+++ mercury_agc_debug.h	1998/11/09 08:31:51
@@ -12,6 +12,11 @@
 **	Debugging support for accurate garbage collection.
 */
 
+#include "mercury_types.h"		/* for Word */
+#include "mercury_label.h"		/* for MR_Internal */
+#include "mercury_memory_zones.h"	/* for MemoryZone */
+#include "mercury_accurate_gc.h"	/* for MR_RootList */
+
 /*---------------------------------------------------------------------------*/
 
 /*
Index: runtime/mercury_heap_profile.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap_profile.h,v
retrieving revision 1.1
diff -u -r1.1 mercury_heap_profile.h
--- mercury_heap_profile.h	1997/12/05 15:56:36	1.1
+++ mercury_heap_profile.h	1998/11/09 07:59:59
@@ -18,6 +18,8 @@
 #ifndef MERCURY_HEAP_PROFILE_H
 #define MERCURY_HEAP_PROFILE_H
 
+#include "mercury_types.h"	/* for `Code' */
+
 /*---------------------------------------------------------------------------*/
 
 /*
Index: runtime/mercury_layout_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.h,v
retrieving revision 1.2
diff -u -r1.2 mercury_layout_util.h
--- mercury_layout_util.h	1998/11/09 05:23:34	1.2
+++ mercury_layout_util.h	1998/11/09 08:29:09
@@ -7,6 +7,10 @@
 #ifndef	MERCURY_LAYOUT_UTIL_H
 #define	MERCURY_LAYOUT_UTIL_H
 
+#include "mercury_std.h"
+#include "mercury_types.h"
+#include "mercury_stack_layout.h"
+
 /*
 ** These two functions copy the register state to and from the provided
 ** saved_regs array, which should have room for MAX_FAKE_REG Words.
Index: runtime/mercury_library_types.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_library_types.h,v
retrieving revision 1.1
diff -u -r1.1 mercury_library_types.h
--- mercury_library_types.h	1998/07/28 03:09:59	1.1
+++ mercury_library_types.h	1998/11/09 08:03:03
@@ -12,7 +12,8 @@
 #ifndef MERCURY_LIBRARY_TYPES_H
 #define MERCURY_LIBRARY_TYPES_H
 
-#include <stdio.h>	/* for `FILE' */
+#include <stdio.h>		/* for `FILE' */
+#include "mercury_types.h"	/* for `Word' and `Integer' */
 
 /*
 ** The C `MercuryFile' type is used for the Mercury `io__stream' type
Index: runtime/mercury_misc.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_misc.h,v
retrieving revision 1.10
diff -u -r1.10 mercury_misc.h
--- mercury_misc.h	1998/10/16 06:18:53	1.10
+++ mercury_misc.h	1998/11/09 07:56:33
@@ -16,6 +16,7 @@
 #define	MERCURY_MISC_H
 
 #include "mercury_types.h"	/* for `Code *' */
+#include <stdlib.h>		/* for `size_t' */
 
 #ifdef MR_LOWLEVEL_DEBUG
 extern	void	mkframe_msg(void);
Index: runtime/mercury_signal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_signal.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_signal.h
--- mercury_signal.h	1998/05/18 08:41:35	1.3
+++ mercury_signal.h	1998/11/09 08:03:42
@@ -13,6 +13,9 @@
 #ifndef	MERCURY_SIGNAL_H
 #define	MERCURY_SIGNAL_H
 
+#include "mercury_types.h"
+#include "mercury_std.h"
+
 	/*
 	** MR_setup_signal sets a signal handler (handler) to handle
 	** signals of the given signal type (sig).  
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.12
diff -u -r1.12 mercury_stack_layout.h
--- mercury_stack_layout.h	1998/11/05 03:53:42	1.12
+++ mercury_stack_layout.h	1998/11/09 08:04:36
@@ -16,6 +16,9 @@
 ** you may need to change compiler/stack_layout.m as well.
 */
 
+#include "mercury_types.h"
+#include "mercury_types.h"
+
 /*-------------------------------------------------------------------------*/
 /*
 ** Definitions for MR_PredFunc
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.11
diff -u -r1.11 mercury_stack_trace.h
--- mercury_stack_trace.h	1998/10/30 04:51:42	1.11
+++ mercury_stack_trace.h	1998/11/09 08:05:05
@@ -7,6 +7,7 @@
 #ifndef MERCURY_STACK_TRACE_H
 #define MERCURY_STACK_TRACE_H
 
+#include <stdio.h>
 #include "mercury_stack_layout.h"
 
 /*
Index: runtime/mercury_tabling.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.h,v
retrieving revision 1.9
diff -u -r1.9 mercury_tabling.h
--- mercury_tabling.h	1998/09/21 06:30:55	1.9
+++ mercury_tabling.h	1998/11/09 08:57:34
@@ -5,20 +5,81 @@
 */
 
 /*
-** mercury_tabling.h - definitions of some basic macros used by the tabling
-** code generated by the Mercury compiler and by the Mercury runtime.
+** mercury_tabling.h - definitions of some basic stuff used for tabling.
+** For tabling code, the Mercury compiler (compiler/table_gen.m) generates
+** references to special procedures defined in library/private_builtin.m.
+** The types and macros defined here are used by the procedures defined in
+** library/private_builtin.m.
 */
 
 #ifndef	MERCURY_TABLING_H
 #define	MERCURY_TABLING_H
 
+#include "mercury_types.h"
+#include "mercury_float.h"
+
+/*---------------------------------------------------------------------------*/
+
 typedef Word	**TrieNode;
 typedef Word	**AnswerBlock;
 
-#include "mercury_table_enum.h"
-#include "mercury_table_any.h"
-#include "mercury_table_type_info.h"
-#include "mercury_table_builtins.h"
+/*---------------------------------------------------------------------------*/
+/*
+** The functions defined here are used only via the macros defined below.
+*/
+
+/* functions to handle the builtin types: string, int, float, type_info */
+
+/* 
+** Look to see if the given integer key is in the given table. If it
+** is, return the address of the data pointer associated with the key.
+** If it is not, create a new element for the key in the table and
+** return the address of its data pointer.
+**/
+TrieNode MR_int_hash_lookup_or_add(TrieNode Table, Integer Key);
+
+/* 
+** Look to see if the given float key is in the given table. If it
+** is return the address of the data pointer associated with the key.
+** If it is not create a new element for the key in the table and
+** return the address of its data pointer.
+**/
+TrieNode MR_float_hash_lookup_or_add(TrieNode Table, Float Key);
+
+/* 
+** Look to see if the given string key is in the given table. If it
+** is return the address of the data pointer associated with the key.
+** If it is not create a new element for the key in the table and
+** return the address of its data pointer.
+**/
+TrieNode MR_string_hash_lookup_or_add(TrieNode Table, String Key);
+
+/*
+** Lookup or insert the given type_info into the given table. Return a 
+** pointer to the node of the table reached by the lookup/insert. 
+*/
+TrieNode MR_type_info_lookup_or_add(TrieNode, Word *);
+
+/* --- a function to handle enumerated types --- */
+
+/*
+**  MR_int_index_lookup_or_add() : This function maintains a simple indexed 
+**	table of size Range. The return value is a pointer to the table
+** 	node found by the lookup/insert. 
+*/
+TrieNode MR_int_index_lookup_or_add(TrieNode table, Integer range, Integer key);
+
+/* --- a function to handle any type at all --- */
+
+/*
+** This function will lookup or insert any type of value into a 
+** table. It uses the provided type_info to extract the necessary
+** info to do this. It returns a pointer to the node found by the 
+** insertion/lookup.
+*/
+TrieNode MR_table_type(TrieNode Table, Word *type_info, Word data_value);
+
+/*---------------------------------------------------------------------------*/
 
 #define MR_RAW_TABLE_ANY(Table, TypeInfo, Value)			\
 	MR_table_type(Table, (Word *) TypeInfo, Value)
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_trace_base.h
--- mercury_trace_base.h	1998/10/16 06:19:07	1.3
+++ mercury_trace_base.h	1998/11/09 08:07:43
@@ -16,6 +16,8 @@
 #define MERCURY_TRACE_BASE_H
 
 #include <stdio.h>
+#include "mercury_stack_layout.h"
+#include "mercury_std.h"
 
 /*
 ** This enum should EXACTLY match the definition of the `trace_port_type' type
cvs diff: runtime/mercury_table.c was removed, no comparison available
cvs diff: runtime/mercury_table.h was removed, no comparison available
cvs diff: runtime/mercury_table_any.c was removed, no comparison available
cvs diff: runtime/mercury_table_any.h was removed, no comparison available
cvs diff: runtime/mercury_table_builtins.c was removed, no comparison available
cvs diff: runtime/mercury_table_builtins.h was removed, no comparison available
cvs diff: runtime/mercury_table_enum.c was removed, no comparison available
cvs diff: runtime/mercury_table_enum.h was removed, no comparison available
cvs diff: runtime/mercury_table_type_info.c was removed, no comparison available
cvs diff: runtime/mercury_table_type_info.h was removed, no comparison available
cvs diff: runtime/mercury_tabling.c is a new entry, no comparison available

---- new file runtime/mercury_tabling.c ---------------------------------------
/*
** Copyright (C) 1997-1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/

#include "mercury_imp.h"

#include "mercury_type_info.h"
#include <stdio.h>

/*---------------------------------------------------------------------------*/

/*
** this part defines the functions
**	MR_int_hash_lookup_or_add(),
**	MR_float_hash_lookup_or_add(), and 
** 	MR_string_hash_lookup_or_add().
*/

/* Initial size of a new table */
#define TABLE_START_SIZE primes[0] 

/* 
** Maximum ratio of used to unused buckets in the table. Must be less than 
** 0.9 if you want even poor lookup times. 
*/
#define MAX_EL_SIZE_RATIO 0.65

/* Extract info from a table */
#define SIZE(table)		(((TableRoot *) table)->size) 
#define ELEMENTS(table)	 	(((TableRoot *) table)->used_elements)
#define BUCKET(table, Bucket) 	((TableNode **) &(((TableRoot *) table)-> \
					elements))[(Bucket)]
typedef struct {
	Word key;
	Word * data;
} TableNode;

typedef struct {
	Word size;
	Word used_elements;
	Word elements;
} TableRoot;


static Word next_prime(Word);
static Word * create_hash_table(Word);
static void re_hash(Word *, Word, TableNode * Node);

/*
** Prime numbers which are close to powers of 2.  Used for choosing
** the next size for a hash table.
*/

#define NUM_OF_PRIMES 16
static Word primes[NUM_OF_PRIMES] =
    {127, 257, 509, 1021, 2053, 4099, 8191, 16381, 32771, 65537, 131071,
       262147, 524287, 1048573, 2097143, 4194301};

/*
** Return the next prime number greater than the number received.
** If no such prime number can be found, compute an approximate one.
*/
static Word 
next_prime(Word old_size) 
{
	int i;

	i = 0;
	while ( (old_size >= primes[i]) && (i < NUM_OF_PRIMES) ) {
		i++;
	}

	if (i < NUM_OF_PRIMES) {
		return primes[i];
	} else { 
		return 2 * old_size - 1;
	}
}

/* Create a new empty hash table. */
static Word * 
create_hash_table(Word table_size)
{
   	Word i;
	TableRoot * table =
		table_allocate_bytes(sizeof(Word) * 2 +
				table_size * sizeof(TableNode *));
	
	table->size = table_size;
	table->used_elements = 0;

	for (i = 0; i < table_size; i++) {
		BUCKET(table, i) = NULL;
	}

	return (Word *) table;
}

/* 
** Insert key and Data into a new hash table using the given hash.
** this function does not have to do compares as the given key 
** is definitely not in the table. 
*/
static void
re_hash(Word * table, Word hash, TableNode * node)
{
	Word bucket = hash % SIZE(table);

	while (BUCKET(table, bucket)) {
		++bucket;

		if (bucket == SIZE(table))
			bucket = 0;
	}

	BUCKET(table, bucket) = node;
	++ELEMENTS(table);
}			

/* 
** Look to see if the given integer key is in the given table. If it
** is return the address of the data pointer associated with the key.
** If it is not; create a new element for the key in the table and
** return the address of its data pointer.
*/
TrieNode 
MR_int_hash_lookup_or_add(TrieNode t, Integer key)
{
	TableNode * p, * q;
	Word * table = *t;	/* Deref the table pointer */
	Word bucket;
	
	/* Has the the table been built? */
	if (table == NULL) {
		table = create_hash_table(TABLE_START_SIZE);
		*t = table;
	}

	bucket = key % SIZE(table);
	p = BUCKET(table, bucket);

	/* Find if the element is present. If not add it */
	while (p) {
		if (key == p->key) {
			return &p->data;
		}

		if (bucket == SIZE(table))
			bucket = 0;
		
		p = BUCKET(table, bucket);
	}

	p = table_allocate_bytes(sizeof(TableNode));
	p->key = key;
	p->data = NULL;

	/* Rehash the table if it has grown to full */
	if ((float) ELEMENTS(table) / (float) SIZE(table) > 
	   		MAX_EL_SIZE_RATIO) 
	{
		int old_size = SIZE(table);
		int new_size = next_prime(old_size);
		Word * new_table = create_hash_table(new_size);
		int i;
		
		for (i = 0; i < old_size; i++) {
			q = BUCKET(table, i);
			if (q) {
				re_hash(new_table, q->key, q);
			}
		}
		
		/* Free the old table */
		table_free(table);

		/* Point to the new table */
		*t = new_table;
		
		/* Add a new element */
		re_hash(new_table, key, p);
	} else {
		BUCKET(table, bucket) = p;
		++ELEMENTS(table);
	}

	return &p->data;
}

/* 
** Look to see if the given float key is in the given table. If it
** is return the address of the data pointer associated with the key.
** If it is not create a new element for the key in the table and
** return the address of its data pointer.
*/
TrieNode 
MR_float_hash_lookup_or_add(TrieNode t, Float key)
{
	TableNode * p, * q;
	Word * table = *t;	/* Deref the table pointer */
	Word bucket;
	Word hash;

	/* Has the the table been built? */
	if (table == NULL) {
		table = create_hash_table(TABLE_START_SIZE);
		*t = table;
	}

	hash = hash_float(key);
	bucket = hash % SIZE(table);

	p = BUCKET(table, bucket);

	/* Find if the element is present. If not add it */
	while (p) {
		if (key == word_to_float(p->key)) {
			return &p->data;
		}
		++bucket;
		
		if (bucket == SIZE(table))
			bucket = 0;
		
		p = BUCKET(table, bucket);
	}

	p = table_allocate_bytes(sizeof(TableNode));
	p->key = float_to_word(key);
	p->data = NULL;
	
	/* Rehash the table if it has grown to full */
	if ((float) ELEMENTS(table) / (float) SIZE(table) > 
	   		MAX_EL_SIZE_RATIO) 
	{
		int old_size = SIZE(table);
		int new_size = next_prime(old_size);
		Word * new_table = create_hash_table(new_size);
		int i;

		for (i = 0; i < old_size; i++) {
			q = BUCKET(table, i);
			if (q) {
				re_hash(new_table, hash_float(q->key), q); 
			}
		}
		
		/* Free the old table */
		table_free(table);

		/* Point to the new table */
		*t = new_table;
		
		/* Add a new element */
		re_hash(new_table, hash, p);
	} else {
		++ELEMENTS(table);
		BUCKET(table, bucket) = p;
	}

	return &p->data;
}



/* 
** Look to see if the given string key is in the given table. If it
** is return the address of the data pointer associated with the key.
** If it is not create a new element for the key in the table and
** return the address of its data pointer.
*/
TrieNode 
MR_string_hash_lookup_or_add(TrieNode t, String key)
{
	TableNode * p, * q;
	Word * table = *t;	/* Deref the table pointer */
	Word bucket;
	Word hash;

	/* Has the the table been built? */
	if (table == NULL) {
		table = create_hash_table(TABLE_START_SIZE);
		*t = table;
	}

	hash = hash_string((Word) key);
	bucket = hash % SIZE(table);

	p = BUCKET(table, bucket);

	/* Find if the element is present. */
	while (p) {
		int res = strtest((String)p->key, key);
		
		if (res == 0) {
			return &p->data;
		}
		++bucket;
		
		if (bucket == SIZE(table))
			bucket = 0;
		
		p = BUCKET(table, bucket);
	}

	p = table_allocate_bytes(sizeof(TableNode));
	p->key = (Word) key;
	p->data = NULL;
	
	/* Rehash the table if it has grown to full */
	if ((float) ELEMENTS(table) / (float) SIZE(table) > 
	   		MAX_EL_SIZE_RATIO) 
	{
		int old_size = SIZE(table);
		int new_size = next_prime(old_size);
		Word * new_table = create_hash_table(new_size);
		int i;

		for (i = 0; i < old_size; i++) {
			q = BUCKET(table, i);
			if (q) {
				re_hash(new_table, 
					hash_string((Word) q->key), q); 
			}
		}
		
		/* Free the old table */
		table_free(t);

		/* Point to the new table */
		*t = new_table;
		
		/* Add a new element to rehashed table */
		re_hash(new_table, hash, p); 
	} else {
		BUCKET(table, bucket) = p;
		++ELEMENTS(table);
	}

	return &p->data;
}

/*---------------------------------------------------------------------------*/

/*
** This part defines the MR_int_index_lookup_or_add() function.
*/

#define ELEMENT(Table, Key) ((Word**)&((Table)[Key]))

/*
**  MR_int_index_lookup_or_add() : This function maintains a simple indexed
**	table of size Range.
*/

TrieNode
MR_int_index_lookup_or_add(TrieNode t, Integer range, Integer key)
{
	Word *table = *t;		/* Deref table */

#ifdef	MR_TABLE_DEBUG
	if (key >= range) {
		fatal_error("MR_int_index_lookup_or_add: key out of range");
	}
#endif

	if (table == NULL) {
		*t = table = table_allocate_words(range);
		memset(table, 0, sizeof(Word *) * range);
	}

	return ELEMENT(table, key);
}

#undef ELEMENT

/*---------------------------------------------------------------------------*/

/*
** This part defines the type_info_lookup_or_add() function.
*/

typedef struct TreeNode_struct {
	Word * key;
	Word value;
	struct TreeNode_struct * right;
	struct TreeNode_struct * left;
} TreeNode;

TrieNode
MR_type_info_lookup_or_add(TrieNode table, Word * type_info)
{
	TreeNode *p, *q;
	int i;

	if (*table == NULL) {
		p = table_allocate_bytes(sizeof(TreeNode));

		p->key = type_info;
		p->value = (Word) NULL;
		p->left = NULL;
		p->right = NULL;

		*table = (Word *) p;

		return (Word**) &p->value;
	}
	
	p = (TreeNode *) *table;

	while (p != NULL) {
		i = MR_compare_type_info((Word) p->key, (Word) type_info);

		if (i == COMPARE_EQUAL) {
			return (Word **) &p->value;
		} 
		
		q = p;
		
		if (i == COMPARE_LESS) {
			p = p->left;
		} else {
			p = p->right;
		}
	}

	p = table_allocate_bytes(sizeof(TreeNode));
	p->key = type_info;
	p->value = (Word) NULL; 
	p->left = NULL;
	p->right = NULL;

	if (i == COMPARE_LESS) {
		q->left = p;
	} else {
		q ->right = p;
	}
	
	return (Word **) &p->value;
}

/*---------------------------------------------------------------------------*/


/*
** This part defines the MR_table_type() function.
*/

MR_DECLARE_STRUCT(mercury_data___base_type_info_pred_0);
MR_DECLARE_STRUCT(mercury_data___base_type_info_func_0);

/*
** Due to the depth of the control here, we'll use 4 space indentation.
**
** NOTE : changes to this function will probably also have to be reflected
** in mercury_deep_copy.c and std_util::ML_expand().
*/

TrieNode
MR_table_type(TrieNode table, Word *type_info, Word data)
{
    Word *base_type_info, *base_type_layout, *base_type_functors;
    Word layout_for_tag, *layout_vector_for_tag, *data_value;
    enum MR_DataRepresentation data_rep;
    int data_tag, entry_tag;

    MR_MemoryList allocated_memory_cells = NULL;

    data_tag = tag(data);
    data_value = (Word *) body(data, data_tag);

    base_type_info = MR_TYPEINFO_GET_BASE_TYPEINFO(type_info);
    base_type_layout = MR_BASE_TYPEINFO_GET_TYPELAYOUT(base_type_info);
    base_type_functors = MR_BASE_TYPEINFO_GET_TYPEFUNCTORS(base_type_info);

    layout_for_tag = base_type_layout[data_tag];
    layout_vector_for_tag = (Word *) strip_tag(layout_for_tag);

    data_rep = MR_categorize_data(MR_TYPEFUNCTORS_INDICATOR(base_type_functors),
		    layout_for_tag);

#ifdef	MR_TABLE_DEBUG
    if (MR_tabledebug) {
	printf("ENTRY %p %x, data rep: %d\n", table, data, data_rep);
    }
#endif	/* MR_TABLE_DEBUG */

    switch (data_rep) {
        case MR_DATAREP_ENUM: {
	    int functors = MR_TYPELAYOUT_ENUM_VECTOR_NUM_FUNCTORS(
				layout_vector_for_tag);
	    MR_DEBUG_TABLE_ENUM(table, functors, data);
            break;
        }
        case MR_DATAREP_COMPLICATED_CONST: {
	    int functors = MR_TYPELAYOUT_ENUM_VECTOR_NUM_FUNCTORS(
				layout_vector_for_tag);
	    MR_DEBUG_TABLE_TAG(table, data_tag);
	    MR_DEBUG_TABLE_ENUM(table, functors, unmkbody(data));
            break;
        }
        case MR_DATAREP_SIMPLE: {
            int arity, i;
            Word *argument_vector, *type_info_vector, *new_type_info;

            argument_vector = data_value;

            arity = layout_vector_for_tag[TYPELAYOUT_SIMPLE_ARITY_OFFSET];
            type_info_vector = &layout_vector_for_tag[
		    		TYPELAYOUT_SIMPLE_ARGS_OFFSET];

	    MR_DEBUG_TABLE_TAG(table, data_tag);

                 /* copy arguments */
            for (i = 0; i < arity; i++) {
                new_type_info = MR_make_type_info(type_info,
                    (Word *) type_info_vector[i], &allocated_memory_cells);

                MR_DEBUG_TABLE_ANY(table, new_type_info, argument_vector[i]);
            }
            break;
        }
        case MR_DATAREP_COMPLICATED: {
            int arity, i;
            Word *argument_vector, *type_info_vector, *new_type_info;
            Word secondary_tag, num_sharers, *new_layout_vector;

            secondary_tag = *data_value;
            argument_vector = data_value + 1;

            num_sharers = MR_TYPELAYOUT_COMPLICATED_VECTOR_NUM_SHARERS(
            			layout_vector_for_tag);
            new_layout_vector =
                MR_TYPELAYOUT_COMPLICATED_VECTOR_GET_SIMPLE_VECTOR(
                    layout_vector_for_tag, secondary_tag);
            arity = new_layout_vector[TYPELAYOUT_SIMPLE_ARITY_OFFSET];
            type_info_vector =
		    &new_layout_vector[TYPELAYOUT_SIMPLE_ARGS_OFFSET];

	    MR_DEBUG_TABLE_TAG(table, data_tag);
	    MR_DEBUG_TABLE_ENUM(table, num_sharers, secondary_tag);

            for (i = 0; i < arity; i++) {
                new_type_info = MR_make_type_info(type_info,
                    (Word *) type_info_vector[i], &allocated_memory_cells);

                MR_DEBUG_TABLE_ANY(table, new_type_info, argument_vector[i]);
            }
            break;
        }
        case MR_DATAREP_NOTAG: {
            Word *new_type_info;
            new_type_info = MR_make_type_info(type_info,
                (Word *) *MR_TYPELAYOUT_NO_TAG_VECTOR_ARGS(
		    layout_vector_for_tag),
                &allocated_memory_cells);
            MR_DEBUG_TABLE_ANY(table, new_type_info, data);
            break;
        }
        case MR_DATAREP_EQUIV: {
            Word *new_type_info;
            new_type_info = MR_make_type_info(type_info,
                (Word *) MR_TYPELAYOUT_EQUIV_TYPE(layout_vector_for_tag),
                &allocated_memory_cells);
            MR_DEBUG_TABLE_ANY(table, new_type_info, data);
            break;
        }
        case MR_DATAREP_EQUIV_VAR:
            MR_DEBUG_TABLE_ANY(table,
		(Word *) type_info[(Word) layout_vector_for_tag], data);
            break;

        case MR_DATAREP_INT:
            MR_DEBUG_TABLE_INT(table, data);
            break;

        case MR_DATAREP_CHAR:
            MR_DEBUG_TABLE_CHAR(table, data);
            break;

        case MR_DATAREP_FLOAT:
            MR_DEBUG_TABLE_FLOAT(table, data);
            break;

        case MR_DATAREP_STRING:
            MR_DEBUG_TABLE_STRING(table, data);
            break;

        case MR_DATAREP_PRED: {
            int i;
            Word args = data_value[0];

            MR_DEBUG_TABLE_STRING(table, args);
            MR_DEBUG_TABLE_STRING(table, data_value[1]);

            for (i = 0; i < args; i++) {
        	MR_DEBUG_TABLE_ANY(table,
                    (Word *) type_info[i + TYPEINFO_OFFSET_FOR_PRED_ARGS],
                    data_value[i+2]);
            }
            break;
        }
        case MR_DATAREP_UNIV:
            MR_DEBUG_TABLE_TYPEINFO(table,
                (Word *) data_value[UNIV_OFFSET_FOR_TYPEINFO]);
            MR_DEBUG_TABLE_ANY(table,
                (Word *) data_value[UNIV_OFFSET_FOR_TYPEINFO],
                data_value[UNIV_OFFSET_FOR_DATA]);
            break;

        case MR_DATAREP_VOID:
            fatal_error("Cannot table a void type");
            break;

        case MR_DATAREP_ARRAY: {
            int i;
            MR_ArrayType *array;
            Word *new_type_info;
            Integer array_size;

            array = (MR_ArrayType *) data_value;
            array_size = array->size;

            new_type_info = MR_make_type_info(type_info, (Word *) 1,
                &allocated_memory_cells);

            for (i = 0; i < array_size; i++) {
        	MR_DEBUG_TABLE_ANY(table, new_type_info, array->elements[i]);
            }
            break;
        }
        case MR_DATAREP_TYPEINFO:
            MR_DEBUG_TABLE_TYPEINFO(table, (Word *) data_value);
            break;

        case MR_DATAREP_C_POINTER:
            fatal_error("Attempt to use a C_POINTER tag in table");
            break;

        case MR_DATAREP_UNKNOWN: /* fallthru */
        default:
            fatal_error("Unknown layout tag in table_any");
            break;
    }

    MR_deallocate(allocated_memory_cells);

    return table;
} /* end table_any() */

/*---------------------------------------------------------------------------*/

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"
PGP: finger fjh at 128.250.37.3        |     -- leaked Microsoft memo.



More information about the developers mailing list