[m-rev.] for review: improve error reporting for more foreign language interface pragmas
Julien Fischer
jfischer at opturion.com
Wed May 25 11:37:30 AEST 2016
For review by anyone.
Note I will handle pragma foreign_{decl,code,type,proc} in a separate
change. By and large I haven't changed the content of the error
messages, although that could be improved in many cases. I will
post something about that latter point to the developers list later.
------------------
Improve error reporting for more foreign language interface pragmas.
The first argument of all foreign language interface pragmas specifies the
foreign language. Define a separate predicate that can be used to parse
this for all of them and use that predicate for foreign_{enum,export_enum,
import_module,export} pragmas. (The others will be converted in a separate
change.)
Report all of the syntax errors occurring in foreign_{export_enum,import_module,
export) pragmas, not just the first one.
Improve test coverage for syntax errors occurring in the above pragmas.
compiler/parse_pragma.m:
Rename parse_foreign_language/2 and re-purpose the existing name for
a new predicate that parses a foreign language, possibly returning
an error spec.
Report all syntax errors that occur in foreign_{export_enum,import_module,
export} pragmas.
Add a comment noting some additional checks we could perform for
foreign_export pragmas.
For foreign_import_module pragmas, generate separate error messages
for an incorrect number of arguments and an invalid module name.
Use the correct error context in a number of places.
Re-word some error messages.
compiler/parse_mutable.m:
Conform to the above change to parse_foreign_language.
tests/invalid/Mmakefile:
Add the new tests.
tests/invalid/bad_foreign_export.{m,err_exp}:
tests/invalid/bad_foreign_export_enum.{m,err_exp}:
tests/invalid/bad_foreign_import_module.{m,err_exp}:
New tests for syntax errors in these pragmas.
Julien.
diff --git a/compiler/parse_mutable.m b/compiler/parse_mutable.m
index 9277f28..129e21f 100644
--- a/compiler/parse_mutable.m
+++ b/compiler/parse_mutable.m
@@ -410,7 +410,7 @@ parse_mutable_attr(MutAttrTerm, MutAttrResult) :-
else if
MutAttrTerm = term.functor(term.atom("foreign_name"), Args, _),
Args = [LangTerm, ForeignNameTerm],
- parse_foreign_language(LangTerm, Lang),
+ term_to_foreign_language(LangTerm, Lang),
ForeignNameTerm = term.functor(term.string(ForeignName), [], _)
then
MutAttr = mutable_attr_foreign_name(foreign_name(Lang, ForeignName)),
diff --git a/compiler/parse_pragma.m b/compiler/parse_pragma.m
index 58cbed1..99d570c 100644
--- a/compiler/parse_pragma.m
+++ b/compiler/parse_pragma.m
@@ -38,7 +38,7 @@
% Parse a term that represents a foreign language.
%
-:- pred parse_foreign_language(term::in, foreign_language::out) is semidet.
+:- pred term_to_foreign_language(term::in, foreign_language::out) is semidet.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
@@ -153,7 +153,7 @@ parse_pragma_type(ModuleName, VarSet, ErrorTerm, PragmaName, PragmaTerms,
PragmaTerms, Context, SeqNum, MaybeIOM)
;
PragmaName = "foreign_import_module",
- parse_pragma_foreign_import_module(ErrorTerm,
+ parse_pragma_foreign_import_module(VarSet, ErrorTerm,
PragmaTerms, Context, SeqNum, MaybeIOM)
;
(
@@ -387,7 +387,7 @@ parse_pragma_foreign_type(ModuleName, VarSet, ErrorTerm, PragmaTerms,
MaybeAssertionTerm = yes(AssertionTerm0)
)
then
- ( if parse_foreign_language(LangTerm, Language) then
+ ( if term_to_foreign_language(LangTerm, Language) then
parse_foreign_language_type(ForeignTypeTerm, VarSet, Language,
MaybeForeignType)
else
@@ -525,46 +525,33 @@ parse_pragma_foreign_export_enum(VarSet, ErrorTerm, PragmaTerms,
MaybeOverridesTerm = yes(OverridesTerm)
)
then
- ( if parse_foreign_language(LangTerm, ForeignLang) then
- parse_type_ctor_name_arity("foreign_export_enum", MercuryTypeTerm,
- MaybeTypeCtor),
- (
- MaybeTypeCtor = ok1(TypeCtor),
- maybe_parse_export_enum_attributes(VarSet, MaybeAttributesTerm,
- MaybeAttributes),
- (
- MaybeAttributes = ok1(Attributes),
- maybe_parse_export_enum_overrides(VarSet,
- MaybeOverridesTerm, MaybeOverrides),
- (
- MaybeOverrides = ok1(Overrides),
- FEEInfo = pragma_info_foreign_export_enum(ForeignLang,
- TypeCtor, Attributes, Overrides),
- Pragma = pragma_foreign_export_enum(FEEInfo),
- ItemPragma = item_pragma_info(Pragma, item_origin_user,
- Context, SeqNum),
- Item = item_pragma(ItemPragma),
- MaybeIOM = ok1(iom_item(Item))
- ;
- MaybeOverrides = error1(Specs),
- MaybeIOM = error1(Specs)
- )
- ;
- MaybeAttributes = error1(Specs),
- MaybeIOM = error1(Specs)
- )
- ;
- MaybeTypeCtor = error1(Specs),
- MaybeIOM = error1(Specs)
- )
+ parse_foreign_language("foreign_export_enum", VarSet, LangTerm,
+ MaybeForeignLang),
+ parse_type_ctor_name_arity("foreign_export_enum", MercuryTypeTerm,
+ MaybeTypeCtor),
+ maybe_parse_export_enum_attributes(VarSet, MaybeAttributesTerm,
+ MaybeAttributes),
+ maybe_parse_export_enum_overrides(VarSet, MaybeOverridesTerm,
+ MaybeOverrides),
+ ( if
+ MaybeForeignLang = ok1(ForeignLang),
+ MaybeTypeCtor = ok1(TypeCtor),
+ MaybeAttributes = ok1(Attributes),
+ MaybeOverrides = ok1(Overrides)
+ then
+ FEEInfo = pragma_info_foreign_export_enum(ForeignLang, TypeCtor,
+ Attributes, Overrides),
+ Pragma = pragma_foreign_export_enum(FEEInfo),
+ ItemPragma = item_pragma_info(Pragma, item_origin_user, Context,
+ SeqNum),
+ Item = item_pragma(ItemPragma),
+ MaybeIOM = ok1(iom_item(Item))
else
- Pieces = [words("Error: invalid foreign language in"),
- pragma_decl("foreign_export_enum"), words("declaration."),
- nl],
- % XXX Get_term_context(LangTerm) would be better.
- Spec = error_spec(severity_error, phase_term_to_parse_tree,
- [simple_msg(get_term_context(ErrorTerm), [always(Pieces)])]),
- MaybeIOM = error1([Spec])
+ Specs = get_any_errors1(MaybeForeignLang) ++
+ get_any_errors1(MaybeTypeCtor) ++
+ get_any_errors1(MaybeAttributes) ++
+ get_any_errors1(MaybeOverrides),
+ MaybeIOM = error1(Specs)
)
else
Pieces = [words("Error: wrong number of arguments in"),
@@ -726,18 +713,8 @@ parse_pragma_foreign_enum(VarSet, ErrorTerm, PragmaTerms, Context, SeqNum,
MaybeIOM) :-
( if PragmaTerms = [LangTerm, MercuryTypeTerm, ValuesTerm] then
- ( if parse_foreign_language(LangTerm, ForeignLang) then
- MaybeForeignLang = ok1(ForeignLang)
- else
- LangPieces = [words("Error: invalid foreign language"),
- quote(describe_error_term(VarSet, LangTerm)), words("in"),
- pragma_decl("foreign_enum"), words("declaration."),
- nl],
- LangSpec = error_spec(severity_error, phase_term_to_parse_tree,
- [simple_msg(get_term_context(LangTerm), [always(LangPieces)])]),
- MaybeForeignLang = error1([LangSpec])
- ),
-
+ parse_foreign_language("foreign_enum", VarSet, LangTerm,
+ MaybeForeignLang),
parse_type_ctor_name_arity("foreign_enum", MercuryTypeTerm,
MaybeTypeCtor),
@@ -776,12 +753,11 @@ parse_pragma_foreign_enum(VarSet, ErrorTerm, PragmaTerms, Context, SeqNum,
),
( if
- MaybeForeignLang = ok1(ForeignLangPrime),
+ MaybeForeignLang = ok1(ForeignLang),
MaybeTypeCtor = ok1(TypeCtor),
MaybeValues = ok1(Values)
then
- FEInfo = pragma_info_foreign_enum(ForeignLangPrime, TypeCtor,
- Values),
+ FEInfo = pragma_info_foreign_enum(ForeignLang, TypeCtor, Values),
Pragma = pragma_foreign_enum(FEInfo),
ItemPragma = item_pragma_info(Pragma, item_origin_user, Context,
SeqNum),
@@ -806,6 +782,22 @@ parse_pragma_foreign_enum(VarSet, ErrorTerm, PragmaTerms, Context, SeqNum,
% Common code for parsing foreign_export_enum and foreign_enum pragms.
%
+:- pred parse_foreign_language(string::in, varset::in, term::in,
+ maybe1(foreign_language)::out) is det.
+
+parse_foreign_language(PragmaName, VarSet, LangTerm, MaybeForeignLang) :-
+ ( if term_to_foreign_language(LangTerm, ForeignLang) then
+ MaybeForeignLang = ok1(ForeignLang)
+ else
+ LangPieces = [words("Error: invalid foreign language"),
+ quote(describe_error_term(VarSet, LangTerm)), words("in"),
+ pragma_decl(PragmaName), words("declaration."),
+ nl],
+ LangSpec = error_spec(severity_error, phase_term_to_parse_tree,
+ [simple_msg(get_term_context(LangTerm), [always(LangPieces)])]),
+ MaybeForeignLang = error1([LangSpec])
+ ).
+
:- pred parse_type_ctor_name_arity(string::in, term::in,
maybe1(type_ctor)::out) is det.
@@ -831,46 +823,49 @@ parse_type_ctor_name_arity(PragmaName, TypeTerm, MaybeTypeCtor) :-
parse_pragma_foreign_export(VarSet, ErrorTerm, PragmaTerms, Context, SeqNum,
MaybeIOM) :-
( if PragmaTerms = [LangTerm, PredAndModesTerm, FunctionTerm] then
- ( if FunctionTerm = term.functor(term.string(Function), [], _) then
- ContextPieces = cord.from_list([words("In"),
- pragma_decl("foreign_export"), words("declaration:")]),
- parse_pred_or_func_and_arg_modes(no, VarSet, ContextPieces,
- PredAndModesTerm, MaybePredAndModes),
- (
- MaybePredAndModes = ok3(PredName, PredOrFunc, Modes),
- ( if parse_foreign_language(LangTerm, ForeignLanguage) then
- PredNameModesPF = pred_name_modes_pf(PredName, Modes,
- PredOrFunc),
- FPEInfo = pragma_info_foreign_proc_export(ForeignLanguage,
- PredNameModesPF, Function),
- Pragma = pragma_foreign_proc_export(FPEInfo),
- ItemPragma = item_pragma_info(Pragma, item_origin_user,
- Context, SeqNum),
- Item = item_pragma(ItemPragma),
- MaybeIOM = ok1(iom_item(Item))
- else
- Pieces = [words("Error: invalid foreign language in"),
- pragma_decl("foreign_export"), words("declaration."),
- nl],
- Spec = error_spec(severity_error, phase_term_to_parse_tree,
- [simple_msg(get_term_context(LangTerm),
- [always(Pieces)])]),
- MaybeIOM = error1([Spec])
- )
- ;
- MaybePredAndModes = error3(Specs),
- MaybeIOM = error1(Specs)
- )
+ parse_foreign_language("foreign_export", VarSet, LangTerm,
+ MaybeForeignLang),
+ ContextPieces = cord.from_list([words("In"),
+ pragma_decl("foreign_export"), words("declaration:")]),
+ parse_pred_or_func_and_arg_modes(no, VarSet, ContextPieces,
+ PredAndModesTerm, MaybePredAndModes),
+ ( if FunctionTerm = term.functor(term.string(Function0), [], _) then
+ MaybeFunction = ok1(Function0)
+ % XXX TODO: do some additional checks here:
+ % 1. check that Function0 is not the empty string.
+ % 2. if we have a valid foreign language, check that Function0
+ % is a valid identifier in that language.
else
- % XXX Why this wording?
- Pieces = [words("Error: expected pragma"),
- words("foreign_export(Lang, PredName(ModeList), Function)."),
- nl],
- % XXX Should we use the context of FunctionTerm?
- Spec = error_spec(severity_error, phase_term_to_parse_tree,
- [simple_msg(get_term_context(PredAndModesTerm),
- [always(Pieces)])]),
- MaybeIOM = error1([Spec])
+ FunctionPieces = [
+ words("In"), pragma_decl("foreign_export"),
+ words("declaration: error:"),
+ words("string expected at"),
+ quote(describe_error_term(VarSet, FunctionTerm)),
+ suffix("."), nl
+ ],
+ FunctionSpec = error_spec(severity_error, phase_term_to_parse_tree,
+ [simple_msg(get_term_context(FunctionTerm),
+ [always(FunctionPieces)])]),
+ MaybeFunction = error1([FunctionSpec])
+ ),
+ ( if
+ MaybeForeignLang = ok1(ForeignLang),
+ MaybePredAndModes = ok3(PredName, PredOrFunc, Modes),
+ MaybeFunction = ok1(Function)
+ then
+ PredNameModesPF = pred_name_modes_pf(PredName, Modes, PredOrFunc),
+ FPEInfo = pragma_info_foreign_proc_export(ForeignLang,
+ PredNameModesPF, Function),
+ Pragma = pragma_foreign_proc_export(FPEInfo),
+ ItemPragma = item_pragma_info(Pragma, item_origin_user, Context,
+ SeqNum),
+ Item = item_pragma(ItemPragma),
+ MaybeIOM = ok1(iom_item(Item))
+ else
+ Specs = get_any_errors1(MaybeForeignLang) ++
+ get_any_errors3(MaybePredAndModes) ++
+ get_any_errors1(MaybeFunction),
+ MaybeIOM = error1(Specs)
)
else
Pieces = [words("Error: wrong number of arguments in"),
@@ -882,34 +877,49 @@ parse_pragma_foreign_export(VarSet, ErrorTerm, PragmaTerms, Context, SeqNum,
%---------------------------------------------------------------------------%
-:- pred parse_pragma_foreign_import_module(term::in, list(term)::in,
- prog_context::in, int::in, maybe1(item_or_marker)::out) is det.
+:- pred parse_pragma_foreign_import_module(varset::in, term::in,
+ list(term)::in, prog_context::in, int::in, maybe1(item_or_marker)::out)
+ is det.
-parse_pragma_foreign_import_module(ErrorTerm, PragmaTerms, Context, SeqNum,
- MaybeIOM) :-
+parse_pragma_foreign_import_module(VarSet, ErrorTerm, PragmaTerms, Context,
+ SeqNum, MaybeIOM) :-
( if
- PragmaTerms = [LangTerm, ImportTerm],
- try_parse_sym_name_and_no_args(ImportTerm, Import)
+ PragmaTerms = [LangTerm, ImportTerm]
then
- ( if parse_foreign_language(LangTerm, Language) then
+ parse_foreign_language("foreign_import_language", VarSet, LangTerm,
+ MaybeForeignLang),
+ ( if try_parse_sym_name_and_no_args(ImportTerm, Import0) then
+ MaybeImportModule = ok1(Import0)
+ else
+ ImportModulePieces = [
+ words("Error: invalid module name"),
+ quote(describe_error_term(VarSet, ImportTerm)),
+ words("in"), pragma_decl("foreign_import_module"),
+ words("declaration."), nl],
+ ImportModuleSpec = error_spec(severity_error,
+ phase_term_to_parse_tree,
+ [simple_msg(get_term_context(ImportTerm),
+ [always(ImportModulePieces)])]),
+ MaybeImportModule = error1([ImportModuleSpec])
+ ),
+ ( if
+ MaybeForeignLang = ok1(Language),
+ MaybeImportModule = ok1(Import)
+ then
FIM = foreign_import_module_info(Language, Import),
FIMInfo = pragma_info_foreign_import_module(FIM),
Pragma = pragma_foreign_import_module(FIMInfo),
- ItemPragma = item_pragma_info(Pragma, item_origin_user,
- Context, SeqNum),
+ ItemPragma = item_pragma_info(Pragma, item_origin_user, Context,
+ SeqNum),
Item = item_pragma(ItemPragma),
MaybeIOM = ok1(iom_item(Item))
else
- Pieces = [words("Error: invalid foreign language in"),
- pragma_decl("foreign_import_module"),
- words("declaration."), nl],
- Spec = error_spec(severity_error, phase_term_to_parse_tree,
- [simple_msg(get_term_context(LangTerm), [always(Pieces)])]),
- MaybeIOM = error1([Spec])
+ Specs = get_any_errors1(MaybeForeignLang) ++
+ get_any_errors1(MaybeImportModule),
+ MaybeIOM = error1(Specs)
)
else
- Pieces = [words("Error: wrong number of arguments"),
- words("or invalid module name in"),
+ Pieces = [words("Error: wrong number of arguments in"),
pragma_decl("foreign_import_module"),
words("declaration."), nl],
Spec = error_spec(severity_error, phase_term_to_parse_tree,
@@ -1906,9 +1916,9 @@ parse_foreign_literal_or_include(Term, LiteralOrInclude) :-
LiteralOrInclude = floi_include_file(FileName)
).
-parse_foreign_language(term.functor(term.string(String), _, _), Lang) :-
+term_to_foreign_language(term.functor(term.string(String), _, _), Lang) :-
globals.convert_foreign_language(String, Lang).
-parse_foreign_language(term.functor(term.atom(String), _, _), Lang) :-
+term_to_foreign_language(term.functor(term.atom(String), _, _), Lang) :-
globals.convert_foreign_language(String, Lang).
:- pred parse_foreign_language_type(term::in, varset::in, foreign_language::in,
@@ -1985,7 +1995,7 @@ parse_pragma_foreign_decl_pragma(VarSet, ErrorTerm, PragmaTerms,
parse_foreign_decl_is_local(IsLocalTerm, IsLocal)
)
then
- ( if parse_foreign_language(LangTerm, ForeignLanguage) then
+ ( if term_to_foreign_language(LangTerm, ForeignLanguage) then
( if
parse_foreign_literal_or_include(HeaderTerm, LiteralOrInclude)
then
@@ -2034,7 +2044,7 @@ parse_pragma_foreign_code_pragma(ErrorTerm,
InvalidDeclPrefix = [words("Error: invalid"),
pragma_decl("foreign_code"), words("declaration:")],
( if PragmaTerms = [LangTerm, CodeTerm] then
- ( if parse_foreign_language(LangTerm, ForeignLanguagePrime) then
+ ( if term_to_foreign_language(LangTerm, ForeignLanguagePrime) then
ForeignLanguage = ForeignLanguagePrime,
LangSpecs = []
else
@@ -2091,7 +2101,7 @@ parse_pragma_foreign_proc_pragma(ModuleName, VarSet, ErrorTerm,
pragma_decl("foreign_proc"), words("declaration:")],
(
PragmaTerms = [LangTerm | RestTerms],
- ( if parse_foreign_language(LangTerm, ForeignLanguagePrime) then
+ ( if term_to_foreign_language(LangTerm, ForeignLanguagePrime) then
ForeignLanguage = ForeignLanguagePrime,
LangSpecs = []
else
diff --git a/tests/invalid/Mmakefile b/tests/invalid/Mmakefile
index 295526b..7efb373 100644
--- a/tests/invalid/Mmakefile
+++ b/tests/invalid/Mmakefile
@@ -50,6 +50,9 @@ SINGLEMODULE= \
bad_detism \
bad_end_module \
bad_foreign_enum \
+ bad_foreign_export \
+ bad_foreign_export_enum \
+ bad_foreign_import_module \
bad_finalise_decl \
bad_initialise_decl \
bad_inst_for_type \
diff --git a/tests/invalid/bad_foreign_export.err_exp b/tests/invalid/bad_foreign_export.err_exp
index e69de29..4e746ae 100644
--- a/tests/invalid/bad_foreign_export.err_exp
+++ b/tests/invalid/bad_foreign_export.err_exp
@@ -0,0 +1,14 @@
+bad_foreign_export.m:020: Error: wrong number of arguments in
+bad_foreign_export.m:020: `:- pragma foreign_export' declaration.
+bad_foreign_export.m:024: In `:- pragma foreign_export' declaration: error:
+bad_foreign_export.m:024: atom expected at 12345.
+bad_foreign_export.m:028: In `:- pragma foreign_export' declaration: error:
+bad_foreign_export.m:028: string expected at `12345'.
+bad_foreign_export.m:032: Error: invalid foreign language `"InvalidLanguage"'
+bad_foreign_export.m:032: in `:- pragma foreign_export' declaration.
+bad_foreign_export.m:037: Error: invalid foreign language `"InvalidLanguage"'
+bad_foreign_export.m:037: in `:- pragma foreign_export' declaration.
+bad_foreign_export.m:038: In `:- pragma foreign_export' declaration: error:
+bad_foreign_export.m:038: atom expected at 1234.
+bad_foreign_export.m:039: In `:- pragma foreign_export' declaration: error:
+bad_foreign_export.m:039: string expected at `5678'.
diff --git a/tests/invalid/bad_foreign_export.m b/tests/invalid/bad_foreign_export.m
index e69de29..a693b1a 100644
--- a/tests/invalid/bad_foreign_export.m
+++ b/tests/invalid/bad_foreign_export.m
@@ -0,0 +1,40 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+%
+% Test for the error messages generated for syntax errror in 'foreign_export'
+% pragmas.
+
+:- module bad_foreign_export.
+:- interface.
+
+:- func foo(int, int) = int.
+
+:- implementation.
+:- import_module int.
+
+foo(X, Y) = X + Y.
+
+ % Incorrect number of arguments.
+ %
+:- pragma foreign_export("C").
+
+ % Second arg is not pred-and-modes.
+ %
+:- pragma foreign_export("C", 12345, "Test2").
+
+ % Third arg is not a string.
+ %
+:- pragma foreign_export("C", foo(in, in) = out, 12345).
+
+ % Invalid foreign laguage.
+ %
+:- pragma foreign_export("InvalidLanguage", foo(in, in) = out, "Test4").
+
+ % Check that the contexts error messages for each argument are correct.
+ %
+:- pragma foreign_export(
+ "InvalidLanguage",
+ 1234,
+ 5678
+).
diff --git a/tests/invalid/bad_foreign_export_enum.err_exp b/tests/invalid/bad_foreign_export_enum.err_exp
index e69de29..8aec84f 100644
--- a/tests/invalid/bad_foreign_export_enum.err_exp
+++ b/tests/invalid/bad_foreign_export_enum.err_exp
@@ -0,0 +1,16 @@
+bad_foreign_export_enum.m:017: Error: wrong number of arguments in
+bad_foreign_export_enum.m:017: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:021: Error: invalid foreign language
+bad_foreign_export_enum.m:021: `"InvalidLanguage"' in
+bad_foreign_export_enum.m:021: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:025: Error: expected name/arity for type in
+bad_foreign_export_enum.m:025: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:028: Error: invalid foreign language
+bad_foreign_export_enum.m:028: `"InvalidLanguage"' in
+bad_foreign_export_enum.m:028: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:029: Error: expected name/arity for type in
+bad_foreign_export_enum.m:029: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:030: Error: malformed attributes list in
+bad_foreign_export_enum.m:030: `:- pragma foreign_export_enum' declaration.
+bad_foreign_export_enum.m:031: Error: expected list of mapping elements, not
+bad_foreign_export_enum.m:031: `5678'.
diff --git a/tests/invalid/bad_foreign_export_enum.m b/tests/invalid/bad_foreign_export_enum.m
index e69de29..7e914d1 100644
--- a/tests/invalid/bad_foreign_export_enum.m
+++ b/tests/invalid/bad_foreign_export_enum.m
@@ -0,0 +1,33 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+:- module bad_foreign_export_enum.
+:- interface.
+
+:- type fruit
+ ---> orange
+ ; lemon
+ ; apple.
+
+:- implementation.
+
+ % Wrong number of arguments.
+ %
+:- pragma foreign_export_enum("C").
+
+ % Invalid foreign language.
+ %
+:- pragma foreign_export_enum("InvalidLanguage", fruit/0).
+
+ % Second arg is not name / arity.
+ %
+:- pragma foreign_export_enum("C", fruit).
+
+:- pragma foreign_export_enum(
+ "InvalidLanguage",
+ fruit,
+ 1234,
+ 5678
+).
+
diff --git a/tests/invalid/bad_foreign_import_module.err_exp b/tests/invalid/bad_foreign_import_module.err_exp
index e69de29..49a865b 100644
--- a/tests/invalid/bad_foreign_import_module.err_exp
+++ b/tests/invalid/bad_foreign_import_module.err_exp
@@ -0,0 +1,14 @@
+bad_foreign_import_module.m:018: Error: wrong number of arguments in
+bad_foreign_import_module.m:018: `:- pragma foreign_import_module'
+bad_foreign_import_module.m:018: declaration.
+bad_foreign_import_module.m:022: Error: invalid foreign language
+bad_foreign_import_module.m:022: `"InvalidForeignLang"' in
+bad_foreign_import_module.m:022: `:- pragma foreign_import_language'
+bad_foreign_import_module.m:022: declaration.
+bad_foreign_import_module.m:027: Error: invalid foreign language
+bad_foreign_import_module.m:027: `"InvalidForeignLang"' in
+bad_foreign_import_module.m:027: `:- pragma foreign_import_language'
+bad_foreign_import_module.m:027: declaration.
+bad_foreign_import_module.m:028: Error: invalid module name `int(int)' in
+bad_foreign_import_module.m:028: `:- pragma foreign_import_module'
+bad_foreign_import_module.m:028: declaration.
diff --git a/tests/invalid/bad_foreign_import_module.m b/tests/invalid/bad_foreign_import_module.m
index e69de29..83a79c4 100644
--- a/tests/invalid/bad_foreign_import_module.m
+++ b/tests/invalid/bad_foreign_import_module.m
@@ -0,0 +1,29 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+%
+% Test for error messages produced by syntax errors in 'foreign_import_module'
+% pragmas.
+%
+
+:- module bad_foreign_import_module.
+:- interface.
+
+:- type foo ---> foo.
+
+:- implementation.
+
+ % Incorrect number of arguments.
+ %
+:- pragma foreign_import_module("C").
+
+ % Invalid foreign language.
+ %
+:- pragma foreign_import_module("InvalidForeignLang", int).
+
+ % Check that contexts for the language and import term are correct.
+ %
+:- pragma foreign_import_module(
+ "InvalidForeignLang",
+ int(int)
+).
More information about the reviews
mailing list