[m-rev.] for post-commit review: event goals

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Sep 5 14:27:32 AEST 2006


This diff is the first step in implementing trace events. It introduces the
representation of trace event goals into both the parse tree and HLDS
representations, and updates most compiler passes to handle them.
Changes to the code generator and to the runtime system, user-level
documentation and test cases will come later.

library/ops.m:
	Add "event" as an operator.

mdbcomp/program_representation.m:
	Extend the representation of goals to include events.

browser/declarative_execution.m:
	Allow the reconstruction from bytecode of event goals.

browser/declarative_tree.m:
	Extend the algorithm for following terms to their sources to allow
	it to traverse events (which never generate any values).

compiler/prog_item.m:
compiler/hlds_goal.m:
	Extend the parse tree and the HLDS representations to include event
	goals.

compiler/prog_io_goal.m:
	Convert the term representation of events to the parse tree
	representation.

compiler/add_clause.m:
	Convert the parse tree representation of events to the HLDS
	representation.

compiler/prog_event.m:
	Add this new module to contain the compiler's database of event types.

compiler/notes/compiler_design.html:
	Mention the new module.

compiler/parse_tree.m:
	Include the new module.

compiler/prog_rep.m:
	Generate the extended bytecode for event goals.

compiler/mercury_to_mercury.m:
	Output event goals.

compiler/typecheck.m:
	Typecheck event goals. The types of the arguments of each event type
	is given by the database in prog_event.m.

compiler/typecheck_errors.m:
	Add a predicate for reporting unknown events.

compiler/modecheck_call.m:
	Add a predicate to modecheck event goals. The modes of the arguments
	are also given by the database in prog_event.m.

compiler/modes.m:
	Call the new predicate in modecheck_call.m for event goals.

	Some predicates in this module took a boolean flag, tested many times
	at runtime, to control whether an exact match was required or not.
	However, the choice was fixed at all call sites except one. I have
	split each predicate into two, one for each value of the boolean flag,
	both for clarity of code and for slightly improved speed.

compiler/ml_call_gen.m:
	Ignore event goals, since the MLDS backend doesn't support debugging.

compiler/call_gen.m:
	Document the fact that event goals *should* be handled here.

compiler/build_mode_constraints.m:
compiler/deep_profiling.m:
compiler/exception_analysis.m:
compiler/goal_util.m:
compiler/hlds_out.m:
compiler/hlds_pred.m:
compiler/intermod.m:
compiler/mercury_to_mercury.m:
compiler/mlds_to_c.m:
compiler/mode_constraints.m:
compiler/modecheck_unify.m:
compiler/module_qual.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/simplify.m:
compiler/superhomogeneous.m:
compiler/tabling_analysis.m:
compiler/term_traversal.m:
compiler/trailing_analysis.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unique_modes.m:
	Handle the new goal type. In most cases the new code should be
	functional, but in a few cases (e.g. constraint based mode analysis
	and deep profiling) it just aborts the compiler.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
Index: browser/declarative_execution.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_execution.m,v
retrieving revision 1.53
diff -u -b -r1.53 declarative_execution.m
--- browser/declarative_execution.m	31 Aug 2006 11:09:48 -0000	1.53
+++ browser/declarative_execution.m	1 Sep 2006 02:08:13 -0000
@@ -1685,6 +1685,13 @@
             read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
                 Info, AtomicGoal, Goal)
         ;
+            GoalType = goal_event_call,
+            read_string(Bytecode, Label, !Pos, EventName),
+            read_vars(VarNumRep, Bytecode, !Pos, Args),
+            AtomicGoal = event_call_rep(EventName, Args),
+            read_atomic_info(VarNumRep, Bytecode, Label, !Pos,
+                Info, AtomicGoal, Goal)
+        ;
             GoalType = goal_foreign,
             read_vars(VarNumRep, Bytecode, !Pos, Args),
             AtomicGoal = pragma_foreign_code_rep(Args),
Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.45
diff -u -b -r1.45 declarative_tree.m
--- browser/declarative_tree.m	22 Aug 2006 05:03:30 -0000	1.45
+++ browser/declarative_tree.m	25 Aug 2006 03:45:34 -0000
@@ -1222,7 +1222,7 @@
             Primitives0)
     ;
         Goal = atomic_goal_rep(_, File, Line, BoundVars, AtomicGoal),
-        GeneratesEvent = atomic_goal_generates_event(AtomicGoal),
+        GeneratesEvent = atomic_goal_generates_event_like_call(AtomicGoal),
         (
             GeneratesEvent = yes(AtomicGoalArgs),
             MaybePrims = match_atomic_goal_to_contour_event(Store, File, Line,
@@ -1683,6 +1683,13 @@
         ;
             traverse_primitives(Prims, Var0, TermPath0, Store, ProcRep, Origin)
         )
+    ;
+        AtomicGoal = event_call_rep(_, _),
+        ( list.member(Var0, BoundVars) ->
+            throw(internal_error("traverse_primitives", "bad event"))
+        ;
+            traverse_primitives(Prims, Var0, TermPath0, Store, ProcRep, Origin)
+        )
     ).
 
     % Some foreign calls, such as casts, are handled specially
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/add_clause.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_clause.m,v
retrieving revision 1.30
diff -u -b -r1.30 add_clause.m
--- compiler/add_clause.m	30 Aug 2006 04:45:57 -0000	1.30
+++ compiler/add_clause.m	30 Aug 2006 22:38:11 -0000
@@ -63,13 +63,13 @@
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_rtti.
-:- import_module hlds.pred_table.
 :- import_module hlds.make_hlds.add_pragma.
 :- import_module hlds.make_hlds.add_pred.
 :- import_module hlds.make_hlds.field_access.
 :- import_module hlds.make_hlds.make_hlds_error.
 :- import_module hlds.make_hlds.make_hlds_warn.
 :- import_module hlds.make_hlds.superhomogeneous.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
@@ -78,6 +78,7 @@
 :- import_module parse_tree.module_qual.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_io_util.
+:- import_module parse_tree.prog_mode.
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_util.
 
@@ -736,6 +737,22 @@
     NumAdded = NumAddedP + NumAddedQ,
     Goal = shorthand(bi_implication(P, Q)) - GoalInfo,
     finish_equivalence(BeforeSInfo, !SInfo).
+transform_goal_2(event_expr(EventName, Args0), Context, Subst,
+        Goal,
+        NumAdded, !VarSet, !ModuleInfo, !QualInfo, !SInfo, !IO) :-
+    Args1 = expand_bang_state_var_args(Args0),
+    prepare_for_call(!SInfo),
+    term.apply_substitution_to_list(Args1, Subst, Args),
+    make_fresh_arg_vars(Args, HeadVars, !VarSet, !SInfo, !IO),
+    list.length(HeadVars, Arity),
+    list.duplicate(Arity, in_mode, Modes),
+    goal_info_init(Context, GoalInfo),
+    Details = event_call(EventName),
+    Goal0 = generic_call(Details, HeadVars, Modes, detism_det) - GoalInfo,
+    CallId = generic_call_id(gcid_event_call(EventName)),
+    insert_arg_unifications(HeadVars, Args, Context, ac_call(CallId),
+        Goal0, Goal, NumAdded, !VarSet, !ModuleInfo, !QualInfo, !SInfo, !IO),
+    finish_call(!VarSet, !SInfo).
 transform_goal_2(call_expr(Name, Args0, Purity), Context, Subst, Goal,
         NumAdded, !VarSet, !ModuleInfo, !QualInfo, !SInfo, !IO) :-
     Args1 = expand_bang_state_var_args(Args0),
@@ -785,7 +802,7 @@
 
             hlds_goal.generic_call_id(GenericCall, CallId)
         ;
-            % initialize some fields to junk
+            % Initialize some fields to junk.
             PredId = invalid_pred_id,
             ModeId = invalid_proc_id,
 
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.18
diff -u -b -r1.18 build_mode_constraints.m
--- compiler/build_mode_constraints.m	20 Aug 2006 08:20:52 -0000	1.18
+++ compiler/build_mode_constraints.m	25 Aug 2006 02:43:08 -0000
@@ -471,6 +471,11 @@
         Details = class_method(_, _, _, _),
         sorry(this_file, "class_method generic_call")
     ;
