[m-rev.] for review: mix non mode-specific mercury and foreign procs
Peter Ross
peter.ross at miscrit.be
Thu May 2 01:39:57 AEST 2002
Hi,
For trd to review.
===================================================================
Estimated hours taken: 8
Branches: main
Allow one to mix non mode-specific Mercury clauses and foreign procs.
compiler/make_hlds.m:
Handle clauses defined in both Mercury and foreign code by turning
all non mode-specific Mercury clauses into mode-specific Mercury
clauses.
tests/hard_coded/Mmakefile:
tests/hard_coded/foreign_and_mercury.exp:
tests/hard_coded/foreign_and_mercury.m:
Add a test case for mixing foreign and non mode-specific Mercury
clauses.
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.149
diff -u -r1.149 Mmakefile
--- tests/hard_coded/Mmakefile 29 Apr 2002 05:50:44 -0000 1.149
+++ tests/hard_coded/Mmakefile 1 May 2002 15:31:27 -0000
@@ -55,6 +55,7 @@
float_map \
float_reg \
float_rounding_bug \
+ foreign_and_mercury \
foreign_import_module \
frameopt_pragma_redirect \
free_free_mode \
Index: tests/hard_coded/foreign_and_mercury.exp
===================================================================
RCS file: tests/hard_coded/foreign_and_mercury.exp
diff -N tests/hard_coded/foreign_and_mercury.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/foreign_and_mercury.exp 1 May 2002 15:31:27 -0000
@@ -0,0 +1,2 @@
+2
+2
Index: tests/hard_coded/foreign_and_mercury.m
===================================================================
RCS file: tests/hard_coded/foreign_and_mercury.m
diff -N tests/hard_coded/foreign_and_mercury.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/foreign_and_mercury.m 1 May 2002 15:31:27 -0000
@@ -0,0 +1,31 @@
+% Test that we can use non-mode specific mercury implementations in
+% conjunction with foreign code procs.
+:- module foreign_and_mercury.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main -->
+ { f(2, Y) },
+ io__write_int(Y),
+ io__nl,
+ { g(2, Z) },
+ io__write_int(Z),
+ io__nl.
+
+:- pred f(int::in, int::out) is det.
+f(X, X).
+:- pragma foreign_proc(c, f(X::in, Y::out), [promise_pure], "
+ Y = X;
+").
+
+:- pred g(int::in, int::out) is det.
+:- pragma foreign_proc(c, g(X::in, Y::out), [promise_pure], "
+ Y = X;
+").
+g(X, X).
Index: il_compiler/compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.408
diff -u -r1.408 make_hlds.m
--- il_compiler/compiler/make_hlds.m 7 Apr 2002 10:22:34 -0000 1.408
+++ il_compiler/compiler/make_hlds.m 1 May 2002 15:31:35 -0000
@@ -3659,22 +3659,6 @@
PredInfo1 = PredInfo0
},
(
- { pred_info_pragma_goal_type(PredInfo1) },
- { get_mode_annotations(Args, _, empty, ModeAnnotations) },
- { ModeAnnotations = empty ; ModeAnnotations = none }
- ->
- % If we have a pragma foreign_proc for this procedure
- % already, and we are trying to add a non-mode specific
- % Mercury clause
- { module_info_incr_errors(ModuleInfo1, ModuleInfo) },
- prog_out__write_context(Context),
- io__write_string("Error: non mode-specific clause for "),
- hlds_out__write_simple_call_id(PredOrFunc, PredName/Arity),
- io__write_string("\n"),
- prog_out__write_context(Context),
- io__write_string(" with `:- pragma foreign_proc' declaration preceding.\n"),
- { Info = Info0 }
- ;
%
% User-supplied clauses for field access functions are
% not allowed -- the clauses are always generated by the
@@ -3841,12 +3825,28 @@
)
;
{ ModeAnnotations = empty },
- { ProcIds = [] }, % this means the clauses applies to all modes
+ { pred_info_pragma_goal_type(PredInfo) ->
+ % We are only allowed to mix foreign procs and
+ % mode specific clauses, so make this clause
+ % mode specific but apply to all modes.
+ pred_info_all_procids(PredInfo, ProcIds)
+ ;
+ % this means the clauses applies to all modes
+ ProcIds = []
+ },
{ ModuleInfo = ModuleInfo0 },
{ Info = Info0 }
;
{ ModeAnnotations = none },
- { ProcIds = [] }, % this means the clauses applies to all modes
+ { pred_info_pragma_goal_type(PredInfo) ->
+ % We are only allowed to mix foreign procs and
+ % mode specific clauses, so make this clause
+ % mode specific but apply to all modes.
+ pred_info_all_procids(PredInfo, ProcIds)
+ ;
+ % this means the clauses applies to all modes
+ ProcIds = []
+ },
{ ModuleInfo = ModuleInfo0 },
{ Info = Info0 }
;
@@ -4238,9 +4238,31 @@
% tagged as opt_imported only if/when we see a clause (including
% a `pragma c_code' clause) for them
{ Status = opt_imported ->
- pred_info_set_import_status(PredInfo0, opt_imported, PredInfo1)
+ pred_info_set_import_status(PredInfo0, opt_imported, PredInfo1a)
;
- PredInfo1 = PredInfo0
+ PredInfo1a = PredInfo0
+ },
+ {
+ % If this procedure was previously defined as clauses only
+ % then we need to turn all the non mode-specific clauses
+ % into mode-specific clauses.
+ pred_info_clause_goal_type(PredInfo1a)
+ ->
+ pred_info_clauses_info(PredInfo1a, CInfo0),
+ clauses_info_clauses(CInfo0, ClauseList0),
+ ClauseList = list__map(
+ (func(C) =
+ ( C = clause([], Goal, mercury, Ctxt) ->
+ clause(AllProcIds, Goal, mercury, Ctxt)
+ ;
+ C
+ ) :-
+ pred_info_all_procids(PredInfo1a, AllProcIds)
+ ), ClauseList0),
+ clauses_info_set_clauses(CInfo0, ClauseList, CInfo),
+ pred_info_set_clauses_info(PredInfo1a, CInfo, PredInfo1)
+ ;
+ PredInfo1 = PredInfo1a
},
(
{ pred_info_is_imported(PredInfo1) }
@@ -4254,23 +4276,6 @@
io__write_string(".\n"),
{ Info = Info0 }
;
- { pred_info_clause_goal_type(PredInfo1) },
- { pred_info_clauses_info(PredInfo1, CInfo) },
- { clauses_info_clauses(CInfo, ClauseList) },
- { list__member(clause([], _, mercury, _), ClauseList) }
-
- ->
- { module_info_incr_errors(ModuleInfo1, ModuleInfo) },
- prog_out__write_context(Context),
- io__write_string("Error: `:- pragma foreign_proc' (or `pragma c_code')\n"),
- prog_out__write_context(Context),
- io__write_string("declaration for "),
- hlds_out__write_simple_call_id(PredOrFunc, PredName/Arity),
- io__write_string("\n"),
- prog_out__write_context(Context),
- io__write_string(" with preceding non-mode specific clauses.\n"),
- { Info = Info0 }
- ;
% Don't add clauses for foreign languages other
% than the ones we can generate code for.
{ not list__member(PragmaForeignLanguage, BackendForeignLangs) }
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list