diff: fix bug with nested modules & intermod opt
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Nov 2 18:17:03 AEDT 1998
As usual, if anyone wants to review this one, please go ahead...
--------------------
Estimated hours taken: 20
Fix a bug with intermodule optimization of nested modules.
Previously, the compiler used to just label any
predicates defined in a module containing sub-modules
as `exported', since they may be needed by the separately-compiled
sub-modules. However, this is a little bit of a lie,
and it turns out that it doesn't work. The fix is
to use a new status `exported_to_submodules' for this case.
compiler/prog_data.m:
Add a new pseudo-declaration ":- private_interface",
used to mark items in an ":- implementation" section
that will be exported to submodules.
compiler/modules.m:
Put declarations from modules containing sub-modules into
`private_interface' sections rather than into `interface' sections.
compiler/hlds_pred.m:
Add a new alternative `exported_to_submodules' to the
`import_status' data type. Add several new procedures
for testing particular aspects of this type.
compiler/module_qual.m:
Set the import_status of items in a `private_interface'
section to `exported_to_submodules'.
compiler/intermod.m:
Handle procedures with status `exported_to_submodules'
specially. Also reorganize the code here a bit to make
it more maintainable.
compiler/base_type_info.m:
compiler/base_type_info.m:
compiler/base_typeclass_info.m:
compiler/code_util.m:
compiler/dead_proc_elim.m:
compiler/hlds_out.m:
compiler/make_hlds.m:
compiler/termination.m:
compiler/unused_args.m:
Minor changes to reflect the above changes to data-structures;
in particular, use the new procedures defined in hlds_pred.m
instead of hard-coded tests.
tests/hard_coded/Mmakefile:
tests/hard_coded/nested_intermod.m:
tests/hard_coded/nested_intermod_main.m:
tests/hard_coded/nested_intermod_main.exp:
Add a regression test for the bug mentioned above.
Index: compiler/base_type_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_type_info.m,v
retrieving revision 1.19
diff -u -r1.19 base_type_info.m
--- base_type_info.m 1998/09/03 11:13:23 1.19
+++ base_type_info.m 1998/10/27 17:39:57
@@ -148,13 +148,7 @@
but linkage/2 in llds_out.m requires that we make them all exported
if any of them are exported, so that we can compute the linkage
from the data_name, for use in forward declarations.
- (
- ( Status = exported ; Status = abstract_exported )
- ->
- Exported = yes
- ;
- Exported = no
- ),
+ status_is_exported(Status, Exported),
******/
Exported = yes,
Index: compiler/base_typeclass_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_typeclass_info.m,v
retrieving revision 1.6
diff -u -r1.6 base_typeclass_info.m
--- base_typeclass_info.m 1998/09/22 16:12:35 1.6
+++ base_typeclass_info.m 1998/10/27 16:32:11
@@ -78,15 +78,7 @@
(
% Only make the base_typeclass_info if the instance
% declaration originally came from _this_ module.
- (
- ImportStatus = exported
- ;
- ImportStatus = abstract_exported
- ;
- ImportStatus = pseudo_exported
- ;
- ImportStatus = local
- )
+ status_defined_in_this_module(ImportStatus, yes)
->
base_typeclass_info__make_instance_string(InstanceTypes,
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.101
diff -u -r1.101 code_util.m
--- code_util.m 1998/09/10 06:50:58 1.101
+++ code_util.m 1998/10/27 16:32:14
@@ -198,13 +198,7 @@
module_info_preds(ModuleInfo, Preds),
map__lookup(Preds, PredId, PredInfo),
(
- (
- pred_info_is_exported(PredInfo)
- ;
- pred_info_is_pseudo_exported(PredInfo),
- % only the (in, in) mode of a unification is exported
- hlds_pred__in_in_unification_proc_id(ProcId)
- )
+ procedure_is_exported(PredInfo, ProcId)
->
(
Immed = no,
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.42
diff -u -r1.42 dead_proc_elim.m
--- dead_proc_elim.m 1998/09/22 16:12:48 1.42
+++ dead_proc_elim.m 1998/10/27 16:32:16
@@ -179,9 +179,8 @@
Arity, _Status, _Elim, _Procs),
(
% XXX: We'd like to do this, but there are problems.
- % ( Status = exported
- % ; Status = abstract_exported
- % )
+ % status_is_exported(Status, yes)
+ %
% We need to do more thorough analysis of the
% reachability of the special predicates, in general,
% because using arg/3 allows us to get at base_type_info
@@ -228,11 +227,7 @@
(
% We only need the instance declarations which were
% made in this module.
- ( ImportStatus = exported
- ; ImportStatus = abstract_exported
- ; ImportStatus = pseudo_exported
- ; ImportStatus = local
- )
+ status_defined_in_this_module(ImportStatus, yes)
->
get_instance_pred_procs2(PredProcIds, Queue0, Queue,
Needed0, Needed)
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.207
diff -u -r1.207 hlds_out.m
--- hlds_out.m 1998/10/16 10:37:29 1.207
+++ hlds_out.m 1998/10/27 16:32:23
@@ -1729,6 +1729,8 @@
io__write_string("opt_imported").
hlds_out__write_import_status(pseudo_imported) -->
io__write_string("pseudo_imported").
+hlds_out__write_import_status(exported_to_submodules) -->
+ io__write_string("exported_to_submodules").
:- pred hlds_out__write_var_types(int, varset, bool, map(var, type), varset,
io__state, io__state).
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.54
diff -u -r1.54 hlds_pred.m
--- hlds_pred.m 1998/10/23 00:40:06 1.54
+++ hlds_pred.m 1998/10/30 06:00:30
@@ -170,7 +170,31 @@
; pseudo_exported % the converse of pseudo_imported
% this means that only the (in, in) mode
% of a unification is exported
- ; local. % defined in the implementation of this module
+ ; exported_to_submodules
+ % defined in the implementation of this module,
+ % and thus in a sense local,
+ % but the module contains sub-modules,
+ % so the entity needs to be exported
+ % to those sub-modules
+ ; local. % defined in the implementation of this module,
+ % and the module does not contain any
+ % sub-modules.
+
+ % returns yes if the status indicates that the item was
+ % in any way exported -- that is, if it could be used
+ % by any other module, or by sub-modules of this module.
+:- pred status_is_exported(import_status::in, bool::out) is det.
+
+ % returns yes if the status indicates that the item was
+ % in any way imported -- that is, if it was defined in
+ % some other module, or in a sub-module of this module.
+ % This is the opposite of status_defined_in_this_module.
+:- pred status_is_imported(import_status::in, bool::out) is det.
+
+ % returns yes if the status indicates that the item was
+ % defined in this module. This is the opposite of
+ % status_is_imported.
+:- pred status_defined_in_this_module(import_status::in, bool::out) is det.
% N-ary functions are converted into N+1-ary predicates.
% (Clauses are converted in make_hlds, but calls to functions
@@ -388,10 +412,19 @@
:- pred pred_info_is_pseudo_imported(pred_info::in) is semidet.
+ % pred_info_is_exported does *not* include predicates which are
+ % exported_to_submodules or pseudo_exported
:- pred pred_info_is_exported(pred_info::in) is semidet.
+:- pred pred_info_is_exported_to_submodules(pred_info::in) is semidet.
+
:- pred pred_info_is_pseudo_exported(pred_info::in) is semidet.
+ % procedure_is_exported includes all modes of exported or
+ % exported_to_submodules predicates, plus the in-in mode
+ % for pseudo_exported unification predicates.
+:- pred procedure_is_exported(pred_info::in, proc_id::in) is semidet.
+
% Set the import_status of the predicate to `imported'.
% This is used for `:- external(foo/2).' declarations.
@@ -503,6 +536,30 @@
invalid_proc_id(-1).
+status_is_exported(imported, no).
+status_is_exported(abstract_imported, no).
+status_is_exported(pseudo_imported, no).
+status_is_exported(opt_imported, no).
+status_is_exported(exported, yes).
+status_is_exported(abstract_exported, yes).
+status_is_exported(pseudo_exported, yes).
+status_is_exported(exported_to_submodules, yes).
+status_is_exported(local, no).
+
+status_is_imported(Status, Imported) :-
+ status_defined_in_this_module(Status, InThisModule),
+ bool__not(InThisModule, Imported).
+
+status_defined_in_this_module(imported, no).
+status_defined_in_this_module(abstract_imported, no).
+status_defined_in_this_module(pseudo_imported, no).
+status_defined_in_this_module(opt_imported, no).
+status_defined_in_this_module(exported, yes).
+status_defined_in_this_module(abstract_exported, yes).
+status_defined_in_this_module(pseudo_exported, yes).
+status_defined_in_this_module(exported_to_submodules, yes).
+status_defined_in_this_module(local, yes).
+
% The information specific to a predicate, as opposed to a procedure.
% (Functions count as predicates.)
@@ -626,9 +683,15 @@
pred_info_exported_procids(PredInfo, ProcIds) :-
pred_info_import_status(PredInfo, ImportStatus),
- ( ImportStatus = exported ->
+ (
+ ( ImportStatus = exported
+ ; ImportStatus = exported_to_submodules
+ )
+ ->
pred_info_procids(PredInfo, ProcIds)
- ; ImportStatus = pseudo_exported ->
+ ;
+ ImportStatus = pseudo_exported
+ ->
ProcIds = [0]
;
ProcIds = []
@@ -699,9 +762,23 @@
pred_info_import_status(PredInfo, ImportStatus),
ImportStatus = exported.
+pred_info_is_exported_to_submodules(PredInfo) :-
+ pred_info_import_status(PredInfo, ImportStatus),
+ ImportStatus = exported_to_submodules.
+
pred_info_is_pseudo_exported(PredInfo) :-
pred_info_import_status(PredInfo, ImportStatus),
ImportStatus = pseudo_exported.
+
+procedure_is_exported(PredInfo, ProcId) :-
+ (
+ pred_info_is_exported(PredInfo)
+ ;
+ pred_info_is_exported_to_submodules(PredInfo)
+ ;
+ pred_info_is_pseudo_exported(PredInfo),
+ hlds_pred__in_in_unification_proc_id(ProcId)
+ ).
pred_info_mark_as_external(PredInfo0, PredInfo) :-
PredInfo0 = predicate(A, B, C, D, E, F, G, H, I, _, K, L, M, N, O, P,
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.60
diff -u -r1.60 intermod.m
--- intermod.m 1998/09/24 06:00:29 1.60
+++ intermod.m 1998/11/02 06:26:36
@@ -168,6 +168,11 @@
{ module_info_preds(ModuleInfo0, PredTable0) },
{ map__lookup(PredTable0, PredId, PredInfo0) },
(
+ %
+ % note: we can't include exported_to_submodules predicates
+ % in the `.opt' file, for reasons explained in
+ % the comments for intermod_info_add_proc
+ %
{ pred_info_is_exported(PredInfo0) },
{ pred_info_procids(PredInfo0, [ProcId | _ProcIds]) },
{ pred_info_procedures(PredInfo0, Procs) },
@@ -323,7 +328,7 @@
{ map__search(TypeTable, TypeId, TypeDefn) }
->
{ hlds_data__get_type_defn_status(TypeDefn, Status) },
- ( { Status = imported ; Status = abstract_imported } ->
+ ( { status_is_imported(Status, yes) } ->
{ type_util__type_id_module(ModuleInfo,
TypeId, Module) },
intermod_info_get_modules(Modules0),
@@ -481,8 +486,19 @@
{ Cases = Cases0 }
).
- % If a proc called within an exported proc is non-local, we need
- % to include an :- import_module declaration.
+ %
+ % intermod_info_add_proc/4 tries to do what ever is necessary to
+ % ensure that the specified predicate will be exported,
+ % so that it can be called from clauses in the `.opt' file.
+ % If it can't, then it returns DoWrite = no, which will
+ % prevent the caller from being included in the `.opt' file.
+ %
+ % If a proc called within an exported proc is local, we need
+ % to add a declaration for the called proc to the .opt file.
+ % If a proc called within an exported proc is from a different
+ % module, we need to include an `:- import_module' declaration
+ % to import that module in the `.opt' file.
+ %
:- pred intermod_info_add_proc(pred_id::in, bool::out,
intermod_info::in, intermod_info::out) is det.
@@ -493,52 +509,107 @@
{ pred_info_procids(PredInfo, ProcIds) },
{ pred_info_get_markers(PredInfo, Markers) },
(
- { check_marker(Markers, infer_modes) }
- ->
- % Don't write this pred if it calls preds without mode decls.
- { DoWrite = no }
- ;
- % Don't output declarations for compiler generated procedures,
- % since they will be recreated in the calling module.
+ %
+ % Calling compiler-generated procedures is fine;
+ % we don't need to output declarations for them to
+ % the `.opt' file, since they will be recreated every
+ % time anyway.
+ %
{ code_util__compiler_generated(PredInfo) }
->
{ DoWrite = yes }
;
+ %
+ % Don't write the caller to the `.opt' file if it calls
+ % a pred without mode or determinism decls, because we'd
+ % need to include the mode decls for the callee in the `.opt'
+ % file and (since writing the `.opt' file happens before mode
+ % inference) we can't do that because we don't know what
+ % the modes are.
+ %
+ % XXX This prevents intermodule optimizations in such cases,
+ % which is a pity.
+ %
{
- pred_info_procedures(PredInfo, Procs),
- list__member(ProcId, ProcIds),
- map__lookup(Procs, ProcId, ProcInfo),
- proc_info_declared_determinism(ProcInfo, no)
+ check_marker(Markers, infer_modes)
+ ;
+ pred_info_procedures(PredInfo, Procs),
+ list__member(ProcId, ProcIds),
+ map__lookup(Procs, ProcId, ProcInfo),
+ proc_info_declared_determinism(ProcInfo, no)
}
->
- % Don't write this pred if it calls preds
- % without determinism decls.
{ DoWrite = no }
;
+ %
+ % Don't write this pred if it is exported to submodules,
+ % because we don't know whether or not to write out the
+ % pred decl to the .opt file -- if we write it out, you
+ % can get spurious "duplicate declaration" errors when
+ % compiling the submodules, and if we don't, then you
+ % can get spurious "undeclared predicate" errors when
+ % compiling other modules which import the parent module.
+ %
+ % XXX This prevents intermodule optimization in those
+ % cases, which is a pity.
+ %
+ { Status = exported_to_submodules }
+ ->
+ { DoWrite = no }
+ ;
+ %
+ % If a pred whose code we're going to put in the `.opt' file
+ % calls a predicate which is local to that module, then
+ % we need to put the declaration for the called predicate
+ % in the `.opt' file.
+ %
{ Status = local }
->
+ { DoWrite = yes },
intermod_info_get_pred_decls(PredDecls0),
{ set__insert(PredDecls0, PredId, PredDecls) },
- intermod_info_set_pred_decls(PredDecls),
- { DoWrite = yes }
+ intermod_info_set_pred_decls(PredDecls)
;
- { Status = imported }
+ { Status = imported
+ ; Status = opt_imported
+ }
->
{ DoWrite = yes },
- { pred_info_module(PredInfo, Module) },
- ( { module_info_name(ModuleInfo, Module) } ->
- % :- external pred - add decl
+ { module_info_name(ModuleInfo, ThisModule) },
+ { pred_info_module(PredInfo, PredModule) },
+ (
+ { PredModule = ThisModule }
+ ->
+ %
+ % This can happen in the case of a local predicate
+ % which has been declared as external using a
+ % `:- external(Name/Arity)' declaration, e.g.
+ % because it is implemented as low-level C code.
+ %
+ % We treat these the same as local predicates.
+ %
intermod_info_get_pred_decls(PredDecls0),
{ set__insert(PredDecls0, PredId, PredDecls) },
intermod_info_set_pred_decls(PredDecls)
;
+ %
% imported pred - add import for module
+ %
intermod_info_get_modules(Modules0),
- { set__insert(Modules0, Module, Modules) },
+ { set__insert(Modules0, PredModule, Modules) },
intermod_info_set_modules(Modules)
)
;
+ %
+ % if a pred whose code we're going to put in the .opt file
+ % calls a predicate which is exported, then we don't
+ % need to do anything special
+ %
+ { Status = exported }
+ ->
{ DoWrite = yes }
+ ;
+ { error("intermod_info_add_proc: unexpected status") }
).
% Resolve overloading and module qualify everything in a unify_rhs.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.275
diff -u -r1.275 make_hlds.m
--- make_hlds.m 1998/09/24 09:44:36 1.275
+++ make_hlds.m 1998/10/29 12:41:37
@@ -464,6 +464,8 @@
item_status(exported, may_be_unqualified)).
module_defn_update_import_status(implementation,
item_status(local, may_be_unqualified)).
+module_defn_update_import_status(private_interface,
+ item_status(exported_to_submodules, may_be_unqualified)).
module_defn_update_import_status(imported,
item_status(imported, may_be_unqualified)).
module_defn_update_import_status(used,
@@ -1858,7 +1860,8 @@
(
{ MaybeDet = no }
->
- ( { pred_info_is_exported(PredInfo0) } ->
+ { pred_info_import_status(PredInfo0, ImportStatus) },
+ ( { status_is_exported(ImportStatus, yes) } ->
unspecified_det_for_exported(PredName, Arity,
PredOrFunc, MContext)
;
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.39
diff -u -r1.39 module_qual.m
--- module_qual.m 1998/08/07 00:49:17 1.39
+++ module_qual.m 1998/10/27 16:32:34
@@ -205,6 +205,8 @@
process_module_defn(include_module(_), Info, Info).
process_module_defn(interface, Info0, Info) :-
mq_info_set_import_status(Info0, exported, Info).
+process_module_defn(private_interface, Info0, Info) :-
+ mq_info_set_import_status(Info0, exported_to_submodules, Info).
process_module_defn(implementation, Info0, Info) :-
mq_info_set_import_status(Info0, local, Info).
process_module_defn(imported, Info0, Info) :-
@@ -363,6 +365,8 @@
mq_info_set_import_status(Info0, exported, Info).
update_import_status(implementation, Info0, Info, yes) :-
mq_info_set_import_status(Info0, local, Info).
+update_import_status(private_interface, Info0, Info, yes) :-
+ mq_info_set_import_status(Info0, exported_to_submodules, Info).
update_import_status(imported, Info, Info, no).
update_import_status(used, Info, Info, no).
update_import_status(external(_), Info, Info, yes).
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.87
diff -u -r1.87 modules.m
--- modules.m 1998/09/29 05:10:27 1.87
+++ modules.m 1998/10/28 09:23:07
@@ -991,15 +991,18 @@
PublicChildren, FactDeps, Module0) },
% If this module has any seperately-compiled sub-modules,
- % then we need to make everything in this module exported.
+ % then we need to make everything in this module
+ % exported_to_submodules. We do that by splitting
+ % out the declarations and putting them in a special
+ % `:- private_interface' section.
{ get_children(Items0, Children) },
{ Children = [] ->
Module1 = Module0
;
split_clauses_and_decls(Items0, Clauses, Decls),
- make_pseudo_decl(interface, InterfaceDecl),
+ make_pseudo_decl(private_interface, PrivateInterfaceDecl),
make_pseudo_decl(implementation, ImplementationDecl),
- list__append([InterfaceDecl | Decls],
+ list__append([PrivateInterfaceDecl | Decls],
[ImplementationDecl | Clauses], Items1),
module_imports_set_items(Module0, Items1, Module1)
},
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.40
diff -u -r1.40 prog_data.m
--- prog_data.m 1998/08/18 10:00:41 1.40
+++ prog_data.m 1998/10/27 16:32:38
@@ -543,6 +543,14 @@
; interface
; implementation
+ ; private_interface
+ % This is used internally by the compiler,
+ % to identify items which originally
+ % came from an implementation section
+ % for a module that contains sub-modules;
+ % such items need to be exported to the
+ % sub-modules.
+
; imported
% This is used internally by the compiler,
% to identify declarations which originally
Index: compiler/termination.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/termination.m,v
retrieving revision 1.16
diff -u -r1.16 termination.m
--- termination.m 1998/10/02 20:12:22 1.16
+++ termination.m 1998/10/27 16:32:44
@@ -390,10 +390,7 @@
->
ProcTable2 = ProcTable1
;
- ( ImportStatus = exported
- ; ImportStatus = local
- ; ImportStatus = pseudo_exported
- )
+ status_defined_in_this_module(ImportStatus, yes)
->
( check_marker(Markers, terminates) ->
change_procs_termination_info(ProcIds, yes,
@@ -402,11 +399,8 @@
ProcTable2 = ProcTable0
)
;
- ( ImportStatus = imported
- ; ImportStatus = opt_imported
- ; ImportStatus = pseudo_imported % should this be here?
- )
- ->
+ % Not defined in this module.
+
% All of the predicates that are processed in this section
% are imported in some way.
% With imported predicates, any 'check_termination'
@@ -435,13 +429,6 @@
ArgSizeInfo = infinite([Context - ArgSizeError]),
change_procs_arg_size_info(ProcIds, no, ArgSizeInfo,
ProcTable1, ProcTable2)
- ;
-% ( ImportStatus = abstract_imported
-% ; ImportStatus = abstract_exported
-% ),
- % This should not happen, as procedures are being processed
- % here, and these import_status' refer to abstract types.
- error("termination__check_preds: Unexpected import status")
),
( check_marker(Markers, does_not_terminate) ->
RequestError = Context - does_not_term_pragma(PredId),
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.53
diff -u -r1.53 unused_args.m
--- unused_args.m 1998/09/10 06:51:44 1.53
+++ unused_args.m 1998/10/29 13:13:54
@@ -1505,7 +1505,9 @@
write_unused_args_to_opt_file(no, _, _, _) --> [].
write_unused_args_to_opt_file(yes(OptStream), PredInfo, ProcId, UnusedArgs) -->
(
- { pred_info_is_exported(PredInfo) },
+ ( { pred_info_is_exported(PredInfo) }
+ ; { pred_info_is_exported_to_submodules(PredInfo) }
+ ),
{ UnusedArgs \= [] }
->
{ pred_info_module(PredInfo, Module) },
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.45
diff -u -r1.45 Mmakefile
--- Mmakefile 1998/10/23 18:40:39 1.45
+++ Mmakefile 1998/11/02 07:01:56
@@ -61,6 +61,7 @@
nested \
nested2 \
nested3 \
+ nested_intermod_main \
no_fully_strict \
no_inline \
nondet_ctrl_vn \
@@ -110,6 +111,8 @@
MCFLAGS-nondet_ctrl_vn = --optimize-value-number
MCFLAGS-rnd = -O6
MCFLAGS-bigtest = --intermodule-optimization -O3
+MCFLAGS-nested_intermod = --intermodule-optimization
+MCFLAGS-nested_intermod_main = --intermodule-optimization
# In grade `none' with options `-O1 --opt-space' on kryten
# (a sparc-sun-solaris2.5 system), mode_choice needs to be linked
Index: tests/hard_coded/nested_intermod.m
===================================================================
RCS file: nested_intermod.m
diff -N nested_intermod.m
--- /dev/null Mon Nov 2 18:14:52 1998
+++ nested_intermod.m Mon Nov 2 18:15:27 1998
@@ -0,0 +1,39 @@
+:- module nested_intermod.
+
+:- interface.
+
+:- import_module int.
+
+:- pred foo(int).
+:- mode foo(in) is semidet.
+
+ :- module sub.
+
+ :- interface.
+
+ :- pred fu(int).
+ :- mode fu(in) is semidet.
+ :- end_module sub.
+
+:- implementation.
+
+ :- module sub.
+ :- implementation.
+
+ fu(X) :-
+ X < 4.
+
+ :- end_module sub.
+
+:- pragma inline(foo/1).
+
+foo(X) :-
+ bar(X).
+
+:- pred bar(int).
+:- mode bar(in) is semidet.
+
+bar(X) :-
+ X > 3.
+
+:- end_module nested_intermod.
Index: tests/hard_coded/nested_intermod_main.exp
===================================================================
RCS file: nested_intermod_main.exp
diff -N nested_intermod_main.exp
--- /dev/null Mon Nov 2 18:14:52 1998
+++ nested_intermod_main.exp Mon Nov 2 18:04:07 1998
@@ -0,0 +1,5 @@
+X = 1: no
+X = 2: no
+X = 3: no
+X = 4: yes
+X = 5: yes
Index: tests/hard_coded/nested_intermod_main.m
===================================================================
RCS file: nested_intermod_main.m
diff -N nested_intermod_main.m
--- /dev/null Mon Nov 2 18:14:52 1998
+++ nested_intermod_main.m Mon Nov 2 18:00:31 1998
@@ -0,0 +1,34 @@
+:- module nested_intermod_main.
+:- interface.
+:- import_module io.
+
+:- pred xyzzy(int).
+:- mode xyzzy(in) is semidet.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module nested_intermod.
+
+main -->
+ test(1),
+ test(2),
+ test(3),
+ test(4),
+ test(5).
+
+:- pred test(int::in, io__state::di, io__state::uo) is det.
+
+test(X) -->
+ print("X = "), print(X), print(": "),
+ ( { xyzzy(X) } ->
+ print("yes")
+ ;
+ print("no")
+ ),
+ nl.
+
+xyzzy(X) :-
+ foo(X).
+
+:- end_module nested_intermod_main.
--
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