+        % XXX We need to impose the constraint that all the argument variables
+        % are bound elsewhere.
+        Details = event_call(_),
+        sorry(this_file, "event_call generic_call")
+    ;
         % No mode constraints
         Details = cast(_)
     ).
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.181
diff -u -b -r1.181 call_gen.m
--- compiler/call_gen.m	22 Aug 2006 05:03:38 -0000	1.181
+++ compiler/call_gen.m	5 Sep 2006 03:49:09 -0000
@@ -148,24 +148,32 @@
     % `cast' differs from the other generic call types in that there is no
     % address. Also, live_vars.m assumes that casts do not require live
     % variables to be saved to the stack.
-    ( GenericCall = cast(_) ->
+    (
+        ( GenericCall = higher_order(_, _, _, _)
+        ; GenericCall = class_method(_, _, _, _)
+        ),
+        generate_main_generic_call(OuterCodeModel, GenericCall, Args0, Modes0,
+            Det, GoalInfo, Code, !CI)
+    ;
+        GenericCall = event_call(_),
+        % XXX The code for handling events is not yet implemented.
+        Code = empty
+    ;
+        GenericCall = cast(_),
         ( Args0 = [InputArg, OutputArg] ->
             generate_assign_builtin(OutputArg, leaf(InputArg), Code, !CI)
         ;
             unexpected(this_file,
                 "generate_generic_call: invalid type/inst cast call")
         )
-    ;
-        generate_generic_call_2(OuterCodeModel, GenericCall, Args0, Modes0,
-            Det, GoalInfo, Code, !CI)
     ).
 
-:- pred generate_generic_call_2(code_model::in, generic_call::in,
+:- pred generate_main_generic_call(code_model::in, generic_call::in,
     list(prog_var)::in, list(mer_mode)::in, determinism::in,
     hlds_goal_info::in, code_tree::out, code_info::in, code_info::out)
     is det.
 
-generate_generic_call_2(_OuterCodeModel, GenericCall, Args, Modes, Det,
+generate_main_generic_call(_OuterCodeModel, GenericCall, Args, Modes, Det,
         GoalInfo, Code, !CI) :-
     Types = list.map(code_info.variable_type(!.CI), Args),
 
@@ -189,15 +197,14 @@
     list.append(SpecifierArgInfos, InVarArgInfos, InArgInfos),
     list.append(InArgInfos, OutArgsInfos, ArgInfos),
 
-        % Save the necessary vars on the stack and move the input args
-        % defined by variables to their registers.
+    % Save the necessary vars on the stack and move the input args defined
+    % by variables to their registers.
     code_info.setup_call(GoalInfo, ArgInfos, LiveVals0, SetupCode, !CI),
     kill_dead_input_vars(ArgInfos, GoalInfo, NonLiveOutputs, !CI),
 
-        % Move the input args not defined by variables to their
-        % registers. Setting up these arguments last results in
-        % slightly more efficient code, since we can use their
-        % registers when placing the variables.
+    % Move the input args not defined by variables to their registers.
+    % Setting up these arguments last results in slightly more efficient code,
+    % since we can use their registers when placing the variables.
     generic_call_nonvar_setup(GenericCall, HoCallVariant, InVars, OutVars,
         NonVarCode, !CI),
 
@@ -211,15 +218,13 @@
     goal_info_get_context(GoalInfo, Context),
     goal_info_get_goal_path(GoalInfo, GoalPath),
 
-        % Figure out what variables will be live at the return point,
-        % and where, for use in the accurate garbage collector, and
-        % in the debugger.
+    % Figure out what variables will be live at the return point, and where,
+    % for use in the accurate garbage collector, and in the debugger.
     code_info.get_instmap(!.CI, InstMap),
     goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
     instmap.apply_instmap_delta(InstMap, InstMapDelta, ReturnInstMap),
 
-        % Update the code generator state to reflect the situation
-        % after the call.
+    % Update the code generator state to reflect the situation after the call.
     handle_return(OutArgsInfos, GoalInfo, NonLiveOutputs,
         ReturnInstMap, ReturnLiveLvalues, !CI),
 
@@ -230,8 +235,7 @@
         label(ReturnLabel) - "Continuation label"
     ]),
 
-        % If the call can fail, generate code to check for and
-        % handle the failure.
+    % If the call can fail, generate code to check for and handle the failure.
     handle_failure(CodeModel, GoalInfo, FailHandlingCode, !CI),
 
     Code = tree_list([SetupCode, NonVarCode, TraceCode, CallCode,
@@ -294,8 +298,10 @@
             FirstImmediateInputReg = 4
         )
     ;
-        % Casts are generated inline.
-        GenericCall = cast(_),
+        % Events and casts are generated inline.
+        ( GenericCall = event_call(_)
+        ; GenericCall = cast(_)
+        ),
         CodeAddr = do_not_reached,
         SpecifierArgInfos = [],
         FirstImmediateInputReg = 1,
@@ -352,6 +358,8 @@
                 "Assign number of immediate input arguments"
         ])
     ).
+generic_call_nonvar_setup(event_call(_), _, _, _, _, !CI) :-
+    unexpected(this_file, "generic_call_nonvar_setup: event_call").
 generic_call_nonvar_setup(cast(_), _, _, _, _, !CI) :-
     unexpected(this_file, "generic_call_nonvar_setup: cast").
 
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.54
diff -u -b -r1.54 deep_profiling.m
--- compiler/deep_profiling.m	22 Aug 2006 05:03:41 -0000	1.54
+++ compiler/deep_profiling.m	25 Aug 2006 03:11:02 -0000
@@ -1020,6 +1020,10 @@
         wrap_call(Path, Goal0 - GoalInfo0, GoalAndInfo, !DeepInfo),
         AddedImpurity = yes
     ;
+        GenericCall = event_call(_),
+        GoalAndInfo = Goal0 - GoalInfo0,
+        AddedImpurity = no
+    ;
         GenericCall = cast(_),
         GoalAndInfo = Goal0 - GoalInfo0,
         AddedImpurity = no
@@ -1168,6 +1172,9 @@
             ]) - PrepareCallGoalInfo,
             CallSite = method_call(FileName, LineNumber, GoalPath)
         ;
+            Generic = event_call(_),
+            unexpected(this_file, "deep_profiling.wrap_call: event_call")
+        ;
             Generic = cast(_),
             unexpected(this_file, "deep_profiling.wrap_call: cast")
         ),
Index: compiler/exception_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exception_analysis.m,v
retrieving revision 1.32
diff -u -b -r1.32 exception_analysis.m
--- compiler/exception_analysis.m	22 Aug 2006 05:03:43 -0000	1.32
+++ compiler/exception_analysis.m	25 Aug 2006 03:11:26 -0000
@@ -483,6 +483,8 @@
         Details = class_method(_, _, _, _),
         !:Result = !.Result ^ status := may_throw(user_exception)
     ;
+        Details = event_call(_)
+    ;
         Details = cast(_)
     ).
 check_goal_for_exceptions_2(SCC, VarTypes, negation(Goal), _,
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.136
diff -u -b -r1.136 goal_util.m
--- compiler/goal_util.m	20 Aug 2006 08:21:07 -0000	1.136
+++ compiler/goal_util.m	25 Aug 2006 03:19:43 -0000
@@ -336,14 +336,14 @@
 
     % Generate a cast goal.  The input and output insts are just ground.
     %
-:- pred generate_cast(cast_type::in, prog_var::in, prog_var::in,
+:- pred generate_cast(cast_kind::in, prog_var::in, prog_var::in,
     prog_context::in, hlds_goal::out) is det.
 
     % This version takes input and output inst arguments, which may
     % be necessary when casting, say, solver type values with inst
     % any, or casting between enumeration types and ints.
     %
-:- pred generate_cast(cast_type::in, prog_var::in, prog_var::in,
+:- pred generate_cast(cast_kind::in, prog_var::in, prog_var::in,
     mer_inst::in, mer_inst::in, prog_context::in, hlds_goal::out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -719,7 +719,8 @@
         class_method(Var0, Method, ClassId, MethodId),
         class_method(Var, Method, ClassId, MethodId)) :-
     rename_var(Must, Subn, Var0, Var).
-rename_generic_call(_, _, cast(CastType), cast(CastType)).
+rename_generic_call(_, _, event_call(EventName), event_call(EventName)).
+rename_generic_call(_, _, cast(CastKind), cast(CastKind)).
 
 %-----------------------------------------------------------------------------%
 
@@ -890,6 +891,7 @@
 
 generic_call_vars(higher_order(Var, _, _, _), [Var]).
 generic_call_vars(class_method(Var, _, _, _), [Var]).
+generic_call_vars(event_call(_), []).
 generic_call_vars(cast(_), []).
 
 %-----------------------------------------------------------------------------%
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.166
diff -u -b -r1.166 hlds_goal.m
--- compiler/hlds_goal.m	22 Aug 2006 05:03:46 -0000	1.166
+++ compiler/hlds_goal.m	25 Aug 2006 02:23:10 -0000
@@ -407,27 +407,39 @@
 
 :- type generic_call
     --->    higher_order(
-                prog_var,
-                purity,
-                pred_or_func,   % call/N (pred) or apply/N (func)
-                arity           % number of arguments (including the
+                ho_call_var     :: prog_var,
+                ho_call_purity  :: purity,
+                ho_call_kind    :: pred_or_func,
+                                % call/N (pred) or apply/N (func)
+                ho_call_arity   :: arity
+                                % number of arguments (including the
                                 % higher-order term)
             )
 
     ;       class_method(
-                prog_var,       % typeclass_info for the instance
-                int,            % number of the called method
-                class_id,       % name and arity of the class
-                simple_call_id  % name of the called method
+                method_tci      :: prog_var,
+                                % typeclass_info for the instance
+                method_num      :: int,
+                                % number of the called method
+                method_class_id :: class_id,
+                                % name and arity of the class
+                method_name     :: simple_call_id
+                                % name of the called method
+            )
+
+    ;       event_call(
+                event_name      :: string 
             )
 
-    ;       cast(cast_type).
+    ;       cast(
+                cast_kind       :: cast_kind
             % cast(Input, Output): Assigns `Input' to `Output', performing
             % a type and/or inst cast.
+            ).
 
     % The various kinds of casts that we can do.
     %
-:- type cast_type
+:- type cast_kind
     --->    unsafe_type_cast
             % An unsafe type cast between ground values.
 
@@ -1476,11 +1488,14 @@
         generic_call_id(gcid_higher_order(Purity, PorF, Arity))).
 generic_call_id(class_method(_, _, ClassId, MethodId),
         generic_call_id(gcid_class_method(ClassId, MethodId))).
+generic_call_id(event_call(EventName),
+        generic_call_id(gcid_event_call(EventName))).
 generic_call_id(cast(CastType), generic_call_id(gcid_cast(CastType))).
 
 generic_call_pred_or_func(higher_order(_, _, PredOrFunc, _)) = PredOrFunc.
 generic_call_pred_or_func(class_method(_, _, _, CallId)) =
     simple_call_id_pred_or_func(CallId).
+generic_call_pred_or_func(event_call(_)) = predicate.
 generic_call_pred_or_func(cast(_)) = predicate.
 
 :- func simple_call_id_pred_or_func(simple_call_id) = pred_or_func.
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.400
diff -u -b -r1.400 hlds_out.m
--- compiler/hlds_out.m	30 Aug 2006 04:45:58 -0000	1.400
+++ compiler/hlds_out.m	30 Aug 2006 22:38:11 -0000
@@ -433,10 +433,12 @@
     ++ prog_out.pred_or_func_to_full_str(PredOrFunc) ++ " call".
 generic_call_id_to_string(gcid_class_method(_ClassId, MethodId)) =
     simple_call_id_to_string(MethodId).
+generic_call_id_to_string(gcid_event_call(EventName)) =
+    "event " ++ EventName.
 generic_call_id_to_string(gcid_cast(CastType)) =
     cast_type_to_string(CastType).
 
-:- func cast_type_to_string(cast_type) = string.
+:- func cast_type_to_string(cast_kind) = string.
 
 cast_type_to_string(unsafe_type_cast) = "unsafe_type_cast".
 cast_type_to_string(unsafe_type_inst_cast) = "unsafe_type_inst_cast".
@@ -524,6 +526,8 @@
     ).
 arg_number_to_string(generic_call_id(gcid_class_method(_, _)), ArgNum) =
     "argument " ++ int_to_string(ArgNum).
+arg_number_to_string(generic_call_id(gcid_event_call(_)), ArgNum) =
+    "argument " ++ int_to_string(ArgNum).
 arg_number_to_string(generic_call_id(gcid_cast(_)), ArgNum) =
     "argument " ++ int_to_string(ArgNum).
 
@@ -1770,6 +1774,22 @@
         mercury_output_term(Term, VarSet, AppendVarNums, !IO),
         io.write_string(Follow, !IO)
     ;
+        GenericCall = event_call(EventName),
+        globals.io_lookup_string_option(dump_hlds_options, Verbose, !IO),
+        ( string.contains_char(Verbose, 'l') ->
+            write_indent(Indent, !IO),
+            io.write_string("% event call\n", !IO)
+        ;
+            true
+        ),
+        term.context_init(Context),
+        Functor = term.atom(EventName),
+        term.var_list_to_term_list(ArgVars, ArgTerms),
+        Term = term.functor(Functor, ArgTerms, Context),
+        write_indent(Indent, !IO),
+        mercury_output_term(Term, VarSet, AppendVarNums, !IO),
+        io.write_string(Follow, !IO)
+    ;
         GenericCall = cast(CastType),
         CastTypeString = cast_type_to_string(CastType),
         globals.io_lookup_string_option(dump_hlds_options, Verbose, !IO),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.208
diff -u -b -r1.208 hlds_pred.m
--- compiler/hlds_pred.m	30 Aug 2006 04:45:59 -0000	1.208
+++ compiler/hlds_pred.m	30 Aug 2006 22:38:11 -0000
@@ -139,7 +139,8 @@
 :- type generic_call_id
     --->    gcid_higher_order(purity, pred_or_func, arity)
     ;       gcid_class_method(class_id, simple_call_id)
