mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
compiler/error_spec.m:
This new module contains the part of the old error_util.m that defines
the error_spec type, and some functions that can help construct pieces
of error_specs. Most modules of the compiler that deal with errors
will need to import only this part of the old error_util.m.
This change also renames the format_component type to format_piece,
which matches our long-standing naming convention for variables containing
(lists of) values of this type.
compiler/write_error_spec.m:
This new module contains the part of the old error_util.m that
writes out error specs, and converts them to strings.
This diff marks as obsolete the versions of predicates that
write out error specs to the current output stream, without
*explicitly* specifying the intended stream.
compiler/error_sort.m:
This new module contains the part of the old error_util.m that
sorts lists of error specs and error msgs.
compiler/error_type_util.m:
This new module contains the part of the old error_util.m that
convert types to format_pieces that generate readable output.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Include and document the new modules.
compiler/error_util.m:
The code remaining in the original error_util.m consists of
general utility predicates and functions that don't fit into
any of the modules above.
Delete an unneeded pair of I/O states from the argument list
of a predicate.
compiler/file_util.m:
Move the unable_to_open_file predicate here from error_util.m,
since it belongs here. Mark another predicate that writes
to the current output stream as obsolete.
compiler/hlds_error_util.m:
Mark two predicates that wrote out error_spec to the current output
stream as obsolete, and add versions that take an explicit output stream.
compiler/Mercury.options:
Compile the modules that call the newly obsoleted predicates
with --no-warn-obsolete, for the time being.
compiler/*.m:
Conform to the changes above, mostly by updating import_module
declarations, and renaming format_component to format_piece.
528 lines
21 KiB
Mathematica
528 lines
21 KiB
Mathematica
%-----------------------------------------------------------------------------e
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------e
|
|
% Copyright (C) 2008-2009, 2011-2012 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Many of the predicates below exist in two or three forms.
|
|
%
|
|
% - The first form, whose name is of the form parse_<something>, always
|
|
% succeeds; if it doesn't find the thing it is looking for, it returns
|
|
% an error message.
|
|
% - The second form, whose name is of the form try_parse_<something>, exists
|
|
% because building this error message is a waste of time if not finding
|
|
% <something> is not in fact an error, which happens often. This second form
|
|
% simply fails when it does not find <something>.
|
|
% - The third form exists in cases where our caller imposes further
|
|
% restrictions on the form of the thing being looked for, such as a list
|
|
% of arguments being empty.
|
|
%
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
:- module parse_tree.parse_sym_name.
|
|
:- interface.
|
|
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.maybe_error.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module cord.
|
|
:- import_module list.
|
|
:- import_module term.
|
|
:- import_module varset.
|
|
|
|
:- type maybe_functor == maybe_functor(generic).
|
|
:- type maybe_functor(T) == maybe2(sym_name, list(term(T))).
|
|
|
|
% A SymNameAndArgs is one of
|
|
% Name(Args)
|
|
% Module.Name(Args)
|
|
% (or if Args is empty, one of
|
|
% Name
|
|
% Module.Name)
|
|
% where Module is a SymName. For backwards compatibility, we allow `__'
|
|
% as an alternative to `.'.
|
|
|
|
% parse_sym_name_and_args(VarSet, ContextPieces, Term, Result):
|
|
%
|
|
% Parse Term into a sym_name that is its top function symbol and a
|
|
% list of its argument terms, and if successful return them in Result.
|
|
% However, in case it does not succeed, parse_sym_name_and_args
|
|
% also takes as input Varset (from which the variables in Term are taken),
|
|
% and a format_piece list describing the context from which it was
|
|
% called, e.g. "In clause head:".
|
|
%
|
|
% Note: parse_sym_name_and_args is intended for places where a symbol
|
|
% is _used_, where no default module name exists for the sym_name.
|
|
% For places where a symbol is _defined_, use the related predicate
|
|
% parse_implicitly_qualified_sym_name_and_args.
|
|
%
|
|
:- pred parse_sym_name_and_args(varset::in, cord(format_piece)::in,
|
|
term(T)::in, maybe_functor(T)::out) is det.
|
|
:- pred try_parse_sym_name_and_args(term(T)::in,
|
|
sym_name::out, list(term(T))::out) is semidet.
|
|
|
|
% When given the first two arguments Functor and FunctorArgs,
|
|
% try_parse_sym_name_and_args_from_f_args will do exactly the same as
|
|
% what try_parse_sym_name_and_args would do when given the term
|
|
% term.functor(Functor, FunctorArgs, _), but it does so without
|
|
% requiring its caller to construct that term.
|
|
%
|
|
:- pred try_parse_sym_name_and_args_from_f_args(const::in, list(term(T))::in,
|
|
sym_name::out, list(term(T))::out) is semidet.
|
|
|
|
% Versions of parse_sym_name_and_args and try_parse_sym_name_and_args
|
|
% that require the given term to have no arguments.
|
|
%
|
|
:- pred parse_sym_name_and_no_args(varset::in, cord(format_piece)::in,
|
|
term(T)::in, maybe1(sym_name)::out) is det.
|
|
:- pred try_parse_sym_name_and_no_args(term(T)::in, sym_name::out) is semidet.
|
|
|
|
% parse_implicitly_qualified_sym_name_and_args(DefaultModuleName,
|
|
% VarSet, ContextPieces, Term, Result):
|
|
%
|
|
% Parse Term into a sym_name that is its top function symbol and a
|
|
% list of its argument terms, and if successful return them in Result.
|
|
% This predicate thus does almost the same job as the predicate
|
|
% parse_sym_name_and_args above, the difference being that
|
|
% if the sym_name is qualified, then we check whether it is qualified
|
|
% with (possibly a part of) DefaultModuleName, and if it isn't qualified,
|
|
% then we qualify it with DefaultModuleName . This is the right thing
|
|
% to do for clause heads, which is the intended job of
|
|
% parse_implicitly_qualified_sym_name_and_args.
|
|
%
|
|
:- pred parse_implicitly_qualified_sym_name_and_args(module_name::in,
|
|
varset::in, cord(format_piece)::in, term(T)::in,
|
|
maybe_functor(T)::out) is det.
|
|
:- pred parse_implicitly_qualified_sym_name_and_no_args(module_name::in,
|
|
varset::in, cord(format_piece)::in, term(T)::in,
|
|
maybe1(sym_name)::out) is det.
|
|
|
|
% These predicates do just the "implicitly qualifying" part of the
|
|
% job of the predicates above.
|
|
%
|
|
:- pred implicitly_qualify_sym_name(module_name::in, term(T)::in,
|
|
sym_name::in, maybe1(sym_name)::out) is det.
|
|
:- pred try_to_implicitly_qualify_sym_name(module_name::in,
|
|
sym_name::in, sym_name::out) is semidet.
|
|
|
|
% A SymbolName is one of
|
|
% Name
|
|
% Matches symbols with the specified name in the
|
|
% current namespace.
|
|
% Module.Name
|
|
% Matches symbols with the specified name exported
|
|
% by the specified module (where Module is itself a SymbolName).
|
|
%
|
|
% We also allow the syntax `Module__Name' as an alternative
|
|
% for `Module.Name'.
|
|
%
|
|
:- pred parse_symbol_name(varset(T)::in, term(T)::in, maybe1(sym_name)::out)
|
|
is det.
|
|
:- pred try_parse_symbol_name(term(T)::in, sym_name::out) is semidet.
|
|
|
|
:- pred parse_implicitly_qualified_symbol_name(module_name::in, varset::in,
|
|
term::in, maybe1(sym_name)::out) is det.
|
|
|
|
:- type sym_name_specifier
|
|
---> sym_name_specifier_name(sym_name)
|
|
; sym_name_specifier_name_arity(sym_name, user_arity).
|
|
|
|
% A SymbolNameSpecifier is one of
|
|
% SymbolName
|
|
% SymbolName/Arity
|
|
% Matches only symbols of the specified arity.
|
|
%
|
|
:- pred parse_symbol_name_specifier(varset::in, term::in,
|
|
maybe1(sym_name_specifier)::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
:- implementation.
|
|
|
|
:- import_module parse_tree.parse_tree_out_term.
|
|
|
|
:- import_module int.
|
|
:- import_module term_int.
|
|
|
|
parse_sym_name_and_args(VarSet, ContextPieces, Term, MaybeSymNameAndArgs) :-
|
|
( if
|
|
Term = term.functor(Functor, FunctorArgs, TermContext),
|
|
Functor = term.atom("."),
|
|
FunctorArgs = [ModuleTerm, NameArgsTerm]
|
|
then
|
|
( if NameArgsTerm = term.functor(term.atom(Name), Args, _) then
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
parse_symbol_name(GenericVarSet, ModuleTerm, MaybeModule),
|
|
(
|
|
MaybeModule = ok1(Module),
|
|
MaybeSymNameAndArgs = ok2(qualified(Module, Name), Args)
|
|
;
|
|
MaybeModule = error1(_),
|
|
ModuleTermStr = describe_error_term(GenericVarSet, ModuleTerm),
|
|
Pieces = cord.list(ContextPieces) ++
|
|
[lower_case_next_if_not_first,
|
|
words("Error: expected module name before '.'"),
|
|
words("in qualified symbol name, got"),
|
|
words(ModuleTermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
MaybeSymNameAndArgs = error2([Spec])
|
|
)
|
|
else
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
TermStr = describe_error_term(GenericVarSet, Term),
|
|
Pieces = cord.list(ContextPieces) ++ [lower_case_next_if_not_first,
|
|
words("Error: expected identifier after '.'"),
|
|
words("in qualified symbol name, got"),
|
|
words(TermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
MaybeSymNameAndArgs = error2([Spec])
|
|
)
|
|
else
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
( if Term = term.functor(term.atom(Name), Args, _) then
|
|
SymName = string_to_sym_name_sep(Name, "__"),
|
|
MaybeSymNameAndArgs = ok2(SymName, Args)
|
|
else
|
|
TermStr = describe_error_term(GenericVarSet, Term),
|
|
Pieces = cord.list(ContextPieces) ++ [lower_case_next_if_not_first,
|
|
words("Error: expected a symbol name, got"),
|
|
quote(TermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymNameAndArgs = error2([Spec])
|
|
)
|
|
).
|
|
|
|
try_parse_sym_name_and_args(Term, SymName, Args) :-
|
|
Term = term.functor(Functor, FunctorArgs, _TermContext),
|
|
try_parse_sym_name_and_args_from_f_args(Functor, FunctorArgs,
|
|
SymName, Args).
|
|
|
|
:- pragma inline(pred(try_parse_sym_name_and_args_from_f_args/4)).
|
|
|
|
try_parse_sym_name_and_args_from_f_args(Functor, FunctorArgs, SymName, Args) :-
|
|
Functor = term.atom(FunctorName),
|
|
( if
|
|
FunctorName = ".",
|
|
FunctorArgs = [ModuleTerm, NameArgsTerm]
|
|
then
|
|
NameArgsTerm = term.functor(term.atom(Name), Args, _),
|
|
try_parse_symbol_name(ModuleTerm, Module),
|
|
SymName = qualified(Module, Name)
|
|
else
|
|
SymName = string_to_sym_name_sep(FunctorName, "__"),
|
|
Args = FunctorArgs
|
|
).
|
|
|
|
parse_sym_name_and_no_args(VarSet, ContextPieces, Term, MaybeSymName) :-
|
|
( if
|
|
Term = term.functor(Functor, FunctorArgs, TermContext),
|
|
Functor = term.atom("."),
|
|
FunctorArgs = [ModuleTerm, NameArgsTerm]
|
|
then
|
|
( if NameArgsTerm = term.functor(term.atom(Name), Args, _) then
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
parse_symbol_name(GenericVarSet, ModuleTerm, MaybeModule),
|
|
(
|
|
MaybeModule = ok1(Module),
|
|
SymName = qualified(Module, Name),
|
|
insist_on_no_args(ContextPieces, NameArgsTerm, SymName,
|
|
Args, MaybeSymName)
|
|
;
|
|
MaybeModule = error1(_),
|
|
ModuleTermStr = describe_error_term(GenericVarSet, ModuleTerm),
|
|
Pieces = cord.list(ContextPieces) ++
|
|
[lower_case_next_if_not_first,
|
|
words("Error: expected module name expected before '.'"),
|
|
words("in qualified symbol name, got"),
|
|
words(ModuleTermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
else
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
TermStr = describe_error_term(GenericVarSet, Term),
|
|
Pieces = cord.list(ContextPieces) ++ [lower_case_next_if_not_first,
|
|
words("Error: expected identifier after '.'"),
|
|
words("in qualified symbol name, got"),
|
|
words(TermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
else
|
|
varset.coerce(VarSet, GenericVarSet),
|
|
( if Term = term.functor(term.atom(Name), Args, _) then
|
|
SymName = string_to_sym_name_sep(Name, "__"),
|
|
insist_on_no_args(ContextPieces, Term, SymName, Args, MaybeSymName)
|
|
else
|
|
TermStr = describe_error_term(GenericVarSet, Term),
|
|
Pieces = cord.list(ContextPieces) ++ [lower_case_next_if_not_first,
|
|
words("Error: atom expected at"),
|
|
words(TermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
).
|
|
|
|
:- pred insist_on_no_args(cord(format_piece)::in, term(T)::in,
|
|
sym_name::in, list(term(T))::in, maybe1(sym_name)::out) is det.
|
|
|
|
insist_on_no_args(ContextPieces, Term, SymName, Args, MaybeSymName) :-
|
|
(
|
|
Args = [],
|
|
MaybeSymName = ok1(SymName)
|
|
;
|
|
Args = [_ | _],
|
|
Name = sym_name_to_string(SymName),
|
|
Pieces = cord.list(ContextPieces) ++
|
|
[lower_case_next_if_not_first,
|
|
words("Error:"), quote(Name), words("has arguments,"),
|
|
words("expected none."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
).
|
|
|
|
try_parse_sym_name_and_no_args(Term, SymName) :-
|
|
Term = term.functor(Functor, FunctorArgs, _TermContext),
|
|
Functor = term.atom(FunctorName),
|
|
( if
|
|
FunctorName = ".",
|
|
FunctorArgs = [ModuleTerm, NameArgsTerm]
|
|
then
|
|
NameArgsTerm = term.functor(term.atom(Name), [], _),
|
|
try_parse_symbol_name(ModuleTerm, Module),
|
|
SymName = qualified(Module, Name)
|
|
else
|
|
FunctorArgs = [],
|
|
SymName = string_to_sym_name_sep(FunctorName, "__")
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
parse_implicitly_qualified_sym_name_and_args(DefaultModuleName, VarSet,
|
|
ContextPieces, Term, MaybeSymNameAndArgs) :-
|
|
parse_sym_name_and_args(VarSet, ContextPieces, Term, MaybeSymNameAndArgs0),
|
|
(
|
|
MaybeSymNameAndArgs0 = ok2(SymName0, Args),
|
|
implicitly_qualify_sym_name_and_args(DefaultModuleName, Term,
|
|
SymName0, Args, MaybeSymNameAndArgs)
|
|
;
|
|
MaybeSymNameAndArgs0 = error2(_),
|
|
MaybeSymNameAndArgs = MaybeSymNameAndArgs0
|
|
).
|
|
|
|
parse_implicitly_qualified_sym_name_and_no_args(DefaultModuleName, VarSet,
|
|
ContextPieces, Term, MaybeSymName) :-
|
|
parse_sym_name_and_args(VarSet, ContextPieces, Term, MaybeSymNameAndArgs0),
|
|
(
|
|
MaybeSymNameAndArgs0 = ok2(SymName0, Args0),
|
|
implicitly_qualify_sym_name(DefaultModuleName, Term,
|
|
SymName0, MaybeSymName1),
|
|
(
|
|
Args0 = [],
|
|
ArgSpecs = []
|
|
;
|
|
Args0 = [_ | _],
|
|
ArgPieces = [words("Error: did not expect"),
|
|
qual_sym_name(SymName0), words("to have any arguments."), nl],
|
|
ArgSpec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), ArgPieces),
|
|
ArgSpecs = [ArgSpec]
|
|
),
|
|
( if
|
|
MaybeSymName1 = ok1(SymName),
|
|
ArgSpecs = []
|
|
then
|
|
MaybeSymName = ok1(SymName)
|
|
else
|
|
Specs = get_any_errors1(MaybeSymName1) ++ ArgSpecs,
|
|
MaybeSymName = error1(Specs)
|
|
)
|
|
;
|
|
MaybeSymNameAndArgs0 = error2(Specs),
|
|
MaybeSymName = error1(Specs)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
:- pred implicitly_qualify_sym_name_and_args(module_name::in, term(T)::in,
|
|
sym_name::in, list(term(T))::in, maybe2(sym_name, list(term(T)))::out)
|
|
is det.
|
|
|
|
implicitly_qualify_sym_name_and_args(DefaultModuleName, Term, SymName0, Args,
|
|
MaybeSymNameAndArgs) :-
|
|
( if
|
|
try_to_implicitly_qualify_sym_name(DefaultModuleName, SymName0,
|
|
SymName)
|
|
then
|
|
MaybeSymNameAndArgs = ok2(SymName, Args)
|
|
else
|
|
Pieces = [words("Error: the module qualifier in"),
|
|
qual_sym_name(SymName0), words("does not match"),
|
|
words("the preceding"), decl("module"), words("declaration."), nl],
|
|
Spec = simplest_spec($pred, severity_error, phase_term_to_parse_tree,
|
|
get_term_context(Term), Pieces),
|
|
MaybeSymNameAndArgs = error2([Spec])
|
|
).
|
|
|
|
implicitly_qualify_sym_name(DefaultModuleName, Term, SymName0, MaybeSymName) :-
|
|
( if
|
|
try_to_implicitly_qualify_sym_name(DefaultModuleName, SymName0,
|
|
SymName)
|
|
then
|
|
MaybeSymName = ok1(SymName)
|
|
else
|
|
Pieces = [words("Error: the module qualifier in"),
|
|
qual_sym_name(SymName0), words("does not match"),
|
|
words("the preceding"), decl("module"), words("declaration."), nl],
|
|
Spec = simplest_spec($pred, severity_error, phase_term_to_parse_tree,
|
|
get_term_context(Term), Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
).
|
|
|
|
try_to_implicitly_qualify_sym_name(DefaultModuleName, SymName0, SymName) :-
|
|
(
|
|
SymName0 = qualified(ModuleName0, Name0),
|
|
( if partial_sym_name_matches_full(ModuleName0, DefaultModuleName) then
|
|
SymName = qualified(DefaultModuleName, Name0)
|
|
else
|
|
fail
|
|
)
|
|
;
|
|
SymName0 = unqualified(Name0),
|
|
SymName = qualified(DefaultModuleName, Name0)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
parse_symbol_name(VarSet, Term, MaybeSymName) :-
|
|
( if
|
|
Term = term.functor(term.atom(FunctorName), [ModuleTerm, NameTerm],
|
|
TermContext),
|
|
( FunctorName = ":"
|
|
; FunctorName = "."
|
|
)
|
|
then
|
|
( if NameTerm = term.functor(term.atom(Name), [], _) then
|
|
parse_symbol_name(VarSet, ModuleTerm, MaybeModule),
|
|
(
|
|
MaybeModule = ok1(Module),
|
|
MaybeSymName = ok1(qualified(Module, Name))
|
|
;
|
|
MaybeModule = error1(_ModuleResultSpecs),
|
|
% XXX We should say "module name" OR "identifier", not both.
|
|
Pieces = [words("Error: module name identifier"),
|
|
words("expected before"), quote(FunctorName),
|
|
words("in qualified symbol name."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
% XXX Should we include _ModuleResultSpecs?
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
else
|
|
Pieces = [words("Error: identifier expected after"),
|
|
quote(FunctorName), words("in qualified symbol name."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, TermContext, Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
else
|
|
( if Term = term.functor(term.atom(Name), [], _) then
|
|
SymName = string_to_sym_name_sep(Name, "__"),
|
|
MaybeSymName = ok1(SymName)
|
|
else
|
|
TermStr = describe_error_term(VarSet, Term),
|
|
Pieces = [words("Error: symbol name expected at"),
|
|
words(TermStr), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymName = error1([Spec])
|
|
)
|
|
).
|
|
|
|
try_parse_symbol_name(Term, SymName) :-
|
|
( if
|
|
Term = term.functor(term.atom(FunctorName), [ModuleTerm, NameTerm],
|
|
_TermContext),
|
|
( FunctorName = ":"
|
|
; FunctorName = "."
|
|
)
|
|
then
|
|
NameTerm = term.functor(term.atom(Name), [], _),
|
|
try_parse_symbol_name(ModuleTerm, Module),
|
|
SymName = qualified(Module, Name)
|
|
else
|
|
Term = term.functor(term.atom(Name), [], _),
|
|
SymName = string_to_sym_name_sep(Name, "__")
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
parse_implicitly_qualified_symbol_name(DefaultModuleName, VarSet, Term,
|
|
MaybeSymName) :-
|
|
parse_symbol_name(VarSet, Term, MaybeSymName0),
|
|
(
|
|
MaybeSymName0 = ok1(SymName0),
|
|
implicitly_qualify_sym_name(DefaultModuleName, Term,
|
|
SymName0, MaybeSymName)
|
|
;
|
|
MaybeSymName0 = error1(_),
|
|
MaybeSymName = MaybeSymName0
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
|
|
parse_symbol_name_specifier(VarSet, Term, MaybeSymNameSpecifier) :-
|
|
( if Term = term.functor(term.atom("/"), [NameTerm, ArityTerm], _) then
|
|
( if term_int.decimal_term_to_int(ArityTerm, Arity) then
|
|
( if Arity >= 0 then
|
|
parse_symbol_name(VarSet, NameTerm, MaybeName),
|
|
(
|
|
MaybeName = error1(Specs),
|
|
MaybeSymNameSpecifier = error1(Specs)
|
|
;
|
|
MaybeName = ok1(Name),
|
|
UserArity = user_arity(Arity),
|
|
MaybeSymNameSpecifier =
|
|
ok1(sym_name_specifier_name_arity(Name, UserArity))
|
|
)
|
|
else
|
|
Pieces = [words("Error: arity in symbol name specifier"),
|
|
words("must be a non-negative integer."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymNameSpecifier = error1([Spec])
|
|
)
|
|
else
|
|
Pieces = [words("Error: arity in symbol name specifier"),
|
|
words("must be an integer."), nl],
|
|
Spec = simplest_spec($pred, severity_error,
|
|
phase_term_to_parse_tree, get_term_context(Term), Pieces),
|
|
MaybeSymNameSpecifier = error1([Spec])
|
|
)
|
|
else
|
|
parse_symbol_name(VarSet, Term, MaybeSymbolName),
|
|
(
|
|
MaybeSymbolName = error1(Specs),
|
|
MaybeSymNameSpecifier = error1(Specs)
|
|
;
|
|
MaybeSymbolName = ok1(SymbolName),
|
|
MaybeSymNameSpecifier = ok1(sym_name_specifier_name(SymbolName))
|
|
)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------e
|
|
:- end_module parse_tree.parse_sym_name.
|
|
%-----------------------------------------------------------------------------e
|