diff: improved error messages for some syntax errors
Fergus Henderson
fjh at hydra.cs.mu.oz.au
Sun Nov 2 23:27:12 AEDT 1997
Estimated hours taken: 1
Improve the error messages for certain kinds of syntax errors,
where variables occur in places that they shouldn't.
compiler/prog_io_goal.m:
Change parse_qualified_term to take an extra argument,
the "containing" term, in case the term being parsed
is a term__variable, which will not have a term__context.
Use the new argument to give better error messages.
compiler/make_hlds.m:
compiler/prog_io.m:
compiler/prog_io_dcg.m:
compiler/prog_io_pragma.m:
compiler/prog_io_util.m:
Changed calls to parse_qualified_term to pass the new argument.
tests/invalid/Mmakefile:
tests/invalid/vars_in_wrong_places.m:
tests/invalid/vars_in_wrong_places.err_exp:
Test cases for the above change.
cvs diff -N compiler/make_hlds.m compiler/prog_io.m compiler/prog_io_dcg.m compiler/prog_io_goal.m compiler/prog_io_pragma.m compiler/prog_io_util.m tests/invalid/Mmakefile tests/invalid/vars_in_wrong_places.err_exp tests/invalid/vars_in_wrong_places.m
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.242
diff -u -r1.242 make_hlds.m
--- make_hlds.m 1997/10/09 09:38:48 1.242
+++ make_hlds.m 1997/11/02 11:56:38
@@ -2849,10 +2849,10 @@
% NewVar3 = A3.
% In the trivial case `X = c', no unravelling occurs.
-unravel_unification(term__variable(X), Rhs,
+unravel_unification(term__variable(X), RHS,
Context, MainContext, SubContext, VarSet0,
Goal, VarSet, Info0, Info) -->
- { Rhs = term__functor(F, Args, FunctorContext) },
+ { RHS = term__functor(F, Args, FunctorContext) },
(
% Handle explicit type qualification.
{ semidet_fail },
@@ -2996,7 +2996,7 @@
{ goal_info_set_context(GoalInfo0, Context, GoalInfo) },
{ Goal = IfThenElse - GoalInfo }
;
- { parse_qualified_term(Rhs, "", MaybeFunctor) },
+ { parse_qualified_term(RHS, RHS, "", MaybeFunctor) },
(
{ MaybeFunctor = ok(FunctorName, FunctorArgs) },
{ list__length(FunctorArgs, Arity) },
Index: compiler/prog_io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io.m,v
retrieving revision 1.164
diff -u -r1.164 prog_io.m
--- prog_io.m 1997/10/09 09:39:07 1.164
+++ prog_io.m 1997/11/02 11:55:11
@@ -461,12 +461,12 @@
Head = term__functor(term__atom("="),
[FuncHead, FuncResult], _)
->
- parse_qualified_term(ModuleName, FuncHead,
+ parse_qualified_term(ModuleName, FuncHead, Head,
"equation head", R2),
process_func_clause(R2, FuncResult, VarSet2, Body2, R3)
;
- parse_qualified_term(ModuleName, Head, "clause head",
- R2),
+ parse_qualified_term(ModuleName, Head, Term,
+ "clause head", R2),
process_pred_clause(R2, VarSet2, Body2, R3)
),
add_context(R3, TheContext, Result)
@@ -978,9 +978,19 @@
:- mode check_for_errors(in, in, in, out) is det.
check_for_errors(ModuleName, Head, Body, Result) :-
( Head = term__variable(_) ->
- Result = error("variable on LHS of type definition", Head)
+ %
+ % `Head' has no term__context, so we need to get the
+ % context from `Body'
+ %
+ ( Body = term__functor(_, _, Context) ->
+ dummy_term_with_context(Context, ErrorTerm)
+ ;
+ dummy_term(ErrorTerm)
+ ),
+ Result = error("variable on LHS of type definition", ErrorTerm)
;
- parse_qualified_term(ModuleName, Head, "type definition", R),
+ parse_qualified_term(ModuleName, Head, Head,
+ "type definition", R),
check_for_errors_2(R, Body, Head, Result)
).
@@ -1059,7 +1069,7 @@
;
Term2 = Term
),
- parse_qualified_term(ModuleName, Term2, "constructor definition",
+ parse_qualified_term(ModuleName, Term2, Term, "constructor definition",
ok(F, As)),
convert_constructor_arg_list(As, Args),
Result = F - Args.
@@ -1073,7 +1083,8 @@
:- mode process_pred(in, in, in, in, in, out) is det.
process_pred(ModuleName, VarSet, PredType, Cond, MaybeDet, Result) :-
- parse_qualified_term(ModuleName, PredType, "`:- pred' declaration", R),
+ parse_qualified_term(ModuleName, PredType, PredType,
+ "`:- pred' declaration", R),
process_pred_2(R, PredType, VarSet, MaybeDet, Cond, Result).
:- pred process_pred_2(maybe_functor, term, varset, maybe(determinism),
@@ -1135,7 +1146,7 @@
Term = term__functor(term__atom("="),
[FuncTerm, ReturnTypeTerm], _Context)
->
- parse_qualified_term(ModuleName, FuncTerm,
+ parse_qualified_term(ModuleName, FuncTerm, Term,
"`:- func' declaration", R),
process_func_2(R, FuncTerm, ReturnTypeTerm, VarSet, MaybeDet,
Cond, Result)
@@ -1203,12 +1214,12 @@
Term = term__functor(term__atom("="),
[FuncTerm, ReturnTypeTerm], _Context)
->
- parse_qualified_term(ModuleName, FuncTerm,
+ parse_qualified_term(ModuleName, FuncTerm, Term,
"function `:- mode' declaration", R),
process_func_mode(R, FuncTerm, ReturnTypeTerm, VarSet, MaybeDet,
Cond, Result)
;
- parse_qualified_term(ModuleName, Term,
+ parse_qualified_term(ModuleName, Term, Term,
"predicate `:- mode' declaration", R),
process_pred_mode(R, Term, VarSet, MaybeDet, Cond, Result)
).
@@ -1296,7 +1307,7 @@
:- pred convert_inst_defn(string, term, term, maybe1(inst_defn)).
:- mode convert_inst_defn(in, in, in, out) is det.
convert_inst_defn(ModuleName, Head, Body, Result) :-
- parse_qualified_term(ModuleName, Head, "inst definition", R),
+ parse_qualified_term(ModuleName, Head, Body, "inst definition", R),
convert_inst_defn_2(R, Head, Body, Result).
:- pred convert_inst_defn_2(maybe_functor, term, term, maybe1(inst_defn)).
@@ -1356,7 +1367,7 @@
:- pred convert_abstract_inst_defn(string, term, maybe1(inst_defn)).
:- mode convert_abstract_inst_defn(in, in, out) is det.
convert_abstract_inst_defn(ModuleName, Head, Result) :-
- parse_qualified_term(ModuleName, Head, "inst definition", R),
+ parse_qualified_term(ModuleName, Head, Head, "inst definition", R),
convert_abstract_inst_defn_2(R, Head, Result).
:- pred convert_abstract_inst_defn_2(maybe_functor, term, maybe1(inst_defn)).
@@ -1419,7 +1430,7 @@
:- pred convert_mode_defn(string, term, term, maybe1(mode_defn)).
:- mode convert_mode_defn(in, in, in, out) is det.
convert_mode_defn(ModuleName, Head, Body, Result) :-
- parse_qualified_term(ModuleName, Head, "mode definition", R),
+ parse_qualified_term(ModuleName, Head, Head, "mode definition", R),
convert_mode_defn_2(R, Head, Body, Result).
:- pred convert_mode_defn_2(maybe_functor, term, term, maybe1(mode_defn)).
@@ -1754,7 +1765,7 @@
parse_symbol_name_specifier(Term, NameResult),
process_maybe1(make_arity_predicate_specifier, NameResult, Result)
;
- parse_qualified_term(Term, "predicate specifier", TermResult),
+ parse_qualified_term(Term, Term, "predicate specifier", TermResult),
process_typed_predicate_specifier(TermResult, Result)
).
@@ -1786,7 +1797,7 @@
parse_symbol_name_specifier(Term, NameResult),
process_maybe1(make_arity_predicate_specifier, NameResult, Result)
;
- parse_qualified_term(Term, "constructor specifier", TermResult),
+ parse_qualified_term(Term, Term, "constructor specifier", TermResult),
process_typed_predicate_specifier(TermResult, Result)
).
Index: compiler/prog_io_dcg.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_dcg.m,v
retrieving revision 1.6
diff -u -r1.6 prog_io_dcg.m
--- prog_io_dcg.m 1997/10/06 22:18:13 1.6
+++ prog_io_dcg.m 1997/11/02 11:56:53
@@ -42,7 +42,7 @@
new_dcg_var(VarSet0, 0, VarSet1, N0, DCG_0_Var),
parse_dcg_goal(DCG_Body, VarSet1, N0, DCG_0_Var,
Body, VarSet, _N, DCG_Var),
- parse_qualified_term(ModuleName, DCG_Head, "DCG clause head",
+ parse_qualified_term(ModuleName, DCG_Head, DCG_Body, "DCG clause head",
HeadResult),
process_dcg_clause(HeadResult, VarSet, DCG_0_Var, DCG_Var, Body, R),
add_context(R, DCG_Context, Result).
Index: compiler/prog_io_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_goal.m,v
retrieving revision 1.6
diff -u -r1.6 prog_io_goal.m
--- prog_io_goal.m 1997/10/06 22:18:16 1.6
+++ prog_io_goal.m 1997/11/02 12:10:25
@@ -85,23 +85,29 @@
:- pred sym_name_and_args(term, sym_name, list(term)).
:- mode sym_name_and_args(in, out, out) is semidet.
- % parse_qualified_term takes a term and an error message,
+ % parse_qualified_term/4 takes a term (and also the containing
+ % term, and a string describing the context from which it
+ % was called [e.g. "clause head"] and the containing term)
% and returns a sym_name and a list of argument terms.
% Returns an error on ill-formed input.
-:- pred parse_qualified_term(term, string, maybe_functor).
-:- mode parse_qualified_term(in, in, out) is det.
+:- pred parse_qualified_term(term, term, string, maybe_functor).
+:- mode parse_qualified_term(in, in, in, out) is det.
- % parse_qualified_term(DefaultModName, Term, Msg, Result).
- % parse_qualified_term takes a default module name and a term,
+ % parse_qualified_term(DefaultModName, Term,
+ % ContainingTerm, Msg, Result):
+ %
+ % parse_qualified_term/5 takes a default module name and a term,
+ % (and also the containing term, and a string describing
+ % the context from which it was called (e.g. "clause head"),
% and returns a sym_name and a list of argument terms.
% Returns an error on ill-formed input or a module qualifier that
% doesn't match the DefaultModName, if DefaultModName is not ""
% and not "mercury_builtin".
- % parse_qualified_term/3 calls parse_qualified_term/4, and is
+ % parse_qualified_term/4 calls parse_qualified_term/5, and is
% used when no default module name exists.
-:- pred parse_qualified_term(string, term, string, maybe_functor).
-:- mode parse_qualified_term(in, in, in, out) is det.
+:- pred parse_qualified_term(string, term, term, string, maybe_functor).
+:- mode parse_qualified_term(in, in, in, in, out) is det.
%-----------------------------------------------------------------------------%
@@ -353,12 +359,12 @@
%-----------------------------------------------------------------------------%
sym_name_and_args(Term, SymName, Args) :-
- parse_qualified_term(Term, "", ok(SymName, Args)).
+ parse_qualified_term(Term, Term, "", ok(SymName, Args)).
-parse_qualified_term(Term, Msg, Result) :-
- parse_qualified_term("", Term, Msg, Result).
+parse_qualified_term(Term, ContainingTerm, Msg, Result) :-
+ parse_qualified_term("", Term, ContainingTerm, Msg, Result).
-parse_qualified_term(DefaultModName, Term, Msg, Result) :-
+parse_qualified_term(DefaultModName, Term, ContainingTerm, Msg, Result) :-
(
Term = term__functor(term__atom(":"), [ModuleTerm, NameArgsTerm],
_Context)
@@ -416,7 +422,17 @@
)
;
string__append("atom expected in ", Msg, ErrorMsg),
- Result = error(ErrorMsg, Term)
+ %
+ % since variables don't have any term__context,
+ % if Term is a variable, we use ContainingTerm instead
+ % (hopefully that _will_ have a term__context).
+ %
+ ( Term = term__variable(_) ->
+ ErrorTerm = ContainingTerm
+ ;
+ ErrorTerm = Term
+ ),
+ Result = error(ErrorMsg, ErrorTerm)
)
).
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.7
diff -u -r1.7 prog_io_pragma.m
--- prog_io_pragma.m 1997/10/09 09:39:10 1.7
+++ prog_io_pragma.m 1997/11/02 12:02:18
@@ -163,7 +163,7 @@
PredAndModesTerm = term__functor(term__atom("="),
[FuncAndArgModesTerm, RetModeTerm], _)
->
- parse_qualified_term(FuncAndArgModesTerm,
+ parse_qualified_term(FuncAndArgModesTerm, PredAndModesTerm,
"pragma export declaration", FuncAndArgModesResult),
(
FuncAndArgModesResult = ok(FuncName, ArgModeTerms),
@@ -185,7 +185,7 @@
Result = error(Msg, Term)
)
;
- parse_qualified_term(PredAndModesTerm,
+ parse_qualified_term(PredAndModesTerm, ErrorTerm,
"pragma export declaration", PredAndModesResult),
(
PredAndModesResult = ok(PredName, ModeTerms),
@@ -267,7 +267,7 @@
term__atom("function"), [], _),
PredOrFunc = function
),
- parse_qualified_term(PredNameTerm,
+ parse_qualified_term(PredNameTerm, ErrorTerm,
"predicate name", PredNameResult),
PredNameResult = ok(PredName, []),
convert_int_list(UnusedArgsTerm, UnusedArgsResult),
@@ -290,7 +290,8 @@
->
(
parse_qualified_term(ModuleName, PredNameTerm,
- "pragma fact_table declaration", ok(PredName, [])),
+ PredAndArityTerm, "pragma fact_table declaration",
+ ok(PredName, [])),
ArityTerm = term__functor(term__integer(Arity), [], _)
->
(
@@ -347,7 +348,7 @@
PredAndModesTerm = PredAndModesTerm0,
FuncResultTerm = []
),
- parse_qualified_term(ModuleName, PredAndModesTerm,
+ parse_qualified_term(ModuleName, PredAndModesTerm, ErrorTerm,
"`pragma termination_info' declaration", PredNameResult),
PredNameResult = ok(PredName, ModeListTerm0),
(
@@ -445,8 +446,8 @@
[PredNameTerm, ArityTerm], _)
->
(
- parse_qualified_term(ModuleName, PredNameTerm, "",
- ok(PredName, [])),
+ parse_qualified_term(ModuleName, PredNameTerm, ErrorTerm,
+ "", ok(PredName, [])),
ArityTerm = term__functor(term__integer(Arity), [], _)
->
call(MakePragma, PredName, Arity, Pragma),
@@ -518,7 +519,7 @@
PredAndVarsTerm = PredAndVarsTerm0,
FuncResultTerms = []
),
- parse_qualified_term(ModuleName, PredAndVarsTerm,
+ parse_qualified_term(ModuleName, PredAndVarsTerm, PredAndVarsTerm0,
"pragma c_code declaration", PredNameResult),
(
PredNameResult = ok(PredName, VarList0),
Index: compiler/prog_io_util.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_util.m,v
retrieving revision 1.5
diff -u -r1.5 prog_io_util.m
--- prog_io_util.m 1997/07/27 15:01:30 1.5
+++ prog_io_util.m 1997/11/02 12:08:25
@@ -155,7 +155,7 @@
Inst = ground(shared, yes(FuncInstInfo)),
Mode = (Inst -> Inst)
;
- parse_qualified_term(Term, "mode definition", R),
+ parse_qualified_term(Term, Term, "mode definition", R),
R = ok(Name, Args), % should improve error reporting
convert_inst_list(Args, ConvertedArgs),
Mode = user_defined_mode(Name, ConvertedArgs)
@@ -167,7 +167,8 @@
convert_inst_list(T0, T).
convert_inst(term__variable(V), inst_var(V)).
-convert_inst(term__functor(Name, Args0, Context), Result) :-
+convert_inst(Term, Result) :-
+ Term = term__functor(Name, Args0, _Context),
% `free' insts
( Name = term__atom("free"), Args0 = [] ->
Result = free
@@ -250,8 +251,8 @@
% anything else must be a user-defined inst
;
- parse_qualified_term(term__functor(Name, Args0, Context),
- "inst", ok(QualifiedName, Args1)),
+ parse_qualified_term(Term, Term, "inst",
+ ok(QualifiedName, Args1)),
convert_inst_list(Args1, Args),
Result = defined_inst(user_inst(QualifiedName, Args))
).
@@ -287,7 +288,8 @@
convert_bound_inst(InstTerm, functor(ConsId, Args)) :-
InstTerm = term__functor(Functor, Args0, _),
( Functor = term__atom(_) ->
- parse_qualified_term(InstTerm, "inst", ok(SymName, Args1)),
+ parse_qualified_term(InstTerm, InstTerm, "inst",
+ ok(SymName, Args1)),
list__length(Args1, Arity),
ConsId = cons(SymName, Arity)
;
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/invalid/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- Mmakefile 1997/10/14 06:38:30 1.2
+++ Mmakefile 1997/11/02 12:20:54
@@ -36,7 +36,8 @@
unbound_inst_var.m \
undef_lambda_mode.m \
undef_mode.m \
- undef_type.m
+ undef_type.m \
+ vars_in_wrong_places.m
# we do not yet pass the following tests:
# freefree.m \
Index: tests/invalid/vars_in_wrong_places.err_exp
===================================================================
RCS file: vars_in_wrong_places.err_exp
diff -N vars_in_wrong_places.err_exp
--- /dev/null Tue Jan 1 15:00:00 1980
+++ vars_in_wrong_places.err_exp Sun Nov 2 23:21:38 1997
@@ -0,0 +1,8 @@
+vars_in_wrong_places.m:002: Error: atom expected in clause head: _0 :- blah.
+vars_in_wrong_places.m:003: Error: atom expected in equation head: _0 = 42.
+vars_in_wrong_places.m:004: Error: atom expected in equation head: _0 = 42.
+Error: atom expected in `:- pred' declaration: _0.
+vars_in_wrong_places.m:006: Error: atom expected in `:- func' declaration: _0 = int.
+Error: atom expected in predicate `:- mode' declaration: _0.
+vars_in_wrong_places.m:008: Error: atom expected in function `:- mode' declaration: _0 = int.
+For more information, try recompiling with `-E'.
Index: tests/invalid/vars_in_wrong_places.m
===================================================================
RCS file: vars_in_wrong_places.m
diff -N vars_in_wrong_places.m
--- /dev/null Tue Jan 1 15:00:00 1980
+++ vars_in_wrong_places.m Sun Nov 2 23:21:18 1997
@@ -0,0 +1,8 @@
+:- module vars_in_wrong_places.
+Oops1 :- blah.
+Oops2 = 42 :- blah.
+Oops3 = 42.
+:- pred Oops4.
+:- func Oops5 = int.
+:- mode Oops6.
+:- mode Oops7 = int.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list