-    ;       gcid_cast(cast_type).
+    ;       gcid_event_call(string)
+    ;       gcid_cast(cast_kind).
 
 :- type pred_proc_list  ==  list(pred_proc_id).
 
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.206
diff -u -b -r1.206 intermod.m
--- compiler/intermod.m	30 Aug 2006 04:45:59 -0000	1.206
+++ compiler/intermod.m	30 Aug 2006 22:38:12 -0000
@@ -490,9 +490,15 @@
     add_proc(PredId, DoWrite, !Info).
 traverse_goal(Goal @ generic_call(CallType, _, _, _) - Info,
         Goal - Info, DoWrite, !Info) :-
-    ( CallType = higher_order(_, _, _, _), DoWrite = yes
-    ; CallType = class_method(_, _, _, _), DoWrite = no
-    ; CallType = cast(_), DoWrite = no
+    (
+        CallType = higher_order(_, _, _, _),
+        DoWrite = yes
+    ;
+        ( CallType = class_method(_, _, _, _)
+        ; CallType = event_call(_)
+        ; CallType = cast(_)
+        ),
+        DoWrite = no
     ).
 traverse_goal(switch(Var, CanFail, Cases0) - Info,
         switch(Var, CanFail, Cases) - Info, DoWrite, !Info) :-
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.299
diff -u -b -r1.299 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	30 Aug 2006 04:46:00 -0000	1.299
+++ compiler/mercury_to_mercury.m	30 Aug 2006 22:38:12 -0000
@@ -2764,7 +2764,7 @@
 mercury_output_goal_2(Expr, VarSet, Indent, !IO) :-
     Expr = trace_expr(MaybeCompileTime, MaybeRunTime, MaybeIO, MutableVars,
         Goal),
-    Indent1 = Indent + 1,
+    mercury_output_newline(Indent, !IO),
     io.write_string("trace [", !IO),
     some [!NeedComma] (
         !:NeedComma = no,
@@ -2799,8 +2799,8 @@
             MutableVars, !.NeedComma, _, !IO)
     ),
     io.write_string("]", !IO),
-    mercury_output_newline(Indent1, !IO),
-    mercury_output_goal(Goal, VarSet, Indent1, !IO),
+    mercury_output_newline(Indent + 1, !IO),
+    mercury_output_goal(Goal, VarSet, Indent + 1, !IO),
     mercury_output_newline(Indent, !IO),
     io.write_string(")", !IO).
 
@@ -2854,9 +2854,13 @@
     mercury_output_newline(Indent, !IO),
     io.write_string(")", !IO).
 
-mercury_output_goal_2(call_expr(Name, Term, Purity), VarSet, Indent, !IO) :-
+mercury_output_goal_2(event_expr(Name, Terms), VarSet, Indent, !IO) :-
+    io.write_string("event ", !IO),
+    mercury_output_call(unqualified(Name), Terms, VarSet, Indent, !IO).
+
+mercury_output_goal_2(call_expr(Name, Terms, Purity), VarSet, Indent, !IO) :-
     write_purity_prefix(Purity, !IO),
-    mercury_output_call(Name, Term, VarSet, Indent, !IO).
+    mercury_output_call(Name, Terms, VarSet, Indent, !IO).
 
 mercury_output_goal_2(unify_expr(A, B, Purity), VarSet, _Indent, !IO) :-
     write_purity_prefix(Purity, !IO),
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.73
diff -u -b -r1.73 ml_call_gen.m
--- compiler/ml_call_gen.m	22 Aug 2006 05:03:53 -0000	1.73
+++ compiler/ml_call_gen.m	25 Aug 2006 03:52:42 -0000
@@ -149,22 +149,27 @@
     % boxing/unboxing of the arguments.
 ml_gen_generic_call(higher_order(_, _, _, _) @ GenericCall, ArgVars, ArgModes,
         Determinism, Context, Decls, Statements, !Info) :-
