[m-dev.] for review: tuples [2]
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Aug 1 14:16:22 AEST 2000
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.194
diff -u -u -r1.194 std_util.m
--- library/std_util.m 2000/07/18 00:46:19 1.194
+++ library/std_util.m 2000/08/01 02:56:39
@@ -430,6 +430,11 @@
:- func construct(type_desc, int, list(univ)) = univ.
:- mode construct(in, in, in) = out is semidet.
+ % construct_tuple(Args) = Term
+ %
+ % Returns a tuple whose arguments are given by Args.
+:- func construct_tuple(list(univ)) = univ.
+
%-----------------------------------------------------------------------------%
% functor, argument and deconstruct take any type (including univ),
@@ -451,6 +456,7 @@
% quotation marks
% - for predicates and functions, the string
% <<predicate>>
+ % - for tuples, the string {}
% functor(Data, Functor, Arity)
%
@@ -470,8 +476,8 @@
% Argument to that argument of the functor of the data item. If
% the argument index is out of range -- that is, greater than or
% equal to the arity of the functor or lower than 0 -- then
- % the call fails. For argument/1 the argument returned has the
- % type univ, which can store any type. For arg/1, if the
+ % the call fails. For argument/2 the argument returned has the
+ % type univ, which can store any type. For arg/2, if the
% argument has the wrong type, then the call fails.
% (Both abort if the type of Data is a type with a non-canonical
% representation, i.e. one for which there is a user-defined
@@ -1217,12 +1223,13 @@
** Values of type `std_util:type_ctor_desc' are not guaranteed to be
** represented the same way as values of type `private_builtin:type_ctor_info'.
** The representations *are* in fact identical for first order types, but they
-** differ for higher order types. Instead of a type_ctor_desc being a structure
-** containing a pointer to the type_ctor_info for pred/0 or func/0 and an
-** arity, we have a single small encoded integer. This integer is double
-** the arity, plus zero or one; plus zero encodes a predicate, plus one encodes
-** a function. The maximum arity that can be encoded is given by
-** MR_MAX_HO_ARITY (see below).
+** differ for higher order and tuple types. Instead of a type_ctor_desc
+** being a structure containing a pointer to the type_ctor_info for pred/0
+** or func/0 and an arity, we have a single small encoded integer. This
+** integer is four times the arity, plus zero, one or two; plus zero encodes a
+** tuple, plus one encodes a predicate, plus two encodes a function.
+** The maximum arity that can be encoded is given by MR_MAX_VARIABLE_ARITY
+** (see below).
** The C type corresponding to std_util:type_ctor_desc is `MR_TypeCtorInfo'.
*/
@@ -1243,51 +1250,64 @@
** number of general purpose registers, since an predicate or function having
** more arguments that this would run out of registers when passing the input
** arguments, or the output arguments, or both.
+**
+** XXX When tuples were added this was reduced to be the maximum number
+** of general purpose registers, to reduce the probability that the
+** `small' integers for higher-order and tuple types are confused with
+** type_ctor_info pointers. This still allows higher-order terms with
+** 1024 arguments, which is more than ../LIMITATIONS promises.
*/
-#define MR_MAX_HO_ARITY (2 * MAX_VIRTUAL_REG)
+#define MR_MAX_VARIABLE_ARITY MAX_VIRTUAL_REG
/*
** Constructors for the MR_TypeCtorDesc ADT
*/
+
#define MR_TYPECTOR_DESC_MAKE_PRED(Arity) \
- ( (MR_TypeCtorDesc) ((Arity) * 2) )
+ ( (MR_TypeCtorDesc) ((Arity) * 4) )
#define MR_TYPECTOR_DESC_MAKE_FUNC(Arity) \
- ( (MR_TypeCtorDesc) ((Arity) * 2 + 1) )
-#define MR_TYPECTOR_DESC_MAKE_FIRST_ORDER(type_ctor_info) \
- ( MR_CHECK_EXPR_TYPE(type_ctor_info, MR_TypeCtorInfo), \
- (MR_TypeCtorDesc) type_ctor_info )
+ ( (MR_TypeCtorDesc) ((Arity) * 4 + 1) )
+#define MR_TYPECTOR_DESC_MAKE_TUPLE(Arity) \
+ ( (MR_TypeCtorDesc) ((Arity) * 4 + 2) )
+#define MR_TYPECTOR_DESC_MAKE_FIXED_ARITY(type_ctor_info) \
+ ( MR_CHECK_EXPR_TYPE(type_ctor_info, MR_TypeCtorInfo), \
+ (MR_TypeCtorDesc) type_ctor_info )
/*
** Access macros for the MR_TypeCtor ADT.
**
-** The MR_TYPECTOR_DESC_GET_HOT_* macros should only be called if
-** MR_TYPECTOR_DESC_IS_HIGHER_ORDER() returns true.
-** The MR_TYPECTOR_DESC_GET_FIRST_ORDER_TYPE_CTOR_INFO() macro
-** should only be called if MR_TYPECTOR_DESC_IS_HIGHER_ORDER() returns false.
+** The MR_TYPECTOR_DESC_GET_VA_* macros should only be called if
+** MR_TYPECTOR_DESC_IS_VARIABLE_ARITY() returns true.
+** The MR_TYPECTOR_DESC_GET_FIXED_ARITY_TYPE_CTOR_INFO() macro
+** should only be called if MR_TYPECTOR_DESC_IS_VARIABLE_ARITY() returns false.
*/
-#define MR_TYPECTOR_DESC_IS_HIGHER_ORDER(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
- (Unsigned) (T) <= (2 * MR_MAX_HO_ARITY + 1) )
-#define MR_TYPECTOR_DESC_GET_FIRST_ORDER_TYPE_CTOR_INFO(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
- (MR_TypeCtorInfo) (T) )
-#define MR_TYPECTOR_DESC_GET_HOT_ARITY(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
- (Unsigned) (T) / 2 )
-#define MR_TYPECTOR_DESC_GET_HOT_NAME(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
- (ConstString) (((Unsigned) (T) % 2 != 0) \
- ? ""func"" \
- : ""pred"" ))
-#define MR_TYPECTOR_DESC_GET_HOT_MODULE_NAME(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+#define MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+ (Unsigned) (T) <= (4 * MR_MAX_VARIABLE_ARITY + 2) )
+#define MR_TYPECTOR_DESC_GET_FIXED_ARITY_TYPE_CTOR_INFO(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+ (MR_TypeCtorInfo) (T) )
+#define MR_TYPECTOR_DESC_GET_VA_ARITY(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+ (Unsigned) (T) / 4 )
+#define MR_TYPECTOR_DESC_GET_VA_NAME(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+ (ConstString) (((Unsigned) (T) % 4 == 0) \
+ ? ""pred"" \
+ : (((Unsigned) (T) % 4 == 1) \
+ ? ""func"" \
+ : ""{}"" )) )
+#define MR_TYPECTOR_DESC_GET_VA_MODULE_NAME(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
(ConstString) ""builtin"" )
-#define MR_TYPECTOR_DESC_GET_HOT_TYPE_CTOR_INFO(T) \
- ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
- ((Unsigned) (T) % 2 != 0) \
- ? MR_TYPE_CTOR_INFO_HO_FUNC \
- : MR_TYPE_CTOR_INFO_HO_PRED )
-
+#define MR_TYPECTOR_DESC_GET_VA_TYPE_CTOR_INFO(T) \
+ ( MR_CHECK_EXPR_TYPE(T, MR_TypeCtorDesc), \
+ ((Unsigned) (T) % 4 == 0) \
+ ? MR_TYPE_CTOR_INFO_HO_PRED \
+ : (((Unsigned) (T) % 4 == 1) \
+ ? MR_TYPE_CTOR_INFO_HO_FUNC \
+ : MR_TYPE_CTOR_INFO_TUPLE ) )
+
#endif /* ML_TYPECTORDESC_GUARD */
").
@@ -1381,6 +1401,13 @@
IsFunc = no
),
(
+ ModuleName = "builtin", Name = "{}"
+ ->
+ type_arg_names(ArgTypes, IsFunc, ArgTypeNames),
+ list__append(ArgTypeNames, ["}"], TypeStrings0),
+ TypeStrings = ["{" | TypeStrings0],
+ string__append_list(TypeStrings, UnqualifiedTypeName)
+ ;
IsFunc = yes,
ArgTypes = [FuncRetType]
->
@@ -1469,19 +1496,26 @@
if (MR_TYPE_CTOR_INFO_IS_HO_PRED(type_ctor_info)) {
type_ctor_desc = MR_TYPECTOR_DESC_MAKE_PRED(
MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info));
- if (! MR_TYPECTOR_DESC_IS_HIGHER_ORDER(type_ctor_desc)) {
+ if (! MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
MR_fatal_error(""std_util:ML_make_type_ctor_desc""
""- arity out of range."");
}
} else if (MR_TYPE_CTOR_INFO_IS_HO_FUNC(type_ctor_info)) {
type_ctor_desc = MR_TYPECTOR_DESC_MAKE_FUNC(
MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info));
- if (! MR_TYPECTOR_DESC_IS_HIGHER_ORDER(type_ctor_desc)) {
+ if (! MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
MR_fatal_error(""std_util:ML_make_type_ctor_desc""
""- arity out of range."");
}
+ } else if (MR_TYPE_CTOR_INFO_IS_TUPLE(type_ctor_info)) {
+ type_ctor_desc = MR_TYPECTOR_DESC_MAKE_TUPLE(
+ MR_TYPEINFO_GET_TUPLE_ARITY(type_info));
+ if (! MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
+ MR_fatal_error(""std_util:ML_make_type_ctor_desc""
+ ""- arity out of range."");
+ }
} else {
- type_ctor_desc = MR_TYPECTOR_DESC_MAKE_FIRST_ORDER(
+ type_ctor_desc = MR_TYPECTOR_DESC_MAKE_FIXED_ARITY(
type_ctor_info);
}
@@ -1506,8 +1540,9 @@
type_ctor_desc = ML_make_type_ctor_desc(type_info, type_ctor_info);
*type_ctor_desc_ptr = type_ctor_desc;
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
- arity = MR_TYPECTOR_DESC_GET_HOT_ARITY(type_ctor_desc);
+ if (MR_type_ctor_rep_is_variable_arity(type_ctor_info->type_ctor_rep))
+ {
+ arity = MR_TYPECTOR_DESC_GET_VA_ARITY(type_ctor_desc);
*arg_type_info_list_ptr = ML_type_params_vector_to_list(arity,
MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info));
} else {
@@ -1552,10 +1587,10 @@
type_ctor_desc = (MR_TypeCtorDesc) TypeCtorDesc;
- if (MR_TYPECTOR_DESC_IS_HIGHER_ORDER(type_ctor_desc)) {
- arity = MR_TYPECTOR_DESC_GET_HOT_ARITY(type_ctor_desc);
+ if (MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
+ arity = MR_TYPECTOR_DESC_GET_VA_ARITY(type_ctor_desc);
} else {
- type_ctor_info = MR_TYPECTOR_DESC_GET_FIRST_ORDER_TYPE_CTOR_INFO(
+ type_ctor_info = MR_TYPECTOR_DESC_GET_FIXED_ARITY_TYPE_CTOR_INFO(
type_ctor_desc);
arity = type_ctor_info->arity;
}
@@ -1602,16 +1637,16 @@
type_ctor_desc = (MR_TypeCtorDesc) TypeCtorDesc;
- if (MR_TYPECTOR_DESC_IS_HIGHER_ORDER(type_ctor_desc)) {
+ if (MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
TypeCtorModuleName = (String) (Word)
- MR_TYPECTOR_DESC_GET_HOT_MODULE_NAME(type_ctor_desc);
+ MR_TYPECTOR_DESC_GET_VA_MODULE_NAME(type_ctor_desc);
TypeCtorName = (String) (Word)
- MR_TYPECTOR_DESC_GET_HOT_NAME(type_ctor_desc);
- TypeCtorArity = MR_TYPECTOR_DESC_GET_HOT_ARITY(type_ctor_desc);
+ MR_TYPECTOR_DESC_GET_VA_NAME(type_ctor_desc);
+ TypeCtorArity = MR_TYPECTOR_DESC_GET_VA_ARITY(type_ctor_desc);
} else {
MR_TypeCtorInfo type_ctor_info;
- type_ctor_info = MR_TYPECTOR_DESC_GET_FIRST_ORDER_TYPE_CTOR_INFO(
+ type_ctor_info = MR_TYPECTOR_DESC_GET_FIXED_ARITY_TYPE_CTOR_INFO(
type_ctor_desc);
/*
@@ -1669,12 +1704,22 @@
construct_info.functor_name);
arity = construct_info.arity;
Arity = arity;
- save_transient_registers();
- TypeInfoList = ML_pseudo_type_info_vector_to_type_info_list(
- arity,
- MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info),
- construct_info.arg_pseudo_type_infos);
- restore_transient_registers();
+
+ if (MR_TYPE_CTOR_INFO_IS_TUPLE(
+ MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info)))
+ {
+ save_transient_registers();
+ TypeInfoList = ML_type_params_vector_to_list(Arity,
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info));
+ restore_transient_registers();
+ } else {
+ save_transient_registers();
+ TypeInfoList = ML_pseudo_type_info_vector_to_type_info_list(
+ arity,
+ MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info),
+ construct_info.arg_pseudo_type_infos);
+ restore_transient_registers();
+ }
}
SUCCESS_INDICATOR = success;
}
@@ -1713,6 +1758,7 @@
case MR_TYPECTOR_REP_NOTAG_USEREQ:
case MR_TYPECTOR_REP_NOTAG_GROUND:
case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
+ case MR_TYPECTOR_REP_TUPLE:
Ordinal = 0;
break;
@@ -1850,6 +1896,30 @@
}
break;
+ case MR_TYPECTOR_REP_TUPLE:
+ {
+ int arity, i;
+ Word arg_list;
+
+ arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ incr_hp_msg(new_data, arity, MR_PROC_LABEL,
+ ""<created by std_util:construct/3>"");
+
+ arg_list = ArgList;
+ for (i = 0; i < arity; i++) {
+ MR_field(MR_mktag(0), new_data, i) =
+ MR_field(MR_mktag(0), MR_list_head(arg_list),
+ UNIV_OFFSET_FOR_DATA);
+ arg_list = MR_list_tail(arg_list);
+ }
+
+ if (! MR_list_is_empty(arg_list)) {
+ MR_fatal_error(""excess arguments in std_util:construct"");
+ }
+ }
+ break;
+
default:
MR_fatal_error(""bad type_ctor_rep in std_util:construct"");
}
@@ -1869,6 +1939,50 @@
}
").
+construct_tuple(Args) =
+ construct_tuple_2(Args,
+ list__map(univ_type, Args),
+ list__length(Args)).
+
+:- func construct_tuple_2(list(univ), list(type_desc), int) = univ.
+
+:- pragma c_code(construct_tuple_2(Args::in, ArgTypes::in,
+ Arity::in) = (Term::out),
+ will_not_call_mercury, "
+{
+ MR_TypeInfo type_info;
+ Word new_data;
+ Word arg_value;
+ int i;
+
+ /*
+ ** Construct a type_info for the tuple.
+ */
+ type_info = ML_make_type(Arity, MR_TYPECTOR_DESC_MAKE_TUPLE(Arity),
+ ArgTypes);
+
+ /*
+ ** Create the tuple.
+ */
+ incr_hp_msg(new_data, Arity, MR_PROC_LABEL,
+ ""<created by std_util:construct_tuple/1>"");
+ for (i = 0; i < Arity; i++) {
+ arg_value = MR_field(MR_mktag(0), MR_list_head(Args),
+ UNIV_OFFSET_FOR_DATA);
+ MR_field(MR_mktag(0), new_data, i) = arg_value;
+ Args = MR_list_tail(Args);
+ }
+
+ /*
+ ** Create a univ.
+ */
+ incr_hp_msg(Term, 2, MR_PROC_LABEL, ""std_util:univ/0"");
+ MR_field(MR_mktag(0), Term, UNIV_OFFSET_FOR_TYPEINFO) =
+ (Word) type_info;
+ MR_field(MR_mktag(0), Term, UNIV_OFFSET_FOR_DATA) = new_data;
+}
+").
+
:- pragma c_code("
/*
@@ -1980,6 +2094,14 @@
MR_fatal_error(""unexpected EQUIV_VAR type_ctor_rep"");
break;
+ case MR_TYPECTOR_REP_TUPLE:
+ construct_info->functor_name = ""{}"";
+ construct_info->arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ /* Tuple types don't have pseudo-type_infos for the functors. */
+ construct_info->arg_pseudo_type_infos = NULL;
+ break;
+
case MR_TYPECTOR_REP_INT:
case MR_TYPECTOR_REP_CHAR:
case MR_TYPECTOR_REP_FLOAT:
@@ -2043,9 +2165,15 @@
list_arg_type_info = (MR_TypeInfo) MR_field(MR_mktag(0),
MR_list_head(arg_list), UNIV_OFFSET_FOR_TYPEINFO);
- arg_type_info = MR_create_type_info(
- MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info),
- arg_pseudo_type_infos[i]);
+ if (MR_TYPE_CTOR_INFO_IS_TUPLE(
+ MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info)))
+ {
+ arg_type_info = MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info)[i + 1];
+ } else {
+ arg_type_info = MR_create_type_info(
+ MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info),
+ arg_pseudo_type_infos[i]);
+ }
comp = MR_compare_type_info(list_arg_type_info, arg_type_info);
if (comp != MR_COMPARE_EQUAL) {
@@ -2106,22 +2234,22 @@
int i;
/*
- ** We need to treat higher-order predicates as a special case here.
+ ** We need to treat higher-order and tuple types as a special case here.
*/
- if (MR_TYPECTOR_DESC_IS_HIGHER_ORDER(type_ctor_desc)) {
- type_ctor_info = MR_TYPECTOR_DESC_GET_HOT_TYPE_CTOR_INFO(
+ if (MR_TYPECTOR_DESC_IS_VARIABLE_ARITY(type_ctor_desc)) {
+ type_ctor_info = MR_TYPECTOR_DESC_GET_VA_TYPE_CTOR_INFO(
type_ctor_desc);
restore_transient_registers();
incr_hp_atomic_msg(LVALUE_CAST(Word, new_type_info_arena),
MR_higher_order_type_info_size(arity),
- ""mercury__std_util__ML_make_type"", ""type_info"");
+ ""mercury__std_util__ML_make_type"", ""type_info"");
save_transient_registers();
MR_fill_in_higher_order_type_info(new_type_info_arena,
type_ctor_info, arity, new_type_info_args);
} else {
- type_ctor_info = MR_TYPECTOR_DESC_GET_FIRST_ORDER_TYPE_CTOR_INFO(
+ type_ctor_info = MR_TYPECTOR_DESC_GET_FIXED_ARITY_TYPE_CTOR_INFO(
type_ctor_desc);
if (arity == 0) {
@@ -2131,7 +2259,7 @@
restore_transient_registers();
incr_hp_atomic_msg(LVALUE_CAST(Word, new_type_info_arena),
MR_first_order_type_info_size(arity),
- ""mercury__std_util__ML_make_type"", ""type_info"");
+ ""mercury__std_util__ML_make_type"", ""type_info"");
save_transient_registers();
MR_fill_in_first_order_type_info(new_type_info_arena,
type_ctor_info, new_type_info_args);
@@ -2274,6 +2402,7 @@
case MR_TYPECTOR_REP_NOTAG_USEREQ:
case MR_TYPECTOR_REP_NOTAG_GROUND:
case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
+ case MR_TYPECTOR_REP_TUPLE:
functors = 1;
break;
@@ -2366,6 +2495,7 @@
int num_extra_args;
Word *arg_values;
MR_TypeInfo *arg_type_infos;
+ bool can_free_arg_type_infos;
bool non_canonical_type;
bool need_functor;
bool need_args;
@@ -2431,6 +2561,7 @@
type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
expand_info->non_canonical_type = FALSE;
+ expand_info->can_free_arg_type_infos = FALSE;
switch(type_ctor_info->type_ctor_rep) {
@@ -2504,6 +2635,7 @@
int i;
expand_info->arg_values = arg_vector;
+ expand_info->can_free_arg_type_infos = TRUE;
expand_info->arg_type_infos = MR_GC_NEW_ARRAY(MR_TypeInfo,
expand_info->arity);
@@ -2542,6 +2674,7 @@
if (expand_info->need_args) {
expand_info->arg_values = data_word_ptr;
+ expand_info->can_free_arg_type_infos = TRUE;
expand_info->arg_type_infos = MR_GC_NEW_ARRAY(MR_TypeInfo, 1);
expand_info->arg_type_infos[0] = MR_create_type_info(
MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info),
@@ -2566,6 +2699,7 @@
if (expand_info->need_args) {
expand_info->arg_values = data_word_ptr;
+ expand_info->can_free_arg_type_infos = TRUE;
expand_info->arg_type_infos = MR_GC_NEW_ARRAY(MR_TypeInfo, 1);
expand_info->arg_type_infos[0] =
MR_pseudo_type_info_is_ground(type_ctor_info->
@@ -2688,6 +2822,25 @@
expand_info->num_extra_args = 0;
break;
+ case MR_TYPECTOR_REP_TUPLE:
+ expand_info->arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+ expand_info->num_extra_args = 0;
+
+ if (expand_info->need_functor) {
+ MR_make_aligned_string(expand_info->functor, ""{}"");
+ }
+ if (expand_info->need_args) {
+ expand_info->arg_values = (Word *) *data_word_ptr;
+
+ /*
+ ** Type-infos are normally counted from one, but
+ ** the users of this vector count from zero.
+ */
+ expand_info->arg_type_infos =
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info) + 1;
+ }
+ break;
+
case MR_TYPECTOR_REP_UNIV: {
Word data_word;
/*
@@ -2888,7 +3041,9 @@
** the stuff we want out of it.
*/
- MR_GC_free(expand_info.arg_type_infos);
+ if (expand_info.can_free_arg_type_infos) {
+ MR_GC_free(expand_info.arg_type_infos);
+ }
return success;
}
@@ -3081,8 +3236,9 @@
** all its arguments onto the heap.
*/
- MR_GC_free(expand_info.arg_type_infos);
-
+ if (expand_info.can_free_arg_type_infos) {
+ MR_GC_free(expand_info.arg_type_infos);
+ }
}").
%-----------------------------------------------------------------------------%
Index: library/term_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/term_io.m,v
retrieving revision 1.58
diff -u -u -r1.58 term_io.m
--- library/term_io.m 1999/06/09 14:19:09 1.58
+++ library/term_io.m 2000/07/22 23:54:19
@@ -235,6 +235,14 @@
term_io__write_term_2(BracedTerm, VarSet0, N0, VarSet, N),
io__write_string(" }")
;
+ { Functor = term__atom("{}") },
+ { Args = [BracedHead | BracedTail] }
+ ->
+ io__write_char('{'),
+ term_io__write_arg_term(BracedHead, VarSet0, N0, VarSet1, N1),
+ term_io__write_term_args(BracedTail, VarSet1, N1, VarSet, N),
+ io__write_char('}')
+ ;
% the empty functor '' is used for higher-order syntax:
% Var(Arg, ...) gets parsed as ''(Var, Arg). When writing
% it out, we want to use the nice syntax.
Index: profiler/demangle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/profiler/demangle.m,v
retrieving revision 1.9
diff -u -u -r1.9 demangle.m
--- profiler/demangle.m 1999/06/15 07:10:14 1.9
+++ profiler/demangle.m 2000/07/26 04:59:54
@@ -490,6 +490,8 @@
insert_prefix(";")
; remove_prefix("f_cut") ->
insert_prefix("!")
+ ; remove_prefix("f_tuple") ->
+ insert_prefix("{}")
; remove_prefix("f_") ->
fix_mangled_ascii_chars
;
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.8
diff -u -u -r1.8 mercury.c
--- runtime/mercury.c 2000/07/20 10:39:35 1.8
+++ runtime/mercury.c 2000/08/01 02:17:26
@@ -80,6 +80,7 @@
static MR_UnifyFunc_1
mercury__array__do_unify__array_1_0,
+ mercury__builtin__do_unify__tuple_0_0,
mercury__private_builtin__do_unify__type_ctor_info_1_0,
mercury__private_builtin__do_unify__type_info_1_0,
mercury__private_builtin__do_unify__typeclass_info_1_0,
@@ -99,6 +100,7 @@
static MR_CompareFunc_1
mercury__array__do_compare__array_1_0,
+ mercury__builtin__do_compare__tuple_0_0,
mercury__private_builtin__do_compare__type_ctor_info_1_0,
mercury__private_builtin__do_compare__type_info_1_0,
mercury__private_builtin__do_compare__typeclass_info_1_0,
@@ -168,6 +170,7 @@
MR_define_type_ctor_info(builtin, c_pointer, 0, MR_TYPECTOR_REP_C_POINTER);
MR_define_type_ctor_info(builtin, pred, 0, MR_TYPECTOR_REP_PRED);
MR_define_type_ctor_info(builtin, func, 0, MR_TYPECTOR_REP_PRED);
+MR_define_type_ctor_info(builtin, tuple, 0, MR_TYPECTOR_REP_TUPLE);
MR_define_type_ctor_info(array, array, 1, MR_TYPECTOR_REP_ARRAY);
MR_define_type_ctor_info(std_util, univ, 0, MR_TYPECTOR_REP_UNIV);
MR_define_type_ctor_info(std_util, type_desc, 0, MR_TYPECTOR_REP_TYPEINFO);
@@ -199,19 +202,29 @@
{
MR_TypeInfo type_info;
MR_TypeCtorInfo type_ctor_info;
+ MR_TypeCtorRep type_ctor_rep;
int arity;
MR_TypeInfoParams params;
MR_Type_Info *args;
type_info = (MR_TypeInfo) ti;
type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
- arity = MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info);
- params = MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info);
- } else {
- arity = type_ctor_info->arity;
- params = MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info);
+
+ /*
+ ** Tuple and higher-order types do not have a fixed arity,
+ ** so they need to be special cased here.
+ */
+ type_ctor_rep = type_ctor_info->type_ctor_rep;
+ if (type_ctor_rep == MR_TYPECTOR_REP_TUPLE) {
+ return mercury__builtin____Unify____tuple_0_0(ti,
+ (MR_Tuple) x, (MR_Tuple) y);
+ } else if (type_ctor_rep == MR_TYPECTOR_REP_PRED) {
+ return mercury__builtin____Unify____pred_0_0((MR_Pred) x,
+ (MR_Pred) y);
}
+
+ arity = type_ctor_info->arity;
+ params = MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info);
args = (MR_Type_Info *) params;
switch(arity) {
@@ -247,19 +260,31 @@
{
MR_TypeInfo type_info;
MR_TypeCtorInfo type_ctor_info;
+ MR_TypeCtorRep type_ctor_rep;
int arity;
MR_TypeInfoParams params;
MR_Type_Info *args;
type_info = (MR_TypeInfo) ti;
type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
- arity = MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info);
- params = MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info);
- } else {
- arity = type_ctor_info->arity;
- params = MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info);
+
+ /*
+ ** Tuple and higher-order types do not have a fixed arity,
+ ** so they need to be special cased here.
+ */
+ type_ctor_rep = type_ctor_info->type_ctor_rep;
+ if (type_ctor_rep == MR_TYPECTOR_REP_TUPLE) {
+ mercury__builtin____Compare____tuple_0_0(ti,
+ res, (MR_Tuple) x, (MR_Tuple) y);
+ return;
+ } else if (type_ctor_rep == MR_TYPECTOR_REP_PRED) {
+ mercury__builtin____Compare____pred_0_0(res,
+ (MR_Pred) x, (MR_Pred) y);
+ return;
}
+
+ arity = type_ctor_info->arity;
+ params = MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info);
args = (MR_Type_Info *) params;
switch(arity) {
@@ -384,6 +409,30 @@
}
bool
+mercury__builtin____Unify____tuple_0_0(MR_Type_Info ti, MR_Tuple x, MR_Tuple y)
+{
+ int i, arity;
+ bool result;
+ MR_TypeInfo type_info;
+ MR_TypeInfo arg_type_info;
+
+ type_info = (MR_TypeInfo) ti;
+ arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ for (i = 0; i < arity; i++) {
+ /* type_infos are counted starting at one. */
+ arg_type_info =
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info)[i + 1];
+ result = mercury__builtin__unify_2_p_0(
+ (MR_Type_Info) arg_type_info, x[i], y[i]);
+ if (result == FALSE) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+bool
mercury__array____Unify____array_1_0(MR_Type_Info type_info,
MR_Array x, MR_Array y)
{
@@ -509,6 +558,30 @@
}
void
+mercury__builtin____Compare____tuple_0_0(MR_Type_Info ti,
+ MR_Comparison_Result *result, MR_Tuple x, MR_Tuple y)
+{
+ int i, arity;
+ MR_TypeInfo type_info;
+ MR_TypeInfo arg_type_info;
+
+ type_info = (MR_TypeInfo) ti;
+ arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ for (i = 0; i < arity; i++) {
+ /* type_infos are counted starting at one. */
+ arg_type_info =
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info)[i + 1];
+ mercury__builtin__compare_3_p_0((MR_Type_Info) arg_type_info,
+ result, x[i], y[i]);
+ if (*result != MR_COMPARE_EQUAL) {
+ return;
+ }
+ }
+ *result = MR_COMPARE_EQUAL;
+}
+
+void
mercury__array____Compare____array_1_0(
MR_Type_Info type_info, MR_Comparison_Result *result,
MR_Array x, MR_Array y)
@@ -621,6 +694,14 @@
}
static bool
+mercury__builtin__do_unify__tuple_0_0(MR_Type_Info type_info,
+ MR_Box x, MR_Box y)
+{
+ return mercury__builtin____Unify____tuple_0_0(
+ type_info, (MR_Tuple) x, (MR_Tuple) y);
+}
+
+static bool
mercury__array__do_unify__array_1_0(MR_Type_Info type_info, MR_Box x, MR_Box y)
{
return mercury__array____Unify____array_1_0(
@@ -739,6 +820,15 @@
MR_Box x, MR_Box y)
{
MR_fatal_error("called compare/3 for pred type");
+}
+
+static void
+mercury__builtin__do_compare__tuple_0_0(
+ MR_Type_Info type_info, MR_Comparison_Result *result,
+ MR_Box x, MR_Box y)
+{
+ mercury__builtin____Compare____tuple_0_0(
+ type_info, result, (MR_Tuple) x, (MR_Tuple) y);
}
static void
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.14
diff -u -u -r1.14 mercury.h
--- runtime/mercury.h 2000/07/20 10:39:36 1.14
+++ runtime/mercury.h 2000/07/22 23:54:19
@@ -123,6 +123,11 @@
#endif
/*
+** Tuples are always just arrays of polymorphic terms.
+*/
+typedef MR_Box *MR_Tuple;
+
+/*
** Typedefs used for the types of RTTI data structures.
** Many of these types are defined in mercury_type_info.h,
** but the ones which are used only by the MLDS back-end
@@ -140,12 +145,13 @@
/*
** XXX Currently we hard-code the declarations of the first
-** five of these type-info struct types; this imposes a fixed
+** ten of these type-info struct types; this imposes a fixed
** limit of 10 on the arity of types. (If this is exceeded,
** you'll get a parse error in the generated C code, due to
** an undeclared type.)
** Note that the code for compare and unify in runtime/mercury.c
-** also has a fixed limit of 5 on the arity of types.
+** also has a fixed limit of 5 on the arity of types (other than
+** higher-order and tuple types, which have no limit).
** Fortunately types with a high arity tend not to be used very
** often, so this is probably OK for now...
*/
@@ -209,6 +215,7 @@
mercury__builtin__builtin__type_ctor_info_c_pointer_0,
mercury__builtin__builtin__type_ctor_info_pred_0,
mercury__builtin__builtin__type_ctor_info_func_0,
+ mercury__builtin__builtin__type_ctor_info_tuple_0,
mercury__array__array__type_ctor_info_array_1,
mercury__std_util__std_util__type_ctor_info_univ_0,
mercury__std_util__std_util__type_ctor_info_type_desc_0,
@@ -233,6 +240,8 @@
mercury__builtin__builtin__type_ctor_info_character_0
#define mercury__builtin____type_ctor_info_pred_0 \
mercury__builtin__builtin__type_ctor_info_pred_0
+#define mercury__builtin____type_ctor_info_tuple_0 \
+ mercury__builtin__builtin__type_ctor_info_tuple_0
/*
** The compiler generates references to this constant.
@@ -369,6 +378,8 @@
MR_C_Pointer x, MR_C_Pointer y);
bool mercury__builtin____Unify____func_0_0(MR_Func x, MR_Func y);
bool mercury__builtin____Unify____pred_0_0(MR_Pred x, MR_Pred y);
+bool mercury__builtin____Unify____tuple_0_0(MR_Type_Info type_info,
+ MR_Tuple x, MR_Tuple y);
bool mercury__array____Unify____array_1_0(MR_Type_Info type_info,
MR_Array x, MR_Array y);
bool mercury__std_util____Unify____univ_0_0(MR_Univ x, MR_Univ y);
@@ -400,6 +411,8 @@
MR_Comparison_Result *result, MR_Func x, MR_Func y);
void mercury__builtin____Compare____pred_0_0(
MR_Comparison_Result *result, MR_Pred x, MR_Pred y);
+void mercury__builtin____Compare____tuple_0_0(MR_Type_Info type_info,
+ MR_Comparison_Result *result, MR_Tuple x, MR_Tuple y);
void mercury__array____Compare____array_1_0(MR_Type_Info type_info,
MR_Comparison_Result *result, MR_Array x, MR_Array y);
void mercury__std_util____Compare____univ_0_0(
Index: runtime/mercury_deep_copy_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_copy_body.h,v
retrieving revision 1.23
diff -u -u -r1.23 mercury_deep_copy_body.h
--- runtime/mercury_deep_copy_body.h 2000/05/17 18:48:53 1.23
+++ runtime/mercury_deep_copy_body.h 2000/07/24 06:39:05
@@ -444,6 +444,40 @@
}
break;
+ case MR_TYPECTOR_REP_TUPLE:
+ {
+ Word *data_value;
+ int arity, i;
+
+ assert(MR_tag(data) == 0);
+ data_value = (Word *) MR_body(data, MR_mktag(0));
+
+ if (in_range(data_value)) {
+ Word *new_data_ptr;
+ MR_TypeInfo *arg_typeinfo_vector;
+
+ arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ /* allocate space for the new tuple */
+ incr_saved_hp(new_data, arity);
+ new_data_ptr = (Word *) new_data;
+
+ arg_typeinfo_vector =
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info);
+ for (i = 0; i < arity; i++) {
+ /* type_infos are counted from one */
+ new_data_ptr[i] = copy(&data_value[i],
+ (const MR_TypeInfo) arg_typeinfo_vector[i + 1],
+ lower_limit, upper_limit);
+ }
+ leave_forwarding_pointer(data_ptr, new_data);
+ } else {
+ new_data = data;
+ found_forwarding_pointer(data);
+ }
+ }
+ break;
+
case MR_TYPECTOR_REP_UNIV:
{
Word *data_value;
@@ -644,21 +678,23 @@
return (MR_TypeInfo) type_ctor_info;
}
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
+ if (MR_type_ctor_rep_is_variable_arity(
+ type_ctor_info->type_ctor_rep))
+ {
arity = MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info);
type_info_args =
MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info);
incr_saved_hp(LVALUE_CAST(Word, new_type_info_arena),
MR_higher_order_type_info_size(arity));
MR_fill_in_higher_order_type_info(new_type_info_arena,
- type_ctor_info, arity, new_type_info_args);
+ type_ctor_info, arity, new_type_info_args);
} else {
arity = type_ctor_info->arity;
type_info_args = MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info);
incr_saved_hp(LVALUE_CAST(Word, new_type_info_arena),
MR_first_order_type_info_size(arity));
MR_fill_in_first_order_type_info(new_type_info_arena,
- type_ctor_info, new_type_info_args);
+ type_ctor_info, new_type_info_args);
}
for (i = 1; i <= arity; i++) {
new_type_info_args[i] = copy_type_info(&type_info_args[i],
Index: runtime/mercury_make_type_info_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_make_type_info_body.h,v
retrieving revision 1.4
diff -u -u -r1.4 mercury_make_type_info_body.h
--- runtime/mercury_make_type_info_body.h 2000/07/20 04:18:34 1.4
+++ runtime/mercury_make_type_info_body.h 2000/07/22 23:54:20
@@ -62,7 +62,8 @@
return MR_pseudo_type_info_is_ground(pseudo_type_info);
}
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
+ if (MR_type_ctor_rep_is_variable_arity(type_ctor_info->type_ctor_rep))
+ {
arity = MR_PSEUDO_TYPEINFO_GET_HIGHER_ORDER_ARITY(
pseudo_type_info);
start_region_size = 2;
Index: runtime/mercury_tabling.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.c,v
retrieving revision 1.26
diff -u -u -r1.26 mercury_tabling.c
--- runtime/mercury_tabling.c 2000/05/08 14:07:28 1.26
+++ runtime/mercury_tabling.c 2000/07/24 06:37:55
@@ -575,7 +575,8 @@
** sense. This is OK, because in that case it will never be used.
*/
- if (type_ctor_info->type_ctor_rep == MR_TYPECTOR_REP_PRED) {
+ if (MR_type_ctor_rep_is_variable_arity(type_ctor_info->type_ctor_rep))
+ {
arity = MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info);
arg_vector = MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(
type_info);
@@ -813,6 +814,25 @@
*/
MR_DEBUG_TABLE_INT(table, data);
#endif
+ break;
+ }
+
+ case MR_TYPECTOR_REP_TUPLE:
+ {
+ Word *data_value;
+ MR_TypeInfo *arg_type_info_vector;
+ int arity;
+ int i;
+
+ data_value = (Word *) data;
+ arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+ arg_type_info_vector =
+ MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info);
+ for (i = 0; i < arity; i++) {
+ /* type_infos are counted starting at one */
+ MR_DEBUG_TABLE_ANY(table, arg_type_info_vector[i + 1],
+ data_value[i]);
+ }
break;
}
Index: runtime/mercury_type_info.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_type_info.c,v
retrieving revision 1.38
diff -u -u -r1.38 mercury_type_info.c
--- runtime/mercury_type_info.c 2000/05/08 16:11:06 1.38
+++ runtime/mercury_type_info.c 2000/07/22 23:54:20
@@ -183,11 +183,12 @@
** If the type_ctor_info addresses are equal, we don't need to
** compare the arity of the types - they must be the same -
** unless they are higher-order (which are all mapped to
- ** pred/0).
+ ** pred/0) or tuples (which are all mapped to tuple/0).
** But we need to recursively compare the argument types, if any.
*/
- /* Check for higher order */
- if (type_ctor_info_1->type_ctor_rep == MR_TYPECTOR_REP_PRED)
+ /* Check for higher order or tuples */
+ if (MR_type_ctor_rep_is_variable_arity(
+ type_ctor_info_1->type_ctor_rep))
{
int num_arg_types_2;
Index: runtime/mercury_type_info.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_type_info.h,v
retrieving revision 1.52
diff -u -u -r1.52 mercury_type_info.h
--- runtime/mercury_type_info.h 2000/07/12 13:54:40 1.52
+++ runtime/mercury_type_info.h 2000/07/28 05:42:00
@@ -91,11 +91,12 @@
/*
** The C structures of typeinfos and pseudotypeinfos are sort of lies,
** for two reasons. First, we want one C type that can describe both first
-** order and higher order (pseudo-) typeinfos, and they have different
-** structures (higher order (pseudo-) typeinfos have an extra word, the arity,
-** between the type_ctor_info and the argument (pseudo-) typeinfos). Second,
-** we can't rely on the C compiler having a mechanism for the declaration
-** of dynamically sized vectors embedded in structures.
+** order, and higher order and tuple (pseudo-) typeinfos, and they have
+** different structures (higher order and tuple (pseudo-) typeinfos have
+** an extra word, the arity, between the type_ctor_info and the argument
+** (pseudo-) typeinfos). Second, we can't rely on the C compiler having a
+** mechanism for the declaration of dynamically sized vectors embedded in
+** structures.
**
** Instead, the types MR_TypeInfo and MR_PseudoTypeInfo are designed as
** error-detection devices. Values of these types should be manipulated
@@ -132,17 +133,22 @@
MR_TypeCtorInfo MR_ti_type_ctor_info; \
MR_TypeInfo MR_ti_first_order_arg_typeinfos[ARITY]; \
}
+
+/* Tuple types also use the higher-order type-info structure. */
#define MR_HIGHER_ORDER_TYPEINFO_STRUCT(NAME, ARITY) \
struct NAME { \
MR_TypeCtorInfo MR_ti_type_ctor_info; \
Integer MR_ti_higher_order_arity; \
MR_TypeInfo MR_ti_higher_order_arg_typeinfos[ARITY]; \
}
+
#define MR_FIRST_ORDER_PSEUDOTYPEINFO_STRUCT(NAME, ARITY) \
struct NAME { \
MR_TypeCtorInfo MR_pti_type_ctor_info; \
MR_PseudoTypeInfo MR_pti_first_order_arg_pseudo_typeinfos[ARITY]; \
}
+
+/* Tuple types also use the higher-order pseude-type-info structure. */
#define MR_HIGHER_ORDER_PSEUDOTYPEINFO_STRUCT(NAME, ARITY) \
struct NAME { \
MR_TypeCtorInfo MR_pti_type_ctor_info; \
@@ -223,15 +229,24 @@
#define MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info) \
((type_info)->MR_ti_higher_order_arity)
+#define MR_TYPEINFO_GET_TUPLE_ARITY(type_info) \
+ MR_TYPEINFO_GET_HIGHER_ORDER_ARITY(type_info)
+
#define MR_PSEUDO_TYPEINFO_GET_HIGHER_ORDER_ARITY(pseudo_type_info) \
((pseudo_type_info)->MR_pti_higher_order_arity)
+#define MR_PSEUDO_TYPEINFO_GET_TUPLE_ARITY(pseudo_type_info) \
+ MR_PSEUDO_TYPEINFO_GET_HIGHER_ORDER_ARITY(pseudo_type_info)
+
+#define MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info) \
+ ((MR_TypeInfoParams) &(type_info)->MR_ti_type_ctor_info)
+
#define MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info) \
((MR_TypeInfoParams) \
&(type_info)->MR_ti_higher_order_arity)
-#define MR_TYPEINFO_GET_FIRST_ORDER_ARG_VECTOR(type_info) \
- ((MR_TypeInfoParams) &(type_info)->MR_ti_type_ctor_info)
+#define MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(type_info) \
+ MR_TYPEINFO_GET_HIGHER_ORDER_ARG_VECTOR(type_info)
/*
** Macros for creating type_infos.
@@ -243,6 +258,9 @@
#define MR_higher_order_type_info_size(arity) \
(2 + (arity))
+#define MR_tuple_type_info_size(arity) \
+ MR_higher_order_type_info_size(arity)
+
#define MR_fill_in_first_order_type_info(arena, type_ctor_info, vector) \
do { \
MR_TypeInfo new_ti; \
@@ -260,6 +278,9 @@
(vector) = (MR_TypeInfoParams) &new_ti->MR_ti_higher_order_arity;\
} while (0)
+#define MR_fill_in_tuple_type_info(arena, type_ctor_info, arity, vector) \
+ MR_fill_in_higher_order_type_info(arena, type_ctor_info, arity, vector)
+
/*---------------------------------------------------------------------------*/
/*
@@ -397,6 +418,7 @@
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_FLOAT),
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_STRING),
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_PRED),
+ MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_TUPLE),
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_UNIV),
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_VOID),
MR_DEFINE_ENUM_CONST(MR_TYPECTOR_REP_C_POINTER),
@@ -441,6 +463,7 @@
"FLOAT", \
"STRING", \
"PRED", \
+ "TUPLE", \
"UNIV", \
"VOID", \
"C_POINTER", \
@@ -470,6 +493,16 @@
|| ((rep) == MR_TYPECTOR_REP_NOTAG_GROUND) \
|| ((rep) == MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ))
+/*
+** Returns TRUE if the type_ctor_info is used to represent
+** multiple types of different arities. The arity is stored
+** as the first element of the argument type-info vector.
+** This is true for higher-order types and tuple types.
+*/
+#define MR_type_ctor_rep_is_variable_arity(rep) \
+ ( ((rep) == MR_TYPECTOR_REP_PRED) \
+ || ((rep) == MR_TYPECTOR_REP_TUPLE))
+
/*---------------------------------------------------------------------------*/
/*
@@ -937,18 +970,24 @@
#ifdef MR_HIGHLEVEL_CODE
extern const struct MR_TypeCtorInfo_Struct
mercury__builtin__builtin__type_ctor_info_pred_0,
- mercury__builtin__builtin__type_ctor_info_func_0;
+ mercury__builtin__builtin__type_ctor_info_func_0,
+ mercury__builtin__builtin__type_ctor_info_tuple_0;
#define MR_TYPE_CTOR_INFO_HO_PRED \
(&mercury__builtin__builtin__type_ctor_info_pred_0)
#define MR_TYPE_CTOR_INFO_HO_FUNC \
(&mercury__builtin__builtin__type_ctor_info_func_0)
+ #define MR_TYPE_CTOR_INFO_TUPLE \
+ (&mercury__builtin__builtin__type_ctor_info_tuple_0)
#else
MR_DECLARE_TYPE_CTOR_INFO_STRUCT(mercury_data___type_ctor_info_pred_0);
MR_DECLARE_TYPE_CTOR_INFO_STRUCT(mercury_data___type_ctor_info_func_0);
+ MR_DECLARE_TYPE_CTOR_INFO_STRUCT(mercury_data___type_ctor_info_tuple_0);
#define MR_TYPE_CTOR_INFO_HO_PRED \
((MR_TypeCtorInfo) &mercury_data___type_ctor_info_pred_0)
#define MR_TYPE_CTOR_INFO_HO_FUNC \
((MR_TypeCtorInfo) &mercury_data___type_ctor_info_func_0)
+ #define MR_TYPE_CTOR_INFO_TUPLE \
+ ((MR_TypeCtorInfo) &mercury_data___type_ctor_info_tuple_0)
#endif
#define MR_TYPE_CTOR_INFO_IS_HO_PRED(T) \
@@ -957,6 +996,8 @@
(T == MR_TYPE_CTOR_INFO_HO_FUNC)
#define MR_TYPE_CTOR_INFO_IS_HO(T) \
(MR_TYPE_CTOR_INFO_IS_HO_FUNC(T) || MR_TYPE_CTOR_INFO_IS_HO_PRED(T))
+#define MR_TYPE_CTOR_INFO_IS_TUPLE(T) \
+ (T == MR_TYPE_CTOR_INFO_TUPLE)
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_unify_compare_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_unify_compare_body.h,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_unify_compare_body.h
--- runtime/mercury_unify_compare_body.h 2000/04/05 06:29:00 1.2
+++ runtime/mercury_unify_compare_body.h 2000/07/24 06:36:38
@@ -359,6 +359,42 @@
tailcall_user_pred();
+ case MR_TYPECTOR_REP_TUPLE:
+ {
+ int i;
+ int type_arity;
+ int result;
+
+ type_arity = MR_TYPEINFO_GET_TUPLE_ARITY(type_info);
+
+ for (i = 0; i < type_arity; i++) {
+ MR_TypeInfo arg_type_info;
+
+ /* type_infos are counted from one */
+ arg_type_info = MR_TYPEINFO_GET_TUPLE_ARG_VECTOR(
+ type_info)[i + 1];
+
+#ifdef select_compare_code
+ result = MR_generic_compare(arg_type_info,
+ ((Word *) x)[i], ((Word *) y)[i]);
+ if (result != MR_COMPARE_EQUAL) {
+ return_answer(result);
+ }
+#else
+ result = MR_generic_unify(arg_type_info,
+ ((Word *) x)[i], ((Word *) y)[i]);
+ if (! result) {
+ return_answer(FALSE);
+ }
+#endif
+ }
+#ifdef select_compare_code
+ return_answer(MR_COMPARE_EQUAL);
+#else
+ return_answer(TRUE);
+#endif
+ }
+
case MR_TYPECTOR_REP_ENUM:
case MR_TYPECTOR_REP_INT:
case MR_TYPECTOR_REP_CHAR:
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.87
diff -u -u -r1.87 Mmakefile
--- tests/hard_coded/Mmakefile 2000/06/05 02:47:36 1.87
+++ tests/hard_coded/Mmakefile 2000/07/26 05:08:06
@@ -107,6 +107,7 @@
term_io_test \
type_to_term_bug \
tim_qual1 \
+ tuple_test \
user_defined_equality \
write \
write_reg1
Index: tests/hard_coded/construct.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/construct.exp,v
retrieving revision 1.4
diff -u -u -r1.4 construct.exp
--- tests/hard_coded/construct.exp 2000/03/10 13:38:19 1.4
+++ tests/hard_coded/construct.exp 2000/07/31 05:25:24
@@ -158,6 +158,10 @@
-1 functors in this type
+1 functors in this type
+0 - {}/4
+
+
TESTING OTHER TYPES
1 functors in this type
@@ -220,3 +224,7 @@
Constructed: poly_two("goodbye")
About to construct poly_four/2
Constructed: poly_four(1, "goodbye")
+About to construct {}/3
+Constructed: {4, "five", '6'}
+About to call construct_tuple
+Constructed tuple: univ({[1, 2, 3], [one, two, three], 1, 2.10000000000000} : {list:list(int), list:list(construct:enum), int, float)})
Index: tests/hard_coded/construct.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/construct.m,v
retrieving revision 1.3
diff -u -u -r1.3 construct.m
--- tests/hard_coded/construct.m 2000/03/24 10:28:00 1.3
+++ tests/hard_coded/construct.m 2000/07/31 03:46:38
@@ -93,9 +93,16 @@
test_construct_2(type_of(poly_four(3, "hello")), "poly_one", 1, [One]),
test_construct_2(type_of(poly_four(3, "hello")), "poly_two", 1, [Bye]),
test_construct_2(type_of(poly_four(3, "hello")), "poly_four", 2,
- [One, Bye]).
+ [One, Bye]),
+ test_construct_2(type_of({1, "two", '3'}), "{}", 3,
+ [univ(4), univ("five"), univ('6')]),
+
+ io__write_string("About to call construct_tuple\n"),
+ { Tuple = construct_tuple([NumList, EnumList, One, TwoPointOne]) },
+ io__write_string("Constructed tuple: "),
+ io__write(Tuple),
+ io__nl.
-
:- pred test_construct_2(type_desc::in, string::in, int::in, list(univ)::in,
io__state::di, io__state::uo) is det.
test_construct_2(TypeInfo, FunctorName, Arity, Args) -->
@@ -247,6 +254,9 @@
% test predicates
test_all(newline), newline,
+
+ % test tuples
+ test_all({1, "a", 'a', {4, 'd'}}), newline,
newline.
Index: tests/hard_coded/deep_copy.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/deep_copy.exp,v
retrieving revision 1.2
diff -u -u -r1.2 deep_copy.exp
--- tests/hard_coded/deep_copy.exp 2000/03/10 13:38:19 1.2
+++ tests/hard_coded/deep_copy.exp 2000/07/31 03:50:39
@@ -90,6 +90,9 @@
univ(["hi! I\'m a univ!"] : list:list(string))
univ(["hi! I\'m a univ!"] : list:list(string))
univ(["hi! I\'m a univ!"] : list:list(string))
+{1, "two", '3', {4, '5', "6"}}
+{1, "two", '3', {4, '5', "6"}}
+{1, "two", '3', {4, '5', "6"}}
TESTING OTHER TYPES
var(1)
Index: tests/hard_coded/deep_copy.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/deep_copy.m,v
retrieving revision 1.2
diff -u -u -r1.2 deep_copy.m
--- tests/hard_coded/deep_copy.m 2000/03/10 13:38:20 1.2
+++ tests/hard_coded/deep_copy.m 2000/07/31 02:20:05
@@ -207,6 +207,9 @@
% XXX we don't deep copy predicates correctly yet
%test_all(newline),
+ % test tuples
+ test_all({1, "two", '3', {4, '5', "6"}}),
+
newline.
% Note: testing abstract types is always going to have results
Index: tests/hard_coded/expand.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/expand.exp,v
retrieving revision 1.3
diff -u -u -r1.3 expand.exp
--- tests/hard_coded/expand.exp 1998/12/04 01:11:12 1.3
+++ tests/hard_coded/expand.exp 2000/07/25 11:12:26
@@ -109,6 +109,10 @@
no arguments
expand: functor <<predicate>> arity 0 arguments []
+{}/4
+argument 4 of functor {} was:{1, 2, 3, 4}
+expand: functor {} arity 4 arguments [1, 'b', "third", {1, 2, 3, 4}]
+
TESTING OTHER TYPES
var/1
Index: tests/hard_coded/expand.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/expand.m,v
retrieving revision 1.5
diff -u -u -r1.5 expand.m
--- tests/hard_coded/expand.m 1997/06/04 09:59:57 1.5
+++ tests/hard_coded/expand.m 2000/07/24 23:11:54
@@ -142,6 +142,9 @@
% test predicates
test_all(newline), newline,
+ % test tuples
+ test_all({1, 'b', "third", {1,2,3,4}}), newline,
+
newline.
% Note: testing abstract types is always going to have results
Index: tests/hard_coded/tuple_test.exp
===================================================================
RCS file: tuple_test.exp
diff -N tuple_test.exp
--- /dev/null Tue Aug 1 14:05:00 2000
+++ tuple_test.exp Mon Jul 31 15:26:00 2000
@@ -0,0 +1,20 @@
+testing io__write:
+{'a', {'b', 1, [1, 2, 3], {}, { 1 }}, "string"}
+{'a', {'b', 1, [1, 2, 3], {}, { 1 }}, "string"}
+testing type_to_term:
+{a, {b, 1, [1, 2, 3], {}, { 1 }}, "string"}
+testing term_to_type:
+term_to_type succeeded
+{'a', {'b', 1, [1, 2, 3], {}, { 1 }}, "string"}
+testing unification:
+unify test 1 succeeded
+unify test 2 succeeded
+testing comparison:
+comparison test 1 succeeded
+comparison test 2 succeeded
+testing tuple switches:
+[1, 2]
+4
+testing complicated unification
+complicated unification test 1 succeeded
+complicated unification test 2 succeeded
Index: tests/hard_coded/tuple_test.m
===================================================================
RCS file: tuple_test.m
diff -N tuple_test.m
--- /dev/null Tue Aug 1 14:05:00 2000
+++ tuple_test.m Mon Jul 31 14:20:20 2000
@@ -0,0 +1,123 @@
+:- module tuple_test.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module bool, list, char, string, int.
+:- import_module term, std_util, term_io, varset.
+
+main -->
+ io__write_string("testing io__write:\n"),
+ { Tuple = {'a', {'b', 1, [1,2,3], {}, {1}}, "string"} },
+ io__write(Tuple),
+ io__nl,
+ io__write({}('a', {'b', 1, [1,2,3], {}, {1}}, "string")),
+ io__nl,
+
+ io__write_string("testing type_to_term:\n"),
+ { type_to_term(Tuple, TupleTerm) },
+ { is_generic_term(TupleTerm) },
+ { varset__init(VarSet) },
+ term_io__write_term(VarSet, TupleTerm),
+ io__nl,
+
+ io__write_string("testing term_to_type:\n"),
+ (
+ { has_type(NewTuple, type_of(Tuple)) },
+ { term_to_type(TupleTerm, NewTuple) }
+ ->
+ io__write_string("term_to_type succeeded\n"),
+ io__write(NewTuple),
+ io__nl
+ ;
+ io__write_string("term_to_type failed\n")
+ ),
+
+ % Test in-in unification of tuples.
+ io__write_string("testing unification:\n"),
+ ( { unify_tuple({1, 'a', 1, "string"}, {1, 'a', 1, "string"}) } ->
+ io__write_string("unify test 1 succeeded\n")
+ ;
+ io__write_string("unify test 1 failed\n")
+ ),
+ ( { unify_tuple({2, 'b', 1, "foo"}, {2, 'b', 1, "bar"}) } ->
+ io__write_string("unify test 2 failed\n")
+ ;
+ io__write_string("unify test 2 succeeded\n")
+ ),
+
+ % Test comparison of tuples.
+ io__write_string("testing comparison:\n"),
+ { compare(Res1, {1, 'a', 1, "string"}, {1, 'a', 1, "string"}) },
+ ( { Res1 = (=) } ->
+ io__write_string("comparison test 1 succeeded\n")
+ ;
+ io__write_string("comparison test 1 failed\n")
+ ),
+
+ { compare(Res2, {2, 'b', 1, "foo"}, {2, 'b', 1, "bar"}) },
+ ( { Res2 = (>) } ->
+ io__write_string("comparison test 2 succeeded\n")
+ ;
+ io__write_string("comparison test 2 failed\n")
+ ),
+
+ io__write_string("testing tuple switches:\n"),
+ { solutions(tuple_switch_test({1, 2}), Solns1) },
+ io__write(Solns1),
+ io__nl,
+
+ { tuple_switch_test_2({no, 3, 4}, Int) },
+ io__write_int(Int),
+ io__nl,
+
+ %
+ % These tests should generate an out-of-line unification
+ % predicate for the unification with the output argument.
+ %
+ io__write_string("testing complicated unification\n"),
+ ( { choose(yes, {1, "b", 'c'}, {4, "e", 'f'}, {1, _, _}) } ->
+ io__write_string("complicated unification test 1 succeeded\n")
+ ;
+ io__write_string("complicated unification test 1 failed\n")
+ ),
+ ( { choose(yes, {5, "b", 'c'}, {9, "e", 'f'}, {1, _, _}) } ->
+ io__write_string("complicated unification test 2 failed\n")
+ ;
+ io__write_string("complicated unification test 2 succeeded\n")
+ ).
+
+:- pred is_generic_term(term::unused).
+
+is_generic_term(_).
+
+:- type foo(A, B, C) == {int, A, B, C}.
+
+:- pred unify_tuple(foo(A, B, C)::in,
+ {int, A, B, C}::in(bound({ground, ground, ground, ground}))) is semidet.
+:- pragma no_inline(unify_tuple/2).
+
+unify_tuple(X, X).
+
+:- pred choose(bool::in, T::in, T::in, T::out) is det.
+:- pragma no_inline(choose/4).
+
+choose(yes, A, _, A).
+choose(no, _, B, B).
+
+:- pred tuple_switch_test({int, int}::in, int::out) is multi.
+:- pragma no_inline(tuple_switch_test/2).
+
+tuple_switch_test({A, _}, A).
+tuple_switch_test({_, B}, B).
+
+:- pred tuple_switch_test_2({bool, int, int}::in, int::out) is det.
+:- pragma no_inline(tuple_switch_test_2/2).
+
+tuple_switch_test_2({yes, A, _}, A).
+tuple_switch_test_2({no, _, B}, B).
Index: tests/hard_coded/write.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/write.m,v
retrieving revision 1.5
diff -u -u -r1.5 write.m
--- tests/hard_coded/write.m 1998/11/09 02:44:03 1.5
+++ tests/hard_coded/write.m 2000/08/01 04:11:41
@@ -58,10 +58,10 @@
test_ops -->
io__write(var("X") + int(3) * var("X^2") ; (type)), newline,
- io__write({type}), newline,
- io__write({:-}), newline,
+ io__write(write:{type}), newline,
+ io__write(write:{:-}), newline,
io__write((:-)), newline,
- io__write({blah}), newline,
+ io__write(write:{blah}), newline,
io__write((blah ; (type), (type) * blah ; (type))), newline,
io__write(((blah ; blah), blah) * blah ; blah), newline,
io__write((type) * blah ; (type)), newline.
Index: tests/hard_coded/typeclasses/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/Mmakefile,v
retrieving revision 1.30
diff -u -u -r1.30 Mmakefile
--- tests/hard_coded/typeclasses/Mmakefile 2000/07/06 06:25:24 1.30
+++ tests/hard_coded/typeclasses/Mmakefile 2000/07/31 04:22:37
@@ -38,6 +38,7 @@
record_syntax \
superclass_call \
test_default_func_mode \
+ tuple_instance \
typeclass_exist_method \
typeclass_test_5 \
typeclass_test_6 \
Index: tests/hard_coded/typeclasses/tuple_instance.exp
===================================================================
RCS file: tuple_instance.exp
diff -N tuple_instance.exp
--- /dev/null Tue Aug 1 14:05:00 2000
+++ tuple_instance.exp Mon Jul 31 15:27:57 2000
@@ -0,0 +1 @@
+9
Index: tests/hard_coded/typeclasses/tuple_instance.m
===================================================================
RCS file: tuple_instance.m
diff -N tuple_instance.m
--- /dev/null Tue Aug 1 14:05:00 2000
+++ tuple_instance.m Wed Jul 26 15:08:40 2000
@@ -0,0 +1,32 @@
+:- module tuple_instance.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module int, string.
+
+main -->
+ { Size = size({"ok", "failed"}) },
+ io__write_int(Size),
+ io__nl.
+
+:- typeclass size(T) where [
+ func size(T) = int
+].
+
+:- instance size({T, U}) <= (size(T), size(U)) where [
+ func(size/1) is tuple_size
+].
+
+:- instance size(string) where [
+ func(size/1) is string__length
+].
+
+:- func tuple_size({T, U}) = int <= (size(T), size(U)).
+
+tuple_size({T, U}) = 1 + size(T) + size(U).
Index: tests/invalid/errors2.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors2.err_exp,v
retrieving revision 1.9
diff -u -u -r1.9 errors2.err_exp
--- tests/invalid/errors2.err_exp 1999/11/09 22:40:12 1.9
+++ tests/invalid/errors2.err_exp 2000/07/28 00:53:38
@@ -54,6 +54,11 @@
errors2.m:078: error: undefined symbol `[]/0'.
errors2.m:078: In clause for predicate `errors2:type_error_8/0':
errors2.m:078: error: undefined predicate `from_char_list/2'.
+errors2.m:085: In clause for predicate `errors2:type_error_9/0':
+errors2.m:085: type error in unification of variable `X'
+errors2.m:085: and variable `Y'.
+errors2.m:085: `X' has type `{int, string, character}',
+errors2.m:085: `Y' has type `{string, character, int}'.
errors2.m:009: Inferred :- pred bind_type_param(int).
errors2.m:019: In clause for `unresolved_polymorphism':
errors2.m:019: in argument 1 of call to predicate `errors2:bind_type_param/2':
Index: tests/invalid/errors2.err_exp2
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors2.err_exp2,v
retrieving revision 1.4
diff -u -u -r1.4 errors2.err_exp2
--- tests/invalid/errors2.err_exp2 1999/11/09 22:40:14 1.4
+++ tests/invalid/errors2.err_exp2 2000/07/28 00:52:14
@@ -54,5 +54,10 @@
errors2.m:078: error: undefined symbol `[]/0'.
errors2.m:078: In clause for predicate `errors2:type_error_8/0':
errors2.m:078: error: undefined predicate `from_char_list/2'.
+errors2.m:085: In clause for predicate `errors2:type_error_9/0':
+errors2.m:085: type error in unification of variable `X'
+errors2.m:085: and variable `Y'.
+errors2.m:085: `X' has type `{int, string, character}',
+errors2.m:085: `Y' has type `{string, character, int}'.
errors2.m:009: Inferred :- pred bind_type_param(int).
For more information, try recompiling with `-E'.
Index: tests/invalid/errors2.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors2.m,v
retrieving revision 1.4
diff -u -u -r1.4 errors2.m
--- tests/invalid/errors2.m 1997/06/29 23:24:38 1.4
+++ tests/invalid/errors2.m 2000/07/28 00:51:55
@@ -78,4 +78,10 @@
from_char_list([], Str),
string__from_char_list(list:[], Str).
+:- pred type_error_9.
+type_error_9 :-
+ X = {1, "2", '3'},
+ Y = {"1", '2', 3},
+ X = Y.
+
%-----------------------------------------------------------------------------%
Index: tests/tabling/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/tabling/Mmakefile,v
retrieving revision 1.12
diff -u -u -r1.12 Mmakefile
--- tests/tabling/Mmakefile 2000/04/05 06:11:35 1.12
+++ tests/tabling/Mmakefile 2000/07/25 12:10:51
@@ -12,6 +12,7 @@
expand \
expand_float \
expand_poly \
+ expand_tuple \
fib \
fib_float \
fib_list \
Index: util/mdemangle.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mdemangle.c,v
retrieving revision 1.36
diff -u -u -r1.36 mdemangle.c
--- util/mdemangle.c 1999/09/30 21:33:14 1.36
+++ util/mdemangle.c 2000/07/26 04:59:25
@@ -908,7 +908,8 @@
{ "f_slash", "/" },
{ "f_comma", "," },
{ "f_semicolon", ";" },
- { "f_cut", "!" }
+ { "f_cut", "!" },
+ { "f_tuple", "{}" }
};
const int num_translations =
sizeof(translations) / sizeof(translations[0]);
Index: w3/news/newsdb.inc
===================================================================
RCS file: /home/mercury1/repository/w3/news/newsdb.inc,v
retrieving revision 1.47
diff -u -u -r1.47 newsdb.inc
--- w3/news/newsdb.inc 2000/07/26 06:27:36 1.47
+++ w3/news/newsdb.inc 2000/07/31 05:39:50
@@ -21,6 +21,14 @@
$newsdb = array(
+"1 August 2000" => array("Tuple types",
+
+"Mercury now has builtin tuple types, similar to those in
+most other functional languages. The latest
+<A HREF=\"download/rotd.html\">release of the day</A>
+contains tuple support."
+),
+
"26 Jul 2000" => array("Mercury and Microsoft's .NET",
"A page outlining the status of Mercury on Microsoft's net .NET
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list