%--------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%--------------------------------------------------%
% Copyright (C) 2015-2018 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%--------------------------------------------------%
%
% File: term_conversion.m.
% Stability: medium.
%
% This file provides predicates to convert values of arbitrary types to terms,
% and vice versa.
%
%--------------------------------------------------%
%--------------------------------------------------%
:- module term_conversion.
:- interface.
:- import_module list.
:- import_module term.
:- import_module type_desc.
:- import_module univ.
%--------------------------------------------------%
%
% Types that record the results of term to type conversions.
%
:- type term_to_type_result(T, U)
---> ok(T)
; error(term_to_type_error(U)).
:- type term_to_type_result(T) == term_to_type_result(T, generic).
:- type term_to_type_error(T)
---> type_error(
term(T),
type_desc.type_desc,
context,
term_to_type_context
)
; mode_error(
var(T),
term_to_type_context
).
:- type term_to_type_context == list(term_to_type_arg_context).
:- type term_to_type_arg_context
---> arg_context(
const, % functor
int, % argument number (starting from 1)
context % filename & line number
).
%--------------------------------------------------%
%
% The following predicates can convert values of (almost) any type
% to the type `term' and back again.
%
% try_term_to_type(Term, Result):
%
% Try to convert the given term to a ground value of type T.
% If successful, return `ok(X)' where X is the converted value.
% If Term is not ground, return `mode_error(Var, Context)',
% where Var is a variable occurring in Term.
% If Term is not a valid term of the specified type, return
% `type_error(SubTerm, ExpectedType, Context, ArgContexts)',
% where SubTerm is a sub-term of Term and ExpectedType is the type
% expected for that part of Term.
% Context specifies the file and line number where the
% offending part of the term was read in from, if available.
% ArgContexts specifies the path from the root of the term
% to the offending subterm.
%
:- func try_term_to_type(term(U)) = term_to_type_result(T, U).
:- pred try_term_to_type(term(U)::in, term_to_type_result(T, U)::out) is det.
% term_to_type(Term, Type) :- try_term_to_type(Term, ok(Type)).
%
:- pred term_to_type(term(U)::in, T::out) is semidet.
% Like term_to_type, but calls error/1 rather than failing.
%
:- func det_term_to_type(term(_)) = T.
:- pred det_term_to_type(term(_)::in, T::out) is det.
% Converts a value to a term representation of that value.
%
:- func type_to_term(T) = term(_).
:- pred type_to_term(T::in, term(_)::out) is det.
% Convert the value stored in the univ (as distinct from the univ itself)
% to a term.
%
:- func univ_to_term(univ) = term(_).
:- pred univ_to_term(univ::in, term(_)::out) is det.
%--------------------------------------------------%
%--------------------------------------------------%