-    ml_gen_generic_call_2(GenericCall, ArgVars, ArgModes, Determinism,
+    ml_gen_main_generic_call(GenericCall, ArgVars, ArgModes, Determinism,
         Context, Decls, Statements, !Info).
 ml_gen_generic_call(class_method(_, _, _, _) @ GenericCall, ArgVars, ArgModes,
         Determinism, Context, Decls, Statements, !Info) :-
-    ml_gen_generic_call_2(GenericCall, ArgVars, ArgModes, Determinism,
+    ml_gen_main_generic_call(GenericCall, ArgVars, ArgModes, Determinism,
         Context, Decls, Statements, !Info).
+ml_gen_generic_call(event_call(_), _ArgVars, _ArgModes, _Determinism, _Context,
+        Decls, Statements, !Info) :-
+    % XXX For now, we can't generate events from the MLDS backend.
+    Decls = [],
+    Statements = [].
 ml_gen_generic_call(cast(_), ArgVars, _ArgModes, _Determinism, Context,
         Decls, Statements, !Info) :-
     ml_gen_cast(Context, ArgVars, Decls, Statements, !Info).
 
-:- pred ml_gen_generic_call_2(generic_call::in, list(prog_var)::in,
+:- pred ml_gen_main_generic_call(generic_call::in, list(prog_var)::in,
     list(mer_mode)::in, determinism::in, prog_context::in,
     mlds_defns::out, statements::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_generic_call_2(GenericCall, ArgVars, ArgModes, Determinism, Context,
+ml_gen_main_generic_call(GenericCall, ArgVars, ArgModes, Determinism, Context,
         Decls, Statements, !Info) :-
     % Allocate some fresh type variables to use as the Mercury types
     % of the boxed arguments.
@@ -230,8 +235,11 @@
         FuncType = mlds_func_type(Params),
         FuncRval = unop(unbox(FuncType), lval(FuncLval))
     ;
+        GenericCall = event_call(_),
+        unexpected(this_file, "ml_gen_main_generic_call: event_call")
+    ;
         GenericCall = cast(_),
-        unexpected(this_file, "ml_gen_generic_call_2: cast")
+        unexpected(this_file, "ml_gen_main_generic_call: cast")
     ),
 
     % Assign the function address rval to a new local variable. This makes
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.197
diff -u -b -r1.197 mlds_to_c.m
--- compiler/mlds_to_c.m	22 Aug 2006 05:03:57 -0000	1.197
+++ compiler/mlds_to_c.m	29 Aug 2006 03:14:02 -0000
@@ -1367,7 +1367,6 @@
     ;
         DefnBody = mlds_function(MaybePredProcId, Signature,
             MaybeBody, _Attributes, _EnvVarNames),
-        % ZZZ
         mlds_output_maybe(MaybePredProcId, mlds_output_pred_proc_id, !IO),
         mlds_output_func(Indent, Name, Context, Signature, MaybeBody, !IO)
     ;
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.33
diff -u -b -r1.33 mode_constraints.m
--- compiler/mode_constraints.m	20 Aug 2006 08:21:19 -0000	1.33
+++ compiler/mode_constraints.m	25 Aug 2006 02:43:30 -0000
@@ -1331,6 +1331,9 @@
         generic_call_constrain_var(Var, GoalPath, !Constraint, !GCInfo),
         unexpected(this_file, "class_method call in clause")
     ;
+        GenericCall = event_call(_),
+        sorry(this_file, "event_call NYI")
+    ;
         GenericCall = cast(_),
         sorry(this_file, "type/inst cast call NYI")
     ).
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_call.m,v
retrieving revision 1.73
diff -u -b -r1.73 modecheck_call.m
--- compiler/modecheck_call.m	20 Aug 2006 08:21:20 -0000	1.73
+++ compiler/modecheck_call.m	29 Aug 2006 02:27:22 -0000
@@ -45,6 +45,10 @@
     determinism::out, extra_goals::out,
     mode_info::in, mode_info::out) is det.
 
+:- pred modecheck_event_call(list(mer_mode)::in,
+    list(prog_var)::in, list(prog_var)::out,
+    mode_info::in, mode_info::out) is det.
+
 :- pred modecheck_builtin_cast(list(mer_mode)::in,
     list(prog_var)::in, list(prog_var)::out, determinism::out,
     extra_goals::out, mode_info::in, mode_info::out) is det.
@@ -145,9 +149,8 @@
         % expected livenesses.
         %
         proc_info_arglives(ProcInfo, ModuleInfo, ProcArgLives0),
-        NeedExactMatch = no,
-        modecheck_var_list_is_live(ArgVars0, ProcArgLives0,
-            NeedExactMatch, ArgOffset, !ModeInfo),
+        modecheck_var_list_is_live_no_exact_match(ArgVars0, ProcArgLives0,
+            ArgOffset, !ModeInfo),
 
         % Check that `ArgsVars0' have insts which match the expected
         % initial insts, and set their new final insts (introducing
@@ -159,8 +162,8 @@
         rename_apart_inst_vars(InstVarSet, ProcInstVarSet,
             ProcArgModes0, ProcArgModes),
         mode_list_get_initial_insts(ModuleInfo, ProcArgModes, InitialInsts),
-        modecheck_var_has_inst_list(ArgVars0, InitialInsts,
-            NeedExactMatch, ArgOffset, InstVarSub, !ModeInfo),
+        modecheck_var_has_inst_list_no_exact_match(ArgVars0, InitialInsts,
+            ArgOffset, InstVarSub, !ModeInfo),
 
         modecheck_end_of_call(ProcInfo, Purity, ProcArgModes, ArgVars0,
             ArgOffset, InstVarSub, ArgVars, ExtraGoals, !ModeInfo)
@@ -210,13 +213,10 @@
         mode_info_set_errors(Errors, !ModeInfo)
     ).
 
-
 modecheck_higher_order_call(PredOrFunc, PredVar, Args0, Args, Modes, Det,
         ExtraGoals, !ModeInfo) :-
-    %
     % First, check that `PredVar' has a higher-order pred inst
-    % (of the appropriate arity)
-    %
+    % (of the appropriate arity).
     mode_info_get_instmap(!.ModeInfo, InstMap0),
     instmap.lookup_var(InstMap0, PredVar, PredVarInst0),
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
@@ -227,9 +227,8 @@
         (
             GroundInstInfo = higher_order(PredInstInfo)
         ;
-            % If PredVar has no higher-order inst
-            % information, but is a function type, then
-            % assume the default function mode.
+            % If PredVar has no higher-order inst information, but is
+            % a function type, then assume the default function mode.
             GroundInstInfo = none,
             mode_info_get_var_types(!.ModeInfo, VarTypes),
             map.lookup(VarTypes, PredVar, Type),
@@ -237,11 +236,11 @@
             PredInstInfo = pred_inst_info_standard_func_mode(
                 list.length(ArgTypes))
         ),
-        PredInstInfo = pred_inst_info(PredOrFunc, Modes0, Det0),
-        list.length(Modes0, Arity)
+        PredInstInfo = pred_inst_info(PredOrFunc, ModesPrime, DetPrime),
+        list.length(ModesPrime, Arity)
     ->
-        Det = Det0,
-        Modes = Modes0,
+        Det = DetPrime,
+        Modes = ModesPrime,
         ArgOffset = 1,
         modecheck_arg_list(ArgOffset, Modes, ExtraGoals, Args0, Args,
             !ModeInfo),
@@ -253,7 +252,7 @@
             true
         )
     ;
-        % the error occurred in argument 1, i.e. the pred term
+        % The error occurred in argument 1, i.e. the pred term.
         mode_info_set_call_arg_context(1, !ModeInfo),
         set.singleton_set(WaitingVars, PredVar),
         mode_info_error(WaitingVars,
@@ -266,6 +265,12 @@
         ExtraGoals = no_extra_goals
     ).
 
+modecheck_event_call(Modes, Args0, Args, !ModeInfo) :-
+    ArgOffset = 0,
+    modecheck_arg_list(ArgOffset, Modes, ExtraGoals, Args0, Args, !ModeInfo),
+    expect(unify(ExtraGoals, no_extra_goals), this_file,
+        "modecheck_event_call: ExtraGoals").
+
 modecheck_builtin_cast(Modes, Args0, Args, Det, ExtraGoals, !ModeInfo) :-
     Det = detism_det,
     % These should always be mode correct.
@@ -279,23 +284,17 @@
     is det.
 
 modecheck_arg_list(ArgOffset, Modes, ExtraGoals, Args0, Args, !ModeInfo) :-
-    %
-    % Check that `Args0' have livenesses which match the
-    % expected livenesses.
-    %
+    % Check that `Args0' have livenesses which match the expected livenesses.
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
     get_arg_lives(ModuleInfo0, Modes, ExpectedArgLives),
-    NeedExactMatch = no,
-    modecheck_var_list_is_live(Args0, ExpectedArgLives, NeedExactMatch,
+    modecheck_var_list_is_live_no_exact_match(Args0, ExpectedArgLives,
         ArgOffset, !ModeInfo),
 
-    %
-    % Check that `Args0' have insts which match the expected
-    % initial insts, and set their new final insts (introducing
-    % extra unifications for implied modes, if necessary).
-    %
+    % Check that `Args0' have insts which match the expected initial insts,
+    % and set their new final insts (introducing extra unifications for
+    % implied modes, if necessary).
     mode_list_get_initial_insts(ModuleInfo0, Modes, InitialInsts),
-    modecheck_var_has_inst_list(Args0, InitialInsts, NeedExactMatch,
+    modecheck_var_has_inst_list_no_exact_match(Args0, InitialInsts,
         ArgOffset, InstVarSub, !ModeInfo),
     mode_list_get_final_insts(ModuleInfo0, Modes, FinalInsts0),
     inst_list_apply_substitution(InstVarSub, FinalInsts0, FinalInsts),
@@ -322,7 +321,7 @@
     ( check_marker(Markers, marker_infer_modes) ->
         insert_new_mode(PredId, ArgVars, DeterminismKnown, TheProcId,
             !ModeInfo),
-        % we don't yet know the final insts for the newly created mode
+        % We don't yet know the final insts for the newly created mode
         % of the called predicate, so we set the instmap to unreachable,
         % indicating that we have no information about the modes at this
         % point in the computation.
@@ -337,7 +336,8 @@
             mode_error_no_matching_mode(ArgVars, ArgInsts), !ModeInfo)
     ).
 
-:- type proc_mode ---> proc_mode(proc_id, inst_var_sub, list(mer_mode)).
+:- type proc_mode
+    --->    proc_mode(proc_id, inst_var_sub, list(mer_mode)).
 
 :- pred modecheck_find_matching_modes(list(proc_id)::in, pred_id::in,
     proc_table::in, list(prog_var)::in, list(proc_mode)::in,
@@ -361,29 +361,29 @@
     proc_info_arglives(ProcInfo, ModuleInfo, ProcArgLives0),
 
     % Check whether the livenesses of the args matches their expected liveness.
-    NeedLivenessExactMatch = no,
-    modecheck_var_list_is_live(ArgVars0, ProcArgLives0,
-        NeedLivenessExactMatch, 0, !ModeInfo),
+    modecheck_var_list_is_live_no_exact_match(ArgVars0, ProcArgLives0, 0,
+        !ModeInfo),
 
+    % Check whether the insts of the args matches their expected initial insts.
+    %
         % If we're doing mode inference for the called procedure, and the
-        % called procedure has been inferred as an invalid mode, then
-        % don't use it unless it is an exact match.
+    % called procedure has been inferred as an invalid mode, then don't use
+    % it unless it is an exact match.
         %
         % XXX Do we really want mode inference to use implied modes?
-        % Would it be better to always require an exact match when
-        % doing mode inference, to ensure that we add new inferred
-        % modes rather than using implied modes?
+    % Would it be better to always require an exact match when doing mode
+    % inference, to ensure that we add new inferred modes rather than using
+    % implied modes?
+
+    mode_list_get_initial_insts(ModuleInfo, ProcArgModes, InitialInsts),
     ( proc_info_is_valid_mode(ProcInfo) ->
-        NeedExactMatch = no
+        modecheck_var_has_inst_list_no_exact_match(ArgVars0, InitialInsts, 0,
+            InstVarSub, !ModeInfo)
     ;
-        NeedExactMatch = yes
+        modecheck_var_has_inst_list_exact_match(ArgVars0, InitialInsts, 0,
+            InstVarSub, !ModeInfo)
     ),
 
-    % Check whether the insts of the args matches their expected initial insts.
-    mode_list_get_initial_insts(ModuleInfo, ProcArgModes, InitialInsts),
-    modecheck_var_has_inst_list(ArgVars0, InitialInsts, NeedExactMatch, 0,
-        InstVarSub, !ModeInfo),
-
     % If we got an error, reset the error list and save the list of vars
     % to wait on. Otherwise, insert the proc_id in the list of matching
     % proc_ids.
Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.109
diff -u -b -r1.109 modecheck_unify.m
--- compiler/modecheck_unify.m	22 Aug 2006 05:03:59 -0000	1.109
+++ compiler/modecheck_unify.m	25 Aug 2006 04:01:25 -0000
@@ -1069,10 +1069,9 @@
         list.length(UnifyTypeInfoVars, NumTypeInfoVars),
         list.duplicate(NumTypeInfoVars, ground(shared, none), ExpectedInsts),
         mode_info_set_call_context(call_context_unify(UnifyContext), !ModeInfo),
-        NeedExactMatch = no,
         InitialArgNum = 0,
-        modecheck_var_has_inst_list(UnifyTypeInfoVars, ExpectedInsts,
-            NeedExactMatch, InitialArgNum, _InstVarSub, !ModeInfo),
+        modecheck_var_has_inst_list_no_exact_match(UnifyTypeInfoVars,
+            ExpectedInsts, InitialArgNum, _InstVarSub, !ModeInfo),
             % we can ignore _InstVarSub since type_info variables
             % should not have variable insts.
         mode_info_unset_call_context(!ModeInfo)
@@ -1333,10 +1332,9 @@
     ->
         mode_info_set_call_context(call_context_unify(UnifyContext),
             !ModeInfo),
-        NeedExactMatch = no,
         InitialArgNum = 0,
-        modecheck_var_has_inst_list([ArgVar], [ground(shared, none)],
-            NeedExactMatch, InitialArgNum, _InstVarSub, !ModeInfo),
+        modecheck_var_has_inst_list_no_exact_match([ArgVar],
+            [ground(shared, none)], InitialArgNum, _InstVarSub, !ModeInfo),
         check_type_info_args_are_ground(ArgVars, VarTypes, UnifyContext,
             !ModeInfo),
         mode_info_unset_call_context(!ModeInfo)
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.341
diff -u -b -r1.341 modes.m
--- compiler/modes.m	22 Aug 2006 05:03:59 -0000	1.341
+++ compiler/modes.m	29 Aug 2006 02:34:23 -0000
@@ -210,20 +210,24 @@
 
     % Given a list of variables and a list of expected liveness, ensure
     % that the inst of each variable satisfies the corresponding expected
-    % liveness.  If the bool argument is `yes', then require an exact
-    % match.
+    % liveness.  If the bool argument is `yes', then require an exact match.
     %
-:- pred modecheck_var_list_is_live(list(prog_var)::in, list(is_live)::in,
-    bool::in, int::in, mode_info::in, mode_info::out) is det.
+:- pred modecheck_var_list_is_live_exact_match(list(prog_var)::in,
+    list(is_live)::in, int::in, mode_info::in, mode_info::out) is det.
+:- pred modecheck_var_list_is_live_no_exact_match(list(prog_var)::in,
+    list(is_live)::in, int::in, mode_info::in, mode_info::out) is det.
 
-    % Given a list of variables and a list of initial insts, ensure
-    % that the inst of each variable matches the corresponding initial
-    % inst.  If the bool argument is `yes', then we require an exact
-    % match (using inst_matches_final), otherwise we allow the var
-    % to be more instantiated than the inst (using inst_matches_initial).
+    % Given a list of variables and a list of initial insts, ensure that
+    % the inst of each variable matches the corresponding initial inst.
+    % If the bool argument is `yes', then we require an exact match
+    % (using inst_matches_final), otherwise we allow the var to be more
+    % instantiated than the inst (using inst_matches_initial).
     %
-:- pred modecheck_var_has_inst_list(list(prog_var)::in, list(mer_inst)::in,
-    bool::in, int::in, inst_var_sub::out,
+:- pred modecheck_var_has_inst_list_exact_match(list(prog_var)::in,
+    list(mer_inst)::in, int::in, inst_var_sub::out,
+    mode_info::in, mode_info::out) is det.
+:- pred modecheck_var_has_inst_list_no_exact_match(list(prog_var)::in,
+    list(mer_inst)::in, int::in, inst_var_sub::out,
     mode_info::in, mode_info::out) is det.
 
     % modecheck_set_var_inst(Var, Inst, MaybeUInst, ModeInfo0, ModeInfo):
@@ -324,8 +328,8 @@
     extra_goals::out) is det.
 
     % Handle_extra_goals combines MainGoal and ExtraGoals into a single
-    % hlds_goal_expr, rerunning mode analysis on the entire
-    % conjunction if ExtraGoals is not empty.
+    % hlds_goal_expr, rerunning mode analysis on the entire conjunction
+    % if ExtraGoals is not empty.
     %
 :- pred handle_extra_goals(hlds_goal_expr::in, extra_goals::in,
     hlds_goal_info::in, list(prog_var)::in, list(prog_var)::in,
@@ -355,15 +359,15 @@
 :- import_module check_hlds.delay_info.
 :- import_module check_hlds.inst_match.
 :- import_module check_hlds.inst_util.
-:- import_module check_hlds.modecheck_call.
-:- import_module check_hlds.modecheck_unify.
 :- import_module check_hlds.mode_debug.
 :- import_module check_hlds.mode_errors.
 :- import_module check_hlds.mode_util.
+:- import_module check_hlds.modecheck_call.
+:- import_module check_hlds.modecheck_unify.
 :- import_module check_hlds.polymorphism.
 :- import_module check_hlds.purity.
-:- import_module check_hlds.typecheck.
 :- import_module check_hlds.type_util.
+:- import_module check_hlds.typecheck.
 :- import_module check_hlds.unify_proc.
 :- import_module check_hlds.unique_modes.
 :- import_module hlds.hlds_clauses.
@@ -381,6 +385,7 @@
 :- import_module parse_tree.error_util.
 :- import_module parse_tree.mercury_to_mercury.
 :- import_module parse_tree.module_qual.
+:- import_module parse_tree.prog_event.
 :- import_module parse_tree.prog_mode.
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_type.
@@ -1513,8 +1518,11 @@
         GenericCall = higher_order(PredVar, _, PredOrFunc, _),
         modecheck_higher_order_call(PredOrFunc, PredVar,
             Args0, Args, Modes, Det, ExtraGoals, !ModeInfo),
+        Goal1 = generic_call(GenericCall, Args, Modes, Det),
         AllArgs0 = [PredVar | Args0],
-        AllArgs = [PredVar | Args]
+        AllArgs = [PredVar | Args],
+        handle_extra_goals(Goal1, ExtraGoals, GoalInfo0, AllArgs0, AllArgs,
+            InstMap0, Goal, !ModeInfo, !IO)
     ;
         % Class method calls are added by polymorphism.m.
         % XXX We should probably fill this in so that
@@ -1522,6 +1530,17 @@
         GenericCall = class_method(_, _, _, _),
         unexpected(this_file, "modecheck_goal_expr: class_method_call")
     ;
+        GenericCall = event_call(EventName),
+        ( event_arg_modes(EventName, ModesPrime) ->
+            Modes = ModesPrime
+        ;
+            % The typechecker should have caught the unknown event,
+            % and not let compilation of this predicate proceed any further.
+            unexpected(this_file, "modecheck_goal_expr: unknown event")
+        ),
+        modecheck_event_call(Modes, Args0, Args, !ModeInfo),
+        Goal = generic_call(GenericCall, Args, Modes, detism_det)
+    ;
         GenericCall = cast(_CastType),
         (
             goal_info_has_feature(GoalInfo0, feature_keep_constant_binding),
@@ -1558,13 +1577,10 @@
             Modes = Modes0
         ),
         modecheck_builtin_cast(Modes, Args0, Args, Det, ExtraGoals, !ModeInfo),
-        AllArgs0 = Args0,
-        AllArgs = Args
-    ),
-
     Goal1 = generic_call(GenericCall, Args, Modes, Det),
-    handle_extra_goals(Goal1, ExtraGoals, GoalInfo0, AllArgs0, AllArgs,
-        InstMap0, Goal, !ModeInfo, !IO),
+        handle_extra_goals(Goal1, ExtraGoals, GoalInfo0, Args0, Args,
+            InstMap0, Goal, !ModeInfo, !IO)
+    ),
 
     mode_info_unset_call_context(!ModeInfo),
     mode_checkpoint(exit, "generic_call", !ModeInfo, !IO).
@@ -1677,9 +1693,8 @@
         % unreachable anyway.
         instmap.is_reachable(InstMap0),
 
-        % If we recorded errors processing the goal, it will
-        % have to be reprocessed anyway, so don't add the extra
-        % goals now.
+        % If we recorded errors processing the goal, it will have to be
+        % reprocessed anyway, so don't add the extra goals now.
         Errors = []
     ->
         %
@@ -2762,26 +2777,35 @@
 
 %-----------------------------------------------------------------------------%
 
-    % Given a list of variables and a list of expected livenesses,
-    % ensure the liveness of each variable satisfies the corresponding
-    % expected liveness.
-    %
-modecheck_var_list_is_live([_ | _], [], _, _, !ModeInfo) :-
-    unexpected(this_file, "modecheck_var_list_is_live: length mismatch").
-modecheck_var_list_is_live([], [_ | _], _, _, !ModeInfo) :-
-    unexpected(this_file, "modecheck_var_list_is_live: length mismatch").
-modecheck_var_list_is_live([], [], _NeedExactMatch, _ArgNum, !ModeInfo).
-modecheck_var_list_is_live([Var | Vars], [IsLive | IsLives], NeedExactMatch,
+modecheck_var_list_is_live_exact_match([_ | _], [], _, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_list_is_live_exact_match: length mismatch").
+modecheck_var_list_is_live_exact_match([], [_ | _], _, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_list_is_live_exact_match: length mismatch").
+modecheck_var_list_is_live_exact_match([], [], _ArgNum, !ModeInfo).
+modecheck_var_list_is_live_exact_match([Var | Vars], [IsLive | IsLives], 
+        ArgNum0, !ModeInfo) :-
+    ArgNum = ArgNum0 + 1,
+    mode_info_set_call_arg_context(ArgNum, !ModeInfo),
+    modecheck_var_is_live_exact_match(Var, IsLive, !ModeInfo),
+    modecheck_var_list_is_live_exact_match(Vars, IsLives, ArgNum, !ModeInfo).
+
+modecheck_var_list_is_live_no_exact_match([_ | _], [], _, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_list_is_live_no_exact_match: length mismatch").
+modecheck_var_list_is_live_no_exact_match([], [_ | _], _, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_list_is_live_no_exact_match: length mismatch").
+modecheck_var_list_is_live_no_exact_match([], [], _ArgNum, !ModeInfo).
+modecheck_var_list_is_live_no_exact_match([Var | Vars], [IsLive | IsLives], 
         ArgNum0, !ModeInfo) :-
     ArgNum = ArgNum0 + 1,
     mode_info_set_call_arg_context(ArgNum, !ModeInfo),
-    modecheck_var_is_live(Var, IsLive, NeedExactMatch, !ModeInfo),
-    modecheck_var_list_is_live(Vars, IsLives, NeedExactMatch, ArgNum,
+    modecheck_var_is_live_no_exact_match(Var, IsLive, !ModeInfo),
+    modecheck_var_list_is_live_no_exact_match(Vars, IsLives, ArgNum,
         !ModeInfo).
 
-:- pred modecheck_var_is_live(prog_var::in, is_live::in, bool::in,
-    mode_info::in, mode_info::out) is det.
-
     % `live' means possibly used later on, and `dead' means definitely not used
     % later on. If you don't need an exact match, then the only time you get
     % an error is if you pass a variable which is live to a predicate
@@ -2789,12 +2813,17 @@
     % update to clobber the variable, so we must be sure that it is dead
     % after the call.
     %
-modecheck_var_is_live(VarId, ExpectedIsLive, NeedExactMatch, !ModeInfo) :-
+
+    % A version of modecheck_var_is_live specialized for NeedExactMatch = no.
+    %
+:- pred modecheck_var_is_live_no_exact_match(prog_var::in, is_live::in,
+    mode_info::in, mode_info::out) is det.
+
+modecheck_var_is_live_no_exact_match(VarId, ExpectedIsLive, !ModeInfo) :-
     mode_info_var_is_live(!.ModeInfo, VarId, VarIsLive),
     (
-        ( ExpectedIsLive = dead, VarIsLive = live
-        ; NeedExactMatch = yes, VarIsLive \= ExpectedIsLive
-        )
+        ExpectedIsLive = dead,
+        VarIsLive = live
     ->
         set.singleton_set(WaitingVars, VarId),
         mode_info_error(WaitingVars, mode_error_var_is_live(VarId), !ModeInfo)
@@ -2802,53 +2831,110 @@
         true
     ).
 
+    % A version of modecheck_var_is_live specialized for NeedExactMatch = yes.
+    %
+:- pred modecheck_var_is_live_exact_match(prog_var::in, is_live::in,
+    mode_info::in, mode_info::out) is det.
+
+modecheck_var_is_live_exact_match(VarId, ExpectedIsLive, !ModeInfo) :-
+    mode_info_var_is_live(!.ModeInfo, VarId, VarIsLive),
+    ( VarIsLive = ExpectedIsLive ->
+        true
+    ;
+        set.singleton_set(WaitingVars, VarId),
+        mode_info_error(WaitingVars, mode_error_var_is_live(VarId), !ModeInfo)
+    ).
+
 %-----------------------------------------------------------------------------%
 
     % Given a list of variables and a list of initial insts, ensure that
     % the inst of each variable matches the corresponding initial inst.
     %
-modecheck_var_has_inst_list(Vars, Insts, NeedEaxctMatch, ArgNum, Subst,
+modecheck_var_has_inst_list_exact_match(Vars, Insts, ArgNum, Subst,
         !ModeInfo) :-
-    modecheck_var_has_inst_list_2(Vars, Insts, NeedEaxctMatch, ArgNum,
+    modecheck_var_has_inst_list_exact_match_2(Vars, Insts, ArgNum,
         map.init, Subst, !ModeInfo).
 
-:- pred modecheck_var_has_inst_list_2(list(prog_var)::in, list(mer_inst)::in,
-    bool::in, int::in, inst_var_sub::in, inst_var_sub::out,
+modecheck_var_has_inst_list_no_exact_match(Vars, Insts, ArgNum, Subst,
+        !ModeInfo) :-
+    modecheck_var_has_inst_list_no_exact_match_2(Vars, Insts, ArgNum,
+        map.init, Subst, !ModeInfo).
+
+:- pred modecheck_var_has_inst_list_exact_match_2(list(prog_var)::in,
+    list(mer_inst)::in, int::in, inst_var_sub::in, inst_var_sub::out,
     mode_info::in, mode_info::out) is det.
 
-modecheck_var_has_inst_list_2([_ | _], [], _, _, !Subst, !ModeInfo) :-
-    unexpected(this_file, "modecheck_var_has_inst_list: length mismatch").
-modecheck_var_has_inst_list_2([], [_ | _], _, _, !Subst, !ModeInfo) :-
-    unexpected(this_file, "modecheck_var_has_inst_list: length mismatch").
-modecheck_var_has_inst_list_2([], [], _Exact, _ArgNum, !Subst, !ModeInfo).
-modecheck_var_has_inst_list_2([Var | Vars], [Inst | Insts], NeedExactMatch,
+modecheck_var_has_inst_list_exact_match_2([_ | _], [], _, !Subst, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_has_inst_list_exact_match_2: length mismatch").
+modecheck_var_has_inst_list_exact_match_2([], [_ | _], _, !Subst, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_has_inst_list_exact_match_2: length mismatch").
+modecheck_var_has_inst_list_exact_match_2([], [], _ArgNum, !Subst, !ModeInfo).
+modecheck_var_has_inst_list_exact_match_2([Var | Vars], [Inst | Insts],
+        ArgNum0, !Subst, !ModeInfo) :-
+    ArgNum = ArgNum0 + 1,
+    mode_info_set_call_arg_context(ArgNum, !ModeInfo),
+    modecheck_var_has_inst_exact_match(Var, Inst, !Subst, !ModeInfo),
+    modecheck_var_has_inst_list_exact_match_2(Vars, Insts, ArgNum,
+        !Subst, !ModeInfo).
+
+:- pred modecheck_var_has_inst_list_no_exact_match_2(list(prog_var)::in,
+    list(mer_inst)::in, int::in, inst_var_sub::in, inst_var_sub::out,
+    mode_info::in, mode_info::out) is det.
+
+modecheck_var_has_inst_list_no_exact_match_2([_ | _], [], _, !Subst,
+        !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_has_inst_list_no_exact_match_2: length mismatch").
+modecheck_var_has_inst_list_no_exact_match_2([], [_ | _], _,
+        !Subst, !ModeInfo) :-
+    unexpected(this_file,
+        "modecheck_var_has_inst_list_no_exact_match_2: length mismatch").
+modecheck_var_has_inst_list_no_exact_match_2([], [], _ArgNum,
+        !Subst, !ModeInfo).
+modecheck_var_has_inst_list_no_exact_match_2([Var | Vars], [Inst | Insts],
         ArgNum0, !Subst, !ModeInfo) :-
     ArgNum = ArgNum0 + 1,
     mode_info_set_call_arg_context(ArgNum, !ModeInfo),
-    modecheck_var_has_inst(Var, Inst, NeedExactMatch, !Subst, !ModeInfo),
-    modecheck_var_has_inst_list_2(Vars, Insts, NeedExactMatch, ArgNum,
+    modecheck_var_has_inst_no_exact_match(Var, Inst, !Subst, !ModeInfo),
+    modecheck_var_has_inst_list_no_exact_match_2(Vars, Insts, ArgNum,
         !Subst, !ModeInfo).
 
-:- pred modecheck_var_has_inst(prog_var::in, mer_inst::in, bool::in,
+:- pred modecheck_var_has_inst_exact_match(prog_var::in, mer_inst::in,
     inst_var_sub::in, inst_var_sub::out,
     mode_info::in, mode_info::out) is det.
 
-modecheck_var_has_inst(VarId, Inst, NeedExactMatch, !Subst, !ModeInfo) :-
+modecheck_var_has_inst_exact_match(VarId, Inst, !Subst, !ModeInfo) :-
     mode_info_get_instmap(!.ModeInfo, InstMap),
     instmap.lookup_var(InstMap, VarId, VarInst),
     mode_info_get_var_types(!.ModeInfo, VarTypes),
     map.lookup(VarTypes, VarId, Type),
     mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
     (
+        inst_matches_initial_no_implied_modes(VarInst, Inst, Type,
+            ModuleInfo0, ModuleInfo, !Subst)
+    ->
+        mode_info_set_module_info(ModuleInfo, !ModeInfo)
+    ;
+        set.singleton_set(WaitingVars, VarId),
+        mode_info_error(WaitingVars,
+            mode_error_var_has_inst(VarId, VarInst, Inst), !ModeInfo)
+    ).
+
+:- pred modecheck_var_has_inst_no_exact_match(prog_var::in, mer_inst::in,
+    inst_var_sub::in, inst_var_sub::out,
+    mode_info::in, mode_info::out) is det.
+
+modecheck_var_has_inst_no_exact_match(VarId, Inst, !Subst, !ModeInfo) :-
+    mode_info_get_instmap(!.ModeInfo, InstMap),
+    instmap.lookup_var(InstMap, VarId, VarInst),
+    mode_info_get_var_types(!.ModeInfo, VarTypes),
+    map.lookup(VarTypes, VarId, Type),
+    mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
         (
-            NeedExactMatch = no,
-            inst_matches_initial(VarInst, Inst, Type, ModuleInfo0,
-                ModuleInfo, !Subst)
-        ;
-            NeedExactMatch = yes,
-            inst_matches_initial_no_implied_modes(VarInst, Inst,
-                Type, ModuleInfo0, ModuleInfo, !Subst)
-        )
+        inst_matches_initial(VarInst, Inst, Type, ModuleInfo0, ModuleInfo,
+            !Subst)
     ->
         mode_info_set_module_info(ModuleInfo, !ModeInfo)
     ;
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.144
diff -u -b -r1.144 module_qual.m
--- compiler/module_qual.m	30 Aug 2006 04:46:00 -0000	1.144
+++ compiler/module_qual.m	30 Aug 2006 22:38:13 -0000
@@ -545,6 +545,15 @@
     list.append(Symbols0, SymbolsC, Symbols),
     bool.and(SuccessA, SuccessB, Success0),
     bool.and(Success0, SuccessC, Success).
+process_assert(event_expr(_Name, Args0) - _, Symbols, Success) :-
+    list.map(term.coerce, Args0, Args),
+    ( term_qualified_symbols_list(Args, SymbolsPrime) ->
+        Symbols = SymbolsPrime,
+        Success = yes
+    ;
+        Symbols = [],
+        Success = no
+    ).
 process_assert(call_expr(SymName, Args0, _Purity) - _, Symbols, Success) :-
     ( SymName = qualified(_, _) ->
         list.map(term.coerce, Args0, Args),
Index: compiler/parse_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/parse_tree.m,v
retrieving revision 1.15
diff -u -b -r1.15 parse_tree.m
--- compiler/parse_tree.m	22 Feb 2006 08:05:15 -0000	1.15
+++ compiler/parse_tree.m	28 Aug 2006 04:06:40 -0000
@@ -43,13 +43,14 @@
 :- include_module prog_out.
 
 % Utility routines.
+:- include_module error_util.
+:- include_module prog_event.
 :- include_module prog_foreign.
 :- include_module prog_mode.
 :- include_module prog_mutable.
-:- include_module prog_util.
 :- include_module prog_type.
 :- include_module prog_type_subst.
-:- include_module error_util.
+:- include_module prog_util.
 
 % Transformations that act on the parse tree,
 % and stuff relating to the module system.
Index: compiler/prog_event.m
===================================================================
RCS file: compiler/prog_event.m
diff -N compiler/prog_event.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/prog_event.m	29 Aug 2006 02:33:09 -0000
@@ -0,0 +1,55 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2006 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.
+%-----------------------------------------------------------------------------%
+%
+% File: prog_event.m.
+% Author: zs.
+%
+% Utility predicates dealing with type in the parse tree. The predicates for
+% doing type substitutions are in prog_type_subst.m, while utility predicates
+% for dealing with types in the HLDS are in type_util.m.
+%
+%-----------------------------------------------------------------------------%
+
+:- module parse_tree.prog_event.
+:- interface.
+
+:- import_module parse_tree.prog_data.
+
+:- import_module assoc_list.
+:- import_module list.
+
+    % Given an event name, returns the types and modes of the arguments
+    % of the event.
+    %
+:- pred event_arg_types_modes(string::in,
+    assoc_list(mer_type, mer_mode)::out) is semidet.
+
+    % Given an event name, returns the types of the arguments of the event.
+    %
+:- pred event_arg_types(string::in, list(mer_type)::out) is semidet.
+
+    % Given an event name, returns the modes of the arguments of the event.
+    %
+:- pred event_arg_modes(string::in, list(mer_mode)::out) is semidet.
+
+:- implementation.
+
+:- import_module parse_tree.prog_mode.
+
+:- import_module pair.
+
+event_arg_types_modes("test_event",
+    [builtin_type(builtin_type_string) - in_mode]).
+
+event_arg_types(EventName, ArgTypes) :-
+    event_arg_types_modes(EventName, ArgTypesModes),
+    assoc_list.keys(ArgTypesModes, ArgTypes).
+
+event_arg_modes(EventName, ArgModes) :-
+    event_arg_types_modes(EventName, ArgTypesModes),
+    assoc_list.values(ArgTypesModes, ArgModes).
Index: compiler/prog_io_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_goal.m,v
retrieving revision 1.46
diff -u -b -r1.46 prog_io_goal.m
--- compiler/prog_io_goal.m	30 Aug 2006 04:46:01 -0000	1.46
+++ compiler/prog_io_goal.m	30 Aug 2006 22:38:13 -0000
@@ -510,6 +510,46 @@
 parse_goal_2("semipure", [SubTerm], Context, MaybeGoal, !VarSet) :-
     parse_goal_with_purity(SubTerm, purity_semipure, Context, MaybeGoal,
         !VarSet).
+parse_goal_2("event", [SubTerm], Context, MaybeGoal, !VarSet) :-
+    parse_goal(SubTerm, MaybeSubGoal, !VarSet),
+    (
+        MaybeSubGoal = ok1(SubGoal),
+        ( SubGoal = call_expr(SymName, Args, Purity) - _SubContext ->
+            (
+                SymName = unqualified(EventName),
+                Purity = purity_pure
+            ->
+                Goal = event_expr(EventName, Args) - Context,
+                MaybeGoal = ok1(Goal)
+            ;
+                some [!Errors] (
+                    !:Errors = [],
+                    ( SymName = unqualified(_) ->
+                        true
+                    ;
+                        SymNameMsg = "event name must not be qualified",
+                        SymNameError = SymNameMsg - SubTerm,
+                        !:Errors = [SymNameError | !.Errors]
+                    ),
+                    ( Purity = purity_pure ->
+                        true
+                    ;
+                        PurityMsg = "event cannot be impure or semipure",
+                        PurityError = PurityMsg - SubTerm,
+                        !:Errors = [PurityError | !.Errors]
+                    ),
+                    MaybeGoal = error1(!.Errors)
+                )
+            )
+        ;
+            Msg = "event prefix must not precede anything other than a call",
+            Error = Msg - SubTerm,
+            MaybeGoal = error1([Error])
+        )
+    ;
+        MaybeSubGoal = error1(Errors),
+        MaybeGoal = error1(Errors)
+    ).
 parse_goal_2("is", [ATerm0, BTerm0], Context, MaybeGoal, !VarSet) :-
     % The following is a temporary hack to handle `is' in the parser -
     % we ought to handle it in the code generation - but then `is/2' itself
Index: compiler/prog_item.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_item.m,v
retrieving revision 1.22
diff -u -b -r1.22 prog_item.m
--- compiler/prog_item.m	30 Aug 2006 04:46:01 -0000	1.22
+++ compiler/prog_item.m	30 Aug 2006 22:38:13 -0000
@@ -719,6 +719,7 @@
                             % if_then_else(SomeVars, StateVars, If, Then, Else)
 
     % atomic goals
+    ;       event_expr(string, list(prog_term))
     ;       call_expr(sym_name, list(prog_term), purity)
     ;       unify_expr(prog_term, prog_term, purity).
 
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.47
diff -u -b -r1.47 prog_rep.m
--- compiler/prog_rep.m	27 Jul 2006 05:01:21 -0000	1.47
+++ compiler/prog_rep.m	25 Aug 2006 03:52:07 -0000
@@ -243,6 +243,13 @@
             vars_to_byte_list(Info, Args) ++
             AtomicBytes
     ;
+        GenericCall = event_call(EventName),
+        string_to_byte_list(EventName, !StackInfo, EventNameBytes),
+        Bytes = [goal_type_to_byte(goal_event_call)] ++
+            EventNameBytes ++
+            vars_to_byte_list(Info, Args) ++
+            AtomicBytes
+    ;
         GenericCall = cast(_),
         ( Args = [InputArg, OutputArg] ->
             Bytes = [goal_type_to_byte(goal_cast)] ++
Index: compiler/prog_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_util.m,v
retrieving revision 1.93
diff -u -b -r1.93 prog_util.m
--- compiler/prog_util.m	30 Aug 2006 04:46:01 -0000	1.93
+++ compiler/prog_util.m	30 Aug 2006 22:38:13 -0000
@@ -467,6 +467,10 @@
     rename_in_goal(OldVar, NewVar, Then0, Then),
     rename_in_goal(OldVar, NewVar, Else0, Else).
 rename_in_goal_expr(OldVar, NewVar,
+        event_expr(Name, Terms0),
+        event_expr(Name, Terms)) :-
+    term.substitute_list(Terms0, OldVar, term.variable(NewVar), Terms).
+rename_in_goal_expr(OldVar, NewVar,
         call_expr(SymName, Terms0, Purity),
         call_expr(SymName, Terms, Purity)) :-
     term.substitute_list(Terms0, OldVar, term.variable(NewVar), Terms).
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.101
diff -u -b -r1.101 purity.m
--- compiler/purity.m	31 Aug 2006 08:48:50 -0000	1.101
+++ compiler/purity.m	1 Sep 2006 02:08:15 -0000
@@ -514,7 +514,9 @@
         Purity = purity_pure, % XXX this is wrong!
         GoalExpr = generic_call(GenericCall0, Args, Modes0, Det)
     ;
-        GenericCall0 = cast(_),
+        ( GenericCall0 = cast(_)
+        ; GenericCall0 = event_call(_)
+        ),
         Purity = purity_pure,
         GoalExpr = generic_call(GenericCall0, Args, Modes0, Det)
     ).
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.187
diff -u -b -r1.187 simplify.m
--- compiler/simplify.m	22 Aug 2006 05:04:07 -0000	1.187
+++ compiler/simplify.m	25 Aug 2006 03:17:01 -0000
@@ -2904,6 +2904,9 @@
         GenericCall = class_method(_, _, _, _),
         WillFlush0 = yes
     ;
+        GenericCall = event_call(_),
+        WillFlush0 = no
+    ;
         GenericCall = cast(_),
         WillFlush0 = no
     ),
Index: compiler/superhomogeneous.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/superhomogeneous.m,v
retrieving revision 1.19
diff -u -b -r1.19 superhomogeneous.m
--- compiler/superhomogeneous.m	20 Aug 2006 08:21:30 -0000	1.19
+++ compiler/superhomogeneous.m	27 Aug 2006 15:08:27 -0000
@@ -33,12 +33,12 @@
 
 :- type arg_context
     --->    ac_head(pred_or_func, arity)
-            % the arguments in the head of the clause
+            % The arguments in the head of the clause.
 
     ;       ac_call(call_id)
-            % the arguments in a call to a predicate
+            % The arguments in a call to a predicate.
 
-    ;       ac_functor(            % the arguments in a functor
+    ;       ac_functor(            % The arguments in a functor.
                 cons_id,
                 unify_main_context,
                 unify_sub_contexts
Index: compiler/tabling_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/tabling_analysis.m,v
retrieving revision 1.5
diff -u -b -r1.5 tabling_analysis.m
--- compiler/tabling_analysis.m	22 Aug 2006 05:04:10 -0000	1.5
+++ compiler/tabling_analysis.m	25 Aug 2006 03:11:55 -0000
@@ -490,6 +490,10 @@
         Result  = mm_tabled_may_call,
         MaybeAnalysisStatus = yes(optimal)
     ;
+        Details = event_call(_),
+        Result = mm_tabled_will_not_call,
+        MaybeAnalysisStatus = yes(optimal)
+    ;
         Details = cast(_),
         Result = mm_tabled_will_not_call,
         MaybeAnalysisStatus = yes(optimal)
@@ -768,6 +772,9 @@
         GenericCall = class_method(_, _, _, _),
         Status = mm_tabled_may_call
     ;     
+        GenericCall = event_call(_),
+        Status = mm_tabled_will_not_call
+    ;     
         GenericCall = cast(_),
         Status = mm_tabled_will_not_call
     ).
Index: compiler/term_traversal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_traversal.m,v
retrieving revision 1.50
diff -u -b -r1.50 term_traversal.m
--- compiler/term_traversal.m	16 Aug 2006 01:25:47 -0000	1.50
+++ compiler/term_traversal.m	25 Aug 2006 03:12:24 -0000
@@ -273,6 +273,8 @@
         %
         add_error(Context, method_call, Params, !Info)
     ;
+        Details = event_call(_)
+    ;
         Details = cast(_)
     ).
 
Index: compiler/trailing_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/trailing_analysis.m,v
retrieving revision 1.20
diff -u -b -r1.20 trailing_analysis.m
--- compiler/trailing_analysis.m	22 Aug 2006 05:04:11 -0000	1.20
+++ compiler/trailing_analysis.m	25 Aug 2006 03:13:17 -0000
@@ -425,7 +425,9 @@
         Result = trail_may_modify,
         MaybeAnalysisStatus = yes(optimal)
     ;
-        Details = cast(_),
+        ( Details = cast(_)
+        ; Details = event_call(_)
+        ),
         Result  = trail_will_not_modify,
         MaybeAnalysisStatus = yes(optimal)
     ).
@@ -929,6 +931,9 @@
         Details = class_method(_, _, _, _),
         Status = trail_may_modify
     ;
+        Details = event_call(_),
+        Status = trail_will_not_modify
+    ;
         Details = cast(_),
         Status = trail_will_not_modify
     ).
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.401
diff -u -b -r1.401 typecheck.m
--- compiler/typecheck.m	22 Aug 2006 05:04:12 -0000	1.401
+++ compiler/typecheck.m	28 Aug 2006 04:57:31 -0000
@@ -105,10 +105,10 @@
 :- import_module check_hlds.clause_to_proc.
 :- import_module check_hlds.goal_path.
 :- import_module check_hlds.inst_match.
+:- import_module check_hlds.type_util.
 :- import_module check_hlds.typecheck_errors.
 :- import_module check_hlds.typecheck_info.
 :- import_module check_hlds.typeclasses.
-:- import_module check_hlds.type_util.
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
@@ -128,6 +128,7 @@
 :- import_module parse_tree.mercury_to_mercury.
 :- import_module parse_tree.modules.
 :- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_event.
 :- import_module parse_tree.prog_io.
 :- import_module parse_tree.prog_io_util.
 :- import_module parse_tree.prog_mode.
@@ -897,7 +898,7 @@
     ;
         Clauses0 = [SingleClause0]
     ->
-        SingleClause0 = clause(A, Goal0, C, D),
+        SingleClause0 = clause(ApplicableProcs, Goal0, Language, Context),
 
         Goal0 = _ - GoalInfo0,
         goal_to_conj_list(Goal0, Conj0),
@@ -912,7 +913,7 @@
         apply_partial_map_to_list(Subst, HeadVars0, HeadVars),
         clauses_info_set_headvars(HeadVars, ClausesInfo0, ClausesInfo1),
 
-        SingleClause = clause(A, Goal, C, D),
+        SingleClause = clause(ApplicableProcs, Goal, Language, Context),
         clauses_info_set_clauses([SingleClause], ClausesInfo1, ClausesInfo2),
         clauses_info_set_varset(VarSet, ClausesInfo2, ClausesInfo),
         pred_info_set_clauses_info(ClausesInfo, !PredInfo)
@@ -1291,7 +1292,7 @@
         typecheck_call_pred(CurCall, Args, GoalPath, PredId, !Info, !IO),
         GoalExpr = plain_call(PredId, ProcId, Args, BI, UC, Name)
     ;
-        GoalExpr0 = generic_call(GenericCall0, Args, C, D),
+        GoalExpr0 = generic_call(GenericCall0, Args, Modes, Detism),
         hlds_goal.generic_call_id(GenericCall0, CallId),
         typecheck_info_set_called_predid(CallId, !Info),
         (
@@ -1301,23 +1302,28 @@
             typecheck_higher_order_call(PredVar, Purity, Args, !Info, !IO)
         ;
             GenericCall0 = class_method(_, _, _, _),
-            unexpected(this_file, "typecheck_goal_2:
-                unexpected class method call")
+            unexpected(this_file,
+                "typecheck_goal_2: unexpected class method call")
+        ;
+            GenericCall0 = event_call(EventName),
+            GenericCall = GenericCall0,
+            checkpoint("event call", !Info, !IO),
+            typecheck_event_call(EventName, Args, !Info, !IO)
         ;
             GenericCall0 = cast(_),
             % A cast imposes no restrictions on its argument types,
             % so nothing needs to be done here.
             GenericCall = GenericCall0
         ),
-        GoalExpr = generic_call(GenericCall, Args, C, D)
+        GoalExpr = generic_call(GenericCall, Args, Modes, Detism)
     ;
-        GoalExpr0 = unify(LHS, RHS0, C, D, UnifyContext),
+        GoalExpr0 = unify(LHS, RHS0, UnifyMode, Unification, UnifyContext),
         checkpoint("unify", !Info, !IO),
         typecheck_info_set_arg_num(0, !Info),
         typecheck_info_set_unify_context(UnifyContext, !Info),
         goal_info_get_goal_path(GoalInfo, GoalPath),
         typecheck_unification(LHS, RHS0, RHS, GoalPath, !Info, !IO),
-        GoalExpr = unify(LHS, RHS, C, D, UnifyContext)
+        GoalExpr = unify(LHS, RHS, UnifyMode, Unification, UnifyContext)
     ;
         GoalExpr0 = switch(_, _, _),
         unexpected(this_file, "typecheck_goal_2: unexpected switch")
@@ -1444,6 +1450,18 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred typecheck_event_call(string::in, list(prog_var)::in,
+    typecheck_info::in, typecheck_info::out, io::di, io::uo) is det.
+
+typecheck_event_call(EventName, Args, !Info, !IO) :-
+    ( event_arg_types(EventName, EventArgTypes) ->
+        typecheck_var_has_type_list(Args, EventArgTypes, 1, !Info, !IO)
+    ;
+        report_unknown_event_call_error(EventName, !Info, !IO)
+    ).
+
+%-----------------------------------------------------------------------------%
+
 :- pred typecheck_call_pred(simple_call_id::in, list(prog_var)::in,
     goal_path::in, pred_id::out, typecheck_info::in, typecheck_info::out,
     io::di, io::uo) is det.
@@ -1484,7 +1502,6 @@
         % S. Peyton-Jones, M. Jones 1997, for a discussion of some of the
         % issues.
         perform_context_reduction(OrigTypeAssignSet, !Info, !IO)
-
     ;
         PredId = invalid_pred_id,
         report_pred_call_error(CallId, !Info, !IO)
@@ -1497,7 +1514,6 @@
 
 typecheck_call_pred_id(PredId, Args, GoalPath, !Info, !IO) :-
     typecheck_info_get_module_info(!.Info, ModuleInfo),
-    module_info_get_class_table(ModuleInfo, ClassTable),
     module_info_get_predicate_table(ModuleInfo, PredicateTable),
     predicate_table_get_preds(PredicateTable, Preds),
     map.lookup(Preds, PredId, PredInfo),
@@ -1515,6 +1531,7 @@
     ->
         typecheck_var_has_type_list(Args, PredArgTypes, 1, !Info, !IO)
     ;
+        module_info_get_class_table(ModuleInfo, ClassTable),
         make_body_hlds_constraints(ClassTable, PredTypeVarSet,
             GoalPath, PredClassContext, PredConstraints),
         typecheck_var_has_polymorphic_type_list(Args, PredTypeVarSet,
@@ -1864,10 +1881,10 @@
 
 typecheck_unification(X, rhs_var(Y), rhs_var(Y), _, !Info, !IO) :-
     typecheck_unify_var_var(X, Y, !Info, !IO).
-typecheck_unification(X, rhs_functor(F, E, As), rhs_functor(F, E, As),
-        GoalPath, !Info, !IO) :-
+typecheck_unification(X, rhs_functor(Functor, ExistConstraints, Args),
+        rhs_functor(Functor, ExistConstraints, Args), GoalPath, !Info, !IO) :-
     typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
-    typecheck_unify_var_functor(X, F, As, GoalPath, !Info, !IO),
+    typecheck_unify_var_functor(X, Functor, Args, GoalPath, !Info, !IO),
     perform_context_reduction(OrigTypeAssignSet, !Info, !IO).
 typecheck_unification(X,
         rhs_lambda_goal(Purity, PredOrFunc, EvalMethod,
@@ -2338,8 +2355,8 @@
     % or equal to Arity.  GoalPath is used to identify any constraints
     % introduced.
     %
-    % For example, functor `map.search/1' has type `pred(K,V)'
-    % (hence PredTypeParams = [K,V]) and argument types [map(K,V)].
+    % For example, functor `map.search/1' has type `pred(K, V)'
+    % (hence PredTypeParams = [K, V]) and argument types [map(K, V)].
     %
 :- pred builtin_pred_type(typecheck_info::in, cons_id::in, int::in,
     goal_path::in, list(cons_type_info)::out) is semidet.
Index: compiler/typecheck_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_errors.m,v
retrieving revision 1.27
diff -u -b -r1.27 typecheck_errors.m
--- compiler/typecheck_errors.m	22 Aug 2006 05:04:12 -0000	1.27
+++ compiler/typecheck_errors.m	29 Aug 2006 02:16:35 -0000
@@ -41,6 +41,9 @@
 :- pred report_pred_call_error(simple_call_id::in,
     typecheck_info::in, typecheck_info::out, io::di, io::uo) is det.
 
+:- pred report_unknown_event_call_error(string::in,
+    typecheck_info::in, typecheck_info::out, io::di, io::uo) is det.
+
 :- pred report_no_clauses(string::in, pred_id::in, pred_info::in,
     module_info::in, io::di, io::uo) is det.
 
@@ -141,7 +144,7 @@
             calls_are_fully_qualified(!.Info ^ pred_markers),
             PredOrFunc0, SymName, OtherIds),
         predicate_table_get_preds(PredicateTable, Preds),
-        OtherIds \= []
+        OtherIds = [_ | _]
     ->
         typecheck_find_arities(Preds, OtherIds, Arities),
         report_error_pred_num_args(!.Info, PredCallId, Arities, !IO)
@@ -152,10 +155,9 @@
         predicate_table_search_pf_sym(PredicateTable,
             calls_are_fully_qualified(!.Info ^ pred_markers),
             PredOrFunc, SymName, OtherIds),
-        OtherIds \= []
+        OtherIds = [_ | _]
     ->
-        report_error_func_instead_of_pred(!.Info, PredOrFunc,
-            PredCallId, !IO)
+        report_error_func_instead_of_pred(!.Info, PredOrFunc, PredCallId, !IO)
     ;
         report_error_undef_pred(!.Info, PredCallId, !IO)
     ),
@@ -333,15 +335,23 @@
 
 %-----------------------------------------------------------------------------%
 
+report_unknown_event_call_error(EventName, !Info, !IO) :-
+    typecheck_info_get_context(!.Info, Context),
+    Pieces = [words("There is no event named"), quote(EventName),
+        suffix(".")],
+    error_util.write_error_pieces(Context, 0, Pieces, !IO).
+
+%-----------------------------------------------------------------------------%
+
 report_no_clauses(MessageKind, PredId, PredInfo, ModuleInfo, !IO) :-
     io.get_exit_status(Status, !IO),
     ( Status = 0 ->
         pred_info_context(PredInfo, Context),
         PredPieces = describe_one_pred_name(ModuleInfo,
             should_not_module_qualify, PredId),
-        ErrorMsg = [words(MessageKind ++ ": no clauses for ") | PredPieces] ++
+        Pieces = [words(MessageKind ++ ": no clauses for ") | PredPieces] ++
             [suffix(".")],
-        error_util.write_error_pieces(Context, 0, ErrorMsg, !IO)
+        error_util.write_error_pieces(Context, 0, Pieces, !IO)
     ;
         % It is possible (and even likely) that the error that got the exit
         % status set was caused by a syntax error in a clause defining this
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.115
diff -u -b -r1.115 unique_modes.m
--- compiler/unique_modes.m	22 Aug 2006 05:04:13 -0000	1.115
+++ compiler/unique_modes.m	25 Aug 2006 04:00:47 -0000
@@ -439,6 +439,9 @@
         GenericCall = class_method(_, _, _, _),
         ArgOffset = 0
     ;
+        GenericCall = event_call(_),
+        ArgOffset = 0
+    ;
         % Casts are introduced by the compiler and should be mode correct.
         GenericCall = cast(_),
         ArgOffset = 0
@@ -594,9 +597,8 @@
         !ModeInfo) :-
     mode_info_get_module_info(!.ModeInfo, ModuleInfo),
     mode_list_get_initial_insts(ModuleInfo, ProcArgModes, InitialInsts),
-    NeedExactMatch = no,
-    modecheck_var_has_inst_list(ArgVars, InitialInsts,
-        NeedExactMatch, ArgOffset, InstVarSub, !ModeInfo),
+    modecheck_var_has_inst_list_no_exact_match(ArgVars, InitialInsts,
+        ArgOffset, InstVarSub, !ModeInfo),
     mode_list_get_final_insts(ModuleInfo, ProcArgModes, FinalInsts0),
     inst_list_apply_substitution(InstVarSub, FinalInsts0, FinalInsts),
     modecheck_set_var_inst_list(ArgVars, InitialInsts, FinalInsts,
cvs diff: Diffing compiler/notes
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.121
diff -u -b -r1.121 compiler_design.html
--- compiler/notes/compiler_design.html	27 Jul 2006 05:03:33 -0000	1.121
+++ compiler/notes/compiler_design.html	28 Aug 2006 04:08:53 -0000
@@ -280,6 +280,7 @@
 	for manipulating foreign code,
 	prog_mutable contains utility predicates
 	for manipulating mutable variables,
+	prog_event contains utility predicates for working with events,
 	while error_util.m contains predicates
 	for printing nicely formatting error messages.
 
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/ops.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/ops.m,v
retrieving revision 1.64
diff -u -b -r1.64 ops.m
--- library/ops.m	27 Jul 2006 05:03:39 -0000	1.64
+++ library/ops.m	25 Aug 2006 01:53:58 -0000
@@ -335,6 +335,7 @@
 ops.op_table("pred", before, fx, 800).     % Mercury/NU-Prolog extension
 ops.op_table("promise", before, fx, 1199). % Mercury extension
 ops.op_table("trace", before, fxy, 950).   % Mercury extension
+ops.op_table("event", before, fx, 100).    % Mercury extension
 ops.op_table("promise_exclusive", before, fy, 950). % Mercury extension
 ops.op_table("promise_exhaustive", before, fy, 950). % Mercury extension
 ops.op_table("promise_exclusive_exhaustive", before, fy, 950).
cvs diff: Diffing mdbcomp
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.15
diff -u -b -r1.15 program_representation.m
--- mdbcomp/program_representation.m	9 Aug 2006 03:17:15 -0000	1.15
+++ mdbcomp/program_representation.m	25 Aug 2006 03:42:20 -0000
@@ -155,6 +155,10 @@
                 string,             % name of called pred's module
                 string,             % name of the called pred
                 list(var_rep)       % the call's arguments
+            )
+    ;       event_call_rep(
+                string,             % name of the event
+                list(var_rep)       % the call's arguments
             ).
 
 :- type var_rep ==  int.
@@ -172,10 +176,10 @@
     ;       failure_rep.
 
     % If the given atomic goal behaves like a call in the sense that it
-    % generates events, then return the list of variables that are passed
-    % as arguments.
+    % generates events as ordinary calls do, then return the list of variables
+    % that are passed as arguments.
     %
-:- func atomic_goal_generates_event(atomic_goal_rep) = maybe(list(var_rep)).
+:- func atomic_goal_generates_event_like_call(atomic_goal_rep) = maybe(list(var_rep)).
 
     % If the given goal generates internal events directly then this
     % function will return yes and no otherwise.
@@ -193,7 +197,7 @@
 :- type atomic_goal_id
     ---> atomic_goal_id(string, string, int).
 
-    % Can we find out the atomic goals name, module and arity from
+    % Can we find out the atomic goal's name, module and arity from
     % its atomic_goal_rep? If so return them, otherwise return no.
     %
 :- func atomic_goal_identifiable(atomic_goal_rep) =
@@ -304,7 +308,8 @@
     ;       goal_ho_call
     ;       goal_method_call
     ;       goal_plain_call
-    ;       goal_builtin_call.
+    ;       goal_builtin_call
+    ;       goal_event_call.
 
 :- func goal_type_to_byte(bytecode_goal_type) = int.
 
@@ -351,23 +356,26 @@
 :- import_module require.
 :- import_module string.
 
-atomic_goal_generates_event(unify_construct_rep(_, _, _)) = no.
-atomic_goal_generates_event(unify_deconstruct_rep(_, _, _)) = no.
-atomic_goal_generates_event(partial_construct_rep(_, _, _)) = no.
-atomic_goal_generates_event(partial_deconstruct_rep(_, _, _)) = no.
-atomic_goal_generates_event(unify_assign_rep(_, _)) = no.
-atomic_goal_generates_event(unify_simple_test_rep(_, _)) = no.
-atomic_goal_generates_event(cast_rep(_, _)) = no.
-atomic_goal_generates_event(pragma_foreign_code_rep(_)) = no.
-atomic_goal_generates_event(higher_order_call_rep(_, Args)) = yes(Args).
-atomic_goal_generates_event(method_call_rep(_, _, Args)) = yes(Args).
-atomic_goal_generates_event(builtin_call_rep(_, _, _)) = no.
-atomic_goal_generates_event(plain_call_rep(ModuleName, PredName, Args)) =
+atomic_goal_generates_event_like_call(unify_construct_rep(_, _, _)) = no.
+atomic_goal_generates_event_like_call(unify_deconstruct_rep(_, _, _)) = no.
+atomic_goal_generates_event_like_call(partial_construct_rep(_, _, _)) = no.
+atomic_goal_generates_event_like_call(partial_deconstruct_rep(_, _, _)) = no.
+atomic_goal_generates_event_like_call(unify_assign_rep(_, _)) = no.
+atomic_goal_generates_event_like_call(unify_simple_test_rep(_, _)) = no.
+atomic_goal_generates_event_like_call(cast_rep(_, _)) = no.
+atomic_goal_generates_event_like_call(pragma_foreign_code_rep(_)) = no.
+atomic_goal_generates_event_like_call(higher_order_call_rep(_, Args)) =
+        yes(Args).
+atomic_goal_generates_event_like_call(method_call_rep(_, _, Args)) = yes(Args).
+atomic_goal_generates_event_like_call(builtin_call_rep(_, _, _)) = no.
+atomic_goal_generates_event_like_call(plain_call_rep(ModuleName, PredName,
+        Args)) =
     ( call_does_not_generate_events(ModuleName, PredName, list.length(Args)) ->
         no
     ;
         yes(Args)
     ).
+atomic_goal_generates_event_like_call(event_call_rep(_, _)) = no.
 
 call_does_not_generate_events(ModuleName, PredName, Arity) :-
     (
@@ -415,6 +423,7 @@
     yes(atomic_goal_id(Module, Name, length(Args))).
 atomic_goal_identifiable(plain_call_rep(Module, Name, Args)) =
     yes(atomic_goal_id(Module, Name, length(Args))).
+atomic_goal_identifiable(event_call_rep(_, _)) = no.
 
 :- pragma export(proc_rep_type = out, "ML_proc_rep_type").
 
@@ -527,6 +536,7 @@
 goal_type_byte(16, goal_method_call).
 goal_type_byte(17, goal_plain_call).
 goal_type_byte(18, goal_builtin_call).
+goal_type_byte(19, goal_event_call).
 
 %-----------------------------------------------------------------------------%
 
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list