%--------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %--------------------------------------------------% % Copyright (C) 2002-2009, 2011 The University of Melbourne. % Copyright (C) 2014-2022 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % % File: construct.m. % Main author: zs. % Stability: low. % %--------------------------------------------------% %--------------------------------------------------% :- module construct. :- interface. :- import_module list. :- import_module maybe. :- import_module univ. :- import_module type_desc. %--------------------------------------------------% % The functors of a discriminated union type are numbered from % zero to N-1, where N is the value returned by num_functors. % The functors are numbered in lexicographic order. If two % functors have the same name, the one with the lower arity % will have the lower number. % :- type functor_number_ordinal == int. :- type functor_number_lex == int. % num_functors(Type) = NumFunctors. % num_functors(Type, NumFunctors). % % Returns the number of different functors for the top-level % type constructor of the type specified by Type. % Fails if the type is not a discriminated union type. % % deconstruct.functor_number/3, deconstruct.deconstruct_du/5 % and the semidet predicates and functions in this module will % only succeed for types for which num_functors/1 succeeds. % :- func num_functors(type_desc) = int is semidet. :- pred num_functors(type_desc::in, int::out) is semidet. :- func det_num_functors(type_desc) = int. % get_functor(Type, FunctorNumber, FunctorName, Arity, ArgTypes). % % Binds FunctorName and Arity to the name and arity of functor number % FunctorNumber for the specified type, and binds ArgTypes to the % type_descs for the types of the arguments of that functor. % Fails if the type is not a discriminated union type, or if % FunctorNumber is out of range. % :- pred get_functor(type_desc::in, functor_number_lex::in, string::out, int::out, list(pseudo_type_desc)::out) is semidet. % get_functor_with_names(Type, FunctorNumber, FunctorName, Arity, ArgTypes, % ArgNames). % % Binds FunctorName and Arity to the name and arity of functor number % FunctorNumber for the specified type, ArgTypes to the type_descs % for the types of the arguments of that functor, and ArgNames to the % field name of each functor argument, if any. Fails if the type is % not a discriminated union type, or if FunctorNumber is out of range. % :- pred get_functor_with_names(type_desc::in, functor_number_lex::in, string::out, int::out, list(pseudo_type_desc)::out, list(maybe(string))::out) is semidet. % get_functor_ordinal(Type, I) = Ordinal. % get_functor_ordinal(Type, I, Ordinal). % % Returns Ordinal, where Ordinal is the position in declaration order % for the specified type of the function symbol that is in position I % in lexicographic order. Fails if the type is not a discriminated % union type, or if I is out of range. % :- func get_functor_ordinal(type_desc, functor_number_lex) = functor_number_ordinal is semidet. :- pred get_functor_ordinal(type_desc::in, functor_number_lex::in, functor_number_ordinal::out) is semidet. % get_functor_lex(Type, Ordinal) = I. % get_functor_lex(Type, Ordinal, I). % % Returns I, where I is the position in lexicographic order for the % specified type of the function symbol that is in position Ordinal % in declaration order. Fails if the type is not a discriminated % union type, or if Ordinal is out of range. % :- func get_functor_lex(type_desc, functor_number_ordinal) = functor_number_lex is semidet. :- pred get_functor_lex(type_desc::in, functor_number_ordinal::in, functor_number_lex::out) is semidet. % find_functor(Type, FunctorName, Arity, FunctorNumber, ArgTypes). % % Given a type descriptor, a functor name and arity, finds the functor % number and the types of its arguments. It thus serves as the converse % to get_functor/5. % :- pred find_functor(type_desc::in, string::in, int::in, functor_number_lex::out, list(type_desc)::out) is semidet. % construct(Type, I, Args) = Term. % construct(Type, I, Args, Term). % % Returns a term of the type specified by Type whose functor % is functor number I of the type given by Type, and whose % arguments are given by Args. Fails if the type is not a % discriminated union type, or if I is out of range, or if the % number of arguments supplied doesn't match the arity of the selected % functor, or if the types of the arguments do not match % the expected argument types of that functor. % :- func construct(type_desc, functor_number_lex, list(univ)) = univ is semidet. :- pred construct(type_desc::in, functor_number_lex::in, list(univ)::in, univ::out) is semidet. % construct_tuple(Args) = Term. % % Returns a tuple whose arguments are given by Args. % :- func construct_tuple(list(univ)) = univ. %--------------------------------------------------% %--------------------------------------------------%