[m-rev.] for review: mlds__function_body

Tyson Dowd trd at cs.mu.OZ.AU
Fri Jul 13 01:32:31 AEST 2001


Hi,

===================================================================


Estimated hours taken: 0.75
Branches: main

Use a new mlds__function_body type to represent function bodies, as the old
usage of maybe/1 was error prone ("no" meant the function had been declared
using :- pragma external, not merely that the body was missing).

compiler/mlds.m:
	Add mlds__function_body type.

compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_tailcall.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_csharp.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_mcpp.m:
	Handle this change.


Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.91
diff -u -r1.91 ml_code_gen.m
--- compiler/ml_code_gen.m	2001/07/11 13:52:34	1.91
+++ compiler/ml_code_gen.m	2001/07/12 14:50:48
@@ -1050,7 +1050,7 @@
 		% corresponding definition, making sure that the function
 		% is declared as `extern' rather than `static'.
 		%
-		MaybeStatement = no,
+		FunctionBody = external,
 		ExtraDefns = []
 	;
 		% Set up the initial success continuation, if any.
@@ -1100,10 +1100,10 @@
 		MLDS_Decls = list__append(MLDS_LocalVars, MLDS_Decls0),
 		MLDS_Statement = ml_gen_block(MLDS_Decls, MLDS_Statements,
 			Context),
-		MaybeStatement = yes(MLDS_Statement)
+		FunctionBody = defined_here(MLDS_Statement)
 	),
 	MLDS_ProcDefnBody = mlds__function(yes(proc(PredId, ProcId)),
-			MLDS_Params, MaybeStatement).
+			MLDS_Params, FunctionBody).
 
 	% for model_det and model_semi procedures,
 	% figure out which output variables are returned by
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.41
diff -u -r1.41 ml_code_util.m
--- compiler/ml_code_util.m	2001/07/11 10:20:11	1.41
+++ compiler/ml_code_util.m	2001/07/12 14:50:49
@@ -921,7 +921,8 @@
 	%
 	{ DeclFlags = ml_gen_label_func_decl_flags },
 	{ MaybePredProcId = no },
-	{ FuncDefn = function(MaybePredProcId, FuncParams, yes(Statement)) },
+	{ FuncDefn = function(MaybePredProcId, FuncParams,
+		defined_here(Statement)) },
 	{ Func = mlds__defn(FuncName, mlds__make_context(Context), DeclFlags,
 			FuncDefn) }.
 
@@ -1775,7 +1776,7 @@
 
 	{ 
 		Defn = mlds__defn(function(PredLabel, ProcId, 
-			yes(SeqNum), _), _, _, function(_, _, yes(_)))
+			yes(SeqNum), _), _, _, function(_, _, defined_here(_)))
 	->
 		% We call the proxy function.
 		QualProcLabel = qual(MLDS_Module, PredLabel - ProcId),
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.33
diff -u -r1.33 ml_elim_nested.m
--- compiler/ml_elim_nested.m	2001/07/11 12:45:18	1.33
+++ compiler/ml_elim_nested.m	2001/07/12 14:50:49
@@ -161,7 +161,8 @@
 		mlds__defn) = list(mlds__defn).
 ml_elim_nested_defns(ModuleName, Globals, OuterVars, Defn0) = FlatDefns :-
 	Defn0 = mlds__defn(Name, Context, Flags, DefnBody0),
-	( DefnBody0 = mlds__function(PredProcId, Params, yes(FuncBody0)) ->
+	( DefnBody0 = mlds__function(PredProcId, Params,
+			defined_here(FuncBody0)) ->
 		EnvName = ml_env_name(Name),
 			% XXX this should be optimized to generate 
 			% EnvTypeName from just EnvName
@@ -265,7 +266,8 @@
 				HoistedDefns = HoistedDefns0
 			)
 		),
-		DefnBody = mlds__function(PredProcId, Params, yes(FuncBody)),
+		DefnBody = mlds__function(PredProcId, Params,
+			defined_here(FuncBody)),
 		Defn = mlds__defn(Name, Context, Flags, DefnBody),
 		FlatDefns = list__append(HoistedDefns, [Defn])
 	;
@@ -387,7 +389,7 @@
 		Stmt = mlds__statement(block([], []), Context),
 
 		Ctor = mlds__function(no, func_params([], []),
-				yes(Stmt)),
+				defined_here(Stmt)),
 		CtorFlags = init_decl_flags(public, per_instance, non_virtual,
 				overridable, modifiable, concrete),
 
@@ -486,7 +488,8 @@
 ml_insert_init_env(TypeName, ModuleName, Globals, Defn0, Defn, Init0, Init) :-
 	Defn0 = mlds__defn(Name, Context, Flags, DefnBody0),
 	(
-		DefnBody0 = mlds__function(PredProcId, Params, yes(FuncBody0)),
+		DefnBody0 = mlds__function(PredProcId, Params, 
+			defined_here(FuncBody0)),
 		statement_contains_var(FuncBody0, qual(ModuleName,
 			mlds__var_name("env_ptr", no)))
 	->
@@ -499,7 +502,8 @@
 			Globals, EnvPtrDecl, InitEnvPtr),
 		FuncBody = mlds__statement(block([EnvPtrDecl],
 				[InitEnvPtr, FuncBody0]), Context),
-		DefnBody = mlds__function(PredProcId, Params, yes(FuncBody)),
+		DefnBody = mlds__function(PredProcId, Params,
+			defined_here(FuncBody)),
 		Defn = mlds__defn(Name, Context, Flags, DefnBody),
 		Init = yes
 	;
@@ -671,6 +675,7 @@
 
 %
 % flatten_maybe_statement:
+% flatten_function_body:
 % flatten_statements:
 % flatten_statement:
 %	Recursively process the statement(s), calling fixup_var on every
@@ -679,6 +684,14 @@
 %	variables and nested functions).
 %
 
+:- pred flatten_function_body(function_body, function_body,
+		elim_info, elim_info).
+:- mode flatten_function_body(in, out, in, out) is det.
+
+flatten_function_body(external, external) --> [].
+flatten_function_body(defined_here(Statement0), defined_here(Statement)) -->
+	flatten_statement(Statement0, Statement).
+
 :- pred flatten_maybe_statement(maybe(mlds__statement), maybe(mlds__statement),
 		elim_info, elim_info).
 :- mode flatten_maybe_statement(in, out, in, out) is det.
@@ -813,7 +826,7 @@
 		%
 		% recursively flatten the nested function
 		%
-		flatten_maybe_statement(FuncBody0, FuncBody),
+		flatten_function_body(FuncBody0, FuncBody),
 
 		%
 		% mark the function as private / one_copy,
@@ -1188,6 +1201,7 @@
 % defn_contains_defn:
 % defn_body_contains_defn:
 % maybe_statement_contains_defn:
+% function_body_contains_defn:
 % statements_contains_defn:
 % statement_contains_defn:
 %	Nondeterministically return all the definitions contained
@@ -1212,9 +1226,9 @@
 :- mode defn_body_contains_defn(in, out) is nondet.
 
 % defn_body_contains_defn(mlds__data(_Type, _Initializer), _Defn) :- fail.
-defn_body_contains_defn(mlds__function(_PredProcId, _Params, MaybeBody),
+defn_body_contains_defn(mlds__function(_PredProcId, _Params, FunctionBody),
 		Name) :-
-	maybe_statement_contains_defn(MaybeBody, Name).
+	function_body_contains_defn(FunctionBody, Name).
 defn_body_contains_defn(mlds__class(ClassDefn), Name) :-
 	ClassDefn = mlds__class_defn(_Kind, _Imports, _Inherits, _Implements,
 		CtorDefns, FieldDefns),
@@ -1236,6 +1250,13 @@
 maybe_statement_contains_defn(yes(Statement), Defn) :-
 	statement_contains_defn(Statement, Defn).
 
+:- pred function_body_contains_defn(function_body, mlds__defn).
+:- mode function_body_contains_defn(in, out) is nondet.
+
+% function_body_contains_defn(external, _Defn) :- fail.
+function_body_contains_defn(defined_here(Statement), Defn) :-
+	statement_contains_defn(Statement, Defn).
+
 :- pred statement_contains_defn(mlds__statement, mlds__defn).
 :- mode statement_contains_defn(in, out) is nondet.
 
@@ -1315,7 +1336,7 @@
 % defns_contains_var:
 % defn_contains_var:
 % defn_body_contains_var:
-% maybe_statement_contains_var:
+% function_body_contains_var:
 % statements_contains_var:
 % statement_contains_var:
 % trail_op_contains_var:
@@ -1342,9 +1363,9 @@
 
 defn_body_contains_var(mlds__data(_Type, Initializer), Name) :-
 	initializer_contains_var(Initializer, Name).
-defn_body_contains_var(mlds__function(_PredProcId, _Params, MaybeBody),
+defn_body_contains_var(mlds__function(_PredProcId, _Params, FunctionBody),
 		Name) :-
-	maybe_statement_contains_var(MaybeBody, Name).
+	function_body_contains_var(FunctionBody, Name).
 defn_body_contains_var(mlds__class(ClassDefn), Name) :-
 	ClassDefn = mlds__class_defn(_Kind, _Imports, _Inherits, _Implements,
 		CtorDefns, FieldDefns),
@@ -1357,6 +1378,13 @@
 
 % maybe_statement_contains_var(no, _) :- fail.
 maybe_statement_contains_var(yes(Statement), Name) :-
+	statement_contains_var(Statement, Name).
+
+:- pred function_body_contains_var(function_body, mlds__var).
+:- mode function_body_contains_var(in, in) is semidet.
+
+% function_body_contains_var(external, _) :- fail.
+function_body_contains_var(defined_here(Statement), Name) :-
 	statement_contains_var(Statement, Name).
 	
 :- pred statements_contains_var(mlds__statements, mlds__var).
Index: compiler/ml_optimize.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_optimize.m,v
retrieving revision 1.11
diff -u -r1.11 ml_optimize.m
--- compiler/ml_optimize.m	2001/07/09 15:55:04	1.11
+++ compiler/ml_optimize.m	2001/07/12 14:50:50
@@ -78,7 +78,7 @@
 		OptInfo = opt_info(Globals, ModuleName, Name, Params, Context),
 
 		FuncBody1 = optimize_func(OptInfo, FuncBody0),
-		FuncBody = optimize_in_maybe_statement(OptInfo, FuncBody1),
+		FuncBody = optimize_in_function_body(OptInfo, FuncBody1),
 
 		DefnBody = mlds__function(PredProcId, Params, FuncBody),
 		Defn = mlds__defn(Name, Context, Flags, DefnBody)
@@ -99,6 +99,13 @@
 		Defn = mlds__defn(Name, Context, Flags, DefnBody)
 	).
 
+:- func optimize_in_function_body(opt_info, function_body) = function_body.
+
+optimize_in_function_body(_, external) = external.
+optimize_in_function_body(OptInfo, defined_here(Statement0)) =
+		defined_here(Statement) :-
+	Statement = optimize_in_statement(OptInfo, Statement0).
+
 :- func optimize_in_maybe_statement(opt_info, 
 		maybe(mlds__statement)) = maybe(mlds__statement).
 
@@ -290,16 +297,14 @@
 	).
 
 %----------------------------------------------------------------------------
-
-:- func optimize_func(opt_info, maybe(mlds__statement)) 
-		= maybe(mlds__statement).
 
-optimize_func(OptInfo, MaybeStatement) = 
-	maybe_apply(optimize_func_stmt(OptInfo), MaybeStatement).
+:- func optimize_func(opt_info, function_body) = function_body.
 
+optimize_func(_, external) = external.
+optimize_func(OptInfo, defined_here(Statement)) =
+	defined_here(optimize_func_stmt(OptInfo, Statement)).
 
-:- func optimize_func_stmt(opt_info, 
-	mlds__statement) = (mlds__statement).
+:- func optimize_func_stmt(opt_info, mlds__statement) = (mlds__statement).
 
 optimize_func_stmt(OptInfo, mlds__statement(Stmt0, Context)) = 
 		mlds__statement(Stmt, Context) :-
Index: compiler/ml_tailcall.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_tailcall.m,v
retrieving revision 1.9
diff -u -r1.9 ml_tailcall.m
--- compiler/ml_tailcall.m	2001/07/09 15:55:04	1.9
+++ compiler/ml_tailcall.m	2001/07/12 14:50:50
@@ -125,7 +125,7 @@
 		;
 			AtTail = no
 		),
-		FuncBody = mark_tailcalls_in_maybe_statement(FuncBody0,
+		FuncBody = mark_tailcalls_in_function_body(FuncBody0,
 			AtTail, Locals),
 		DefnBody = mlds__function(PredProcId, Params, FuncBody),
 		Defn = mlds__defn(Name, Context, Flags, DefnBody)
@@ -143,6 +143,14 @@
 		DefnBody = mlds__class(ClassDefn),
 		Defn = mlds__defn(Name, Context, Flags, DefnBody)
 	).
+
+:- func mark_tailcalls_in_function_body(function_body, at_tail, locals)
+		= function_body.
+
+mark_tailcalls_in_function_body(external, _, _) = external.
+mark_tailcalls_in_function_body(defined_here(Statement0), AtTail, Locals) =
+		defined_here(Statement) :-
+	Statement = mark_tailcalls_in_statement(Statement0, AtTail, Locals).
 
 :- func mark_tailcalls_in_maybe_statement(maybe(mlds__statement),
 		at_tail, locals) = maybe(mlds__statement).
Index: compiler/ml_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_util.m,v
retrieving revision 1.11
diff -u -r1.11 ml_util.m
--- compiler/ml_util.m	2001/06/22 09:14:34	1.11
+++ compiler/ml_util.m	2001/07/12 14:50:50
@@ -279,7 +279,7 @@
 
 defn_contains_foreign_code(NativeTargetLang, Defn) :-
 	Defn = mlds__defn(_Name, _Context, _Flags, Body),
-	Body = function(_, _, yes(FunctionBody)),
+	Body = function(_, _, defined_here(FunctionBody)),
 	statement_contains_statement(FunctionBody, Statement),
 	Statement = mlds__statement(Stmt, _),
 	( 
@@ -291,7 +291,7 @@
 
 defn_contains_outline_foreign_proc(ForeignLang, Defn) :-
 	Defn = mlds__defn(_Name, _Context, _Flags, Body),
-	Body = function(_, _, yes(FunctionBody)),
+	Body = function(_, _, defined_here(FunctionBody)),
 	statement_contains_statement(FunctionBody, Statement),
 	Statement = mlds__statement(Stmt, _),
 	Stmt = atomic(outline_foreign_proc(ForeignLang, _, _)).
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.61
diff -u -r1.61 mlds.m
--- compiler/mlds.m	2001/07/11 13:52:35	1.61
+++ compiler/mlds.m	2001/07/12 14:50:51
@@ -444,17 +444,21 @@
 			maybe(pred_proc_id),	% identifies the original
 						% Mercury procedure, if any
 			mlds__func_params,	% the arguments & return types
-			maybe(mlds__statement)	% the function body, or `no'
-						% if the function is abstract
-						% or if the function is defined
-						% externally (i.e. the original
-						% Mercury procedure was declared
-						% `:- external').
+			mlds__function_body	% the function body
+
 		)
 		% packages, classes, interfaces, structs, enums
 	;	mlds__class(
 			mlds__class_defn
 		).
+
+	% It is possible for the function to be defined externally
+	% (i.e. the original Mercury procedure was declared `:- external').
+	% (If you want to generate an abstract body consider adding another
+	% alternative here).
+:- type mlds__function_body 
+	--->	defined_here(mlds__statement)
+	;	external.
 
 	% Note that `one_copy' variables *must* have an initializer
 	% (the GCC back-end relies on this).
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.94
diff -u -r1.94 mlds_to_c.m
--- compiler/mlds_to_c.m	2001/07/10 14:49:14	1.94
+++ compiler/mlds_to_c.m	2001/07/12 14:50:52
@@ -1188,16 +1188,16 @@
 	).
 
 :- pred mlds_output_func(indent, qualified_entity_name, mlds__context,
-		func_params, maybe(statement), io__state, io__state).
+		func_params, function_body, io__state, io__state).
 :- mode mlds_output_func(in, in, in, in, in, di, uo) is det.
 
-mlds_output_func(Indent, Name, Context, Signature, MaybeBody) -->
+mlds_output_func(Indent, Name, Context, Signature, FunctionBody) -->
 	mlds_output_func_decl(Indent, Name, Context, Signature),
 	(
-		{ MaybeBody = no },
+		{ FunctionBody = external },
 		io__write_string(";\n")
 	;
-		{ MaybeBody = yes(Body) },
+		{ FunctionBody = defined_here(Body) },
 		io__write_string("\n"),
 
 		mlds_indent(Context, Indent),
@@ -1803,7 +1803,7 @@
 		{ Name \= type(_, _) },
 		% Don't output "static" for functions that don't have a body.
 		% This can happen for Mercury procedures declared `:- external'
-		{ DefnBody \= mlds__function(_, _, no) }
+		{ DefnBody \= mlds__function(_, _, external) }
 	->
 		io__write_string("static ")
 	;
Index: compiler/mlds_to_csharp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_csharp.m,v
retrieving revision 1.9
diff -u -r1.9 mlds_to_csharp.m
--- compiler/mlds_to_csharp.m	2001/07/11 10:24:37	1.9
+++ compiler/mlds_to_csharp.m	2001/07/12 14:50:52
@@ -195,7 +195,7 @@
 	_Context, _DeclFlags, Entity)) -->
 
 	( 
-		{ Entity = mlds__function(_, Params, yes(Statement)) },
+		{ Entity = mlds__function(_, Params, defined_here(Statement)) },
 		{ has_foreign_languages(Statement, Langs) },
 		{ list__member(csharp, Langs) }
 	->
Index: compiler/mlds_to_gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.44
diff -u -r1.44 mlds_to_gcc.m
--- compiler/mlds_to_gcc.m	2001/07/10 14:49:15	1.44
+++ compiler/mlds_to_gcc.m	2001/07/12 14:50:54
@@ -788,8 +788,8 @@
 		{ GlobalInfo = GlobalInfo0 ^ global_vars := GlobalVars }
 	;
 		{ DefnBody = mlds__function(_MaybePredProcId, Signature,
-			MaybeBody) },
-		gen_func(Name, Context, Flags, Signature, MaybeBody,
+			FunctionBody) },
+		gen_func(Name, Context, Flags, Signature, FunctionBody,
 			GlobalInfo0, GlobalInfo)
 	;
 		{ DefnBody = mlds__class(ClassDefn) },
@@ -1428,7 +1428,7 @@
 %
 
 :- pred gen_func(qualified_entity_name, mlds__context,
-		mlds__decl_flags, func_params, maybe(statement),
+		mlds__decl_flags, func_params, function_body,
 		global_info, global_info, io__state, io__state).
 :- mode gen_func(in, in, in, in, in, in, out, di, uo) is det.
 
@@ -1436,9 +1436,9 @@
 		GlobalInfo0, GlobalInfo) -->
 	{ GlobalInfo = GlobalInfo0 },
 	(
-		{ MaybeBody = no }
+		{ MaybeBody = external }
 	;
-		{ MaybeBody = yes(Body) },
+		{ MaybeBody = defined_here(Body) },
 		gcc__push_gc_context,
 		make_func_decl_for_defn(Name, Signature, GlobalInfo0,
 			FuncDecl, SymbolTable),
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.44
diff -u -r1.44 mlds_to_il.m
--- compiler/mlds_to_il.m	2001/07/11 13:10:18	1.44
+++ compiler/mlds_to_il.m	2001/07/12 14:51:14
@@ -265,13 +265,13 @@
 	= defn(Name, Context, Flags, Entity) :-
 	( Entity0 = data(Type, Initializer),
 		Entity = data(Type, rename_initializer(Initializer))
-	; Entity0 = function(MaybePredProcId, Params, MaybeStmt0),
-		( MaybeStmt0 = yes(Stmt),
-			MaybeStmt = yes(rename_statement(Stmt))
-		; MaybeStmt0 = no,
-			MaybeStmt = no
+	; Entity0 = function(MaybePredProcId, Params, FunctionBody0),
+		( FunctionBody0 = defined_here(Stmt),
+			FunctionBody = defined_here(rename_statement(Stmt))
+		; FunctionBody0 = external,
+			FunctionBody = external
 		),
-		Entity = function(MaybePredProcId, Params, MaybeStmt)
+		Entity = function(MaybePredProcId, Params, FunctionBody)
 	; Entity0 = class(_),
 		unexpected(this_file, "nested class")
 	).
@@ -833,9 +833,11 @@
 	il_info_get_next_block_id(BlockId),
 
 		% Generate the code of the statement.
-	( { MaybeStatement = yes(Statement) } -> 
+	( 
+		{ MaybeStatement = defined_here(Statement) },
 		statement_to_il(Statement, InstrsTree1)
-	;
+	; 
+		{ MaybeStatement = external },
 			% If there is no function body, generate
 			% forwarding code instead.  This can happen with
 			% :- external
Index: compiler/mlds_to_java.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_java.m,v
retrieving revision 1.9
diff -u -r1.9 mlds_to_java.m
--- compiler/mlds_to_java.m	2001/07/09 15:55:07	1.9
+++ compiler/mlds_to_java.m	2001/07/12 14:51:15
@@ -423,7 +423,7 @@
 		Name0 = function(_Label0, ProcID, MaybeSeqNum, PredID),
 		Body0 = mlds__function(MaybeID, Params0, 
 			MaybeStatements0),
-		MaybeStatements0 = yes(Statements0),
+		MaybeStatements0 = defined_here(Statements0),
 		Statements0 = mlds__statement(
 			block(BlockDefns0, _BlockList0), _) 
 	->
@@ -459,7 +459,8 @@
 		% Put it all together.
 		%
 		Params = mlds__func_params(Args, RetTypes),
-		Body   = mlds__function(MaybeID, Params, yes(Statements)),
+		Body   = mlds__function(MaybeID, Params,
+			defined_here(Statements)),
 		Flags  = ml_gen_special_member_decl_flags,	
 		Defn   = mlds__defn(Name, Context, Flags, Body) 
 	;
@@ -977,16 +978,16 @@
 	).
 
 :- pred output_func(indent, qualified_entity_name, mlds__context,
-		func_params, maybe(statement), io__state, io__state).
+		func_params, function_body, io__state, io__state).
 :- mode output_func(in, in, in, in, in, di, uo) is det.
 
 output_func(Indent, Name, Context, Signature, MaybeBody) -->
 	output_func_decl(Indent, Name, Context, Signature),
 	(
-		{ MaybeBody = no },
+		{ MaybeBody = external },
 		io__write_string(";\n")
 	;
-		{ MaybeBody = yes(Body) },
+		{ MaybeBody = defined_here(Body) },
 		io__write_string("\n"),
 		indent_line(Context, Indent),
 		io__write_string("{\n"),
Index: compiler/mlds_to_mcpp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_mcpp.m,v
retrieving revision 1.10
diff -u -r1.10 mlds_to_mcpp.m
--- compiler/mlds_to_mcpp.m	2001/07/11 10:24:37	1.10
+++ compiler/mlds_to_mcpp.m	2001/07/12 14:51:15
@@ -210,7 +210,8 @@
 		defn(function(PredLabel, ProcId, MaybeSeqNum, _PredId), 
 	_Context, _DeclFlags, Entity)) -->
 	( 
-		{ Entity = mlds__function(_, Params, yes(Statement)) },
+		{ Entity = mlds__function(_, Params,
+			defined_here(Statement)) },
 		( 
 			{ has_inline_target_code_statement(Statement) }
 		;
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.208
diff -u -r1.208 reference_manual.texi
--- doc/reference_manual.texi	2001/06/13 04:28:17	1.208
+++ doc/reference_manual.texi	2001/07/12 14:52:54
@@ -49,6 +49,7 @@
 @author Peter Schachte
 @author Simon Taylor
 @author Chris Speirs
+ at author Tyson Speirs
 @page
 @vskip 0pt plus 1filll
 Copyright @copyright{} 1995-2001 The University of Melbourne.
@@ -96,6 +97,8 @@
                       collections.
 * Semantics::         Declarative and operational semantics of Mercury
                       programs.
+* Foreign language interface:: The foreign language interface allows
+		      C code to be called from Mercury code.
 * C interface::       The C interface allows C code to be called
                       from Mercury code, and vice versa.
 * Impurity::          Users can write impure Mercury code.
@@ -4672,6 +4675,119 @@
 For example, they may wish to provide semantics in which function
 evaluation is lazy, rather than strict; semantics with a guaranteed
 fair search rule; and so forth.
+
+ at node Foreign language interface
+ at chapter Foreign language interface
+
+ at menu
+* Calling foreign code from Mercury::   How to implement a Mercury predicate
+					or function as a call to foreign
+					lanugage code.
+ at end menu
+
+ at node Calling foreign code from Mercury
+ at section Calling foreign code from Mercury
+
+ at c we have no multi-language import mechanism at the moment.
+
+Mercury procedures can be implemented using fragments of foreign language
+code using @samp{pragma foreign_proc}.
+
+ at menu
+* pragma foreign_code::         Defining Mercury procedures using foreign code.
+ at end menu
+
+ at node pragma foreign_code
+ at subsection pragma foreign_code
+
+A declaration of the form
+
+ at example
+:- pragma foreign_proc("@var{Lang}", @var{Pred}(@var{Var1}::@var{Mode1}, @var{Var2}::@var{Mode2}, @dots{}),
+        @var{Attributes}, @var{Foreign_Code}).
+ at end example
+
+ at noindent
+or
+
+ at example
+:- pragma foreign_proc("@var{Lang}", @var{Func}(@var{Var1}::@var{Mode1}, @var{Var2}::@var{Mode2}, @dots{}) = (@var{Var}::@var{Mode}),
+        @var{Attributes}, @var{Foreign_Code}).
+ at end example
+
+ at noindent
+means that any calls to the specified mode of @var{Pred} or @var{Func}
+will result in execution of the foreign code given in @var{Foreign_Code}
+written in language @var{Lang}.
+The foreign code fragment may refer to the specified variables
+(@var{Var1}, @var{Var2}, @dots{}, and @var{Var})
+directly by name.  These variables will have foreign language types
+corresponding to their Mercury types, as determined by language and
+implementation specific rules.
+It is an error for a variable to occur more than once in the argument list.
+
+Additional restrictions on the foreign language interface code
+depend on the foreign language, the backend target, and the implementation.
+For more information, including the list of supported foreign languages and 
+the strings used to identify them, see the ``Foreign Language Interfaces''
+chapter of the Mercury User's Guide.
+
+If there is a @code{pragma foreign_proc} declaration for a
+mode of a predicate or function, then there must not be any clauses for that
+predicate or function, and there must be a @code{pragma foreign_proc} 
+ at c or @code{pragma import} 
+declaration for every mode of the predicate or function.
+
+For example, the following piece of code defines a Mercury function
+ at samp{sin/1} which calls the C function @samp{sin()} of the same name.
+
+ at example
+:- func sin(float) = float.
+:- pragma foreign_proc("C", sin(X::in) = (Sin::out),
+        [may_call_mercury],
+        "Sin = sin(X);").
+ at end example
+
+If the C code does not recursively invoke Mercury code,
+as in the above example, then you can use @samp{will_not_call_mercury}
+in place of @samp{may_call_mercury} in the declarations above.
+This allows the compiler to use a slightly more efficient calling convention.
+(If you use this form, and the C code @emph{does} invoke Mercury code,
+then the behaviour is undefined --- your program may misbehave or crash.)
+
+ at c XXX TYSE UP TO HERE
+ at c Move this to the User's Guide
+ at c
+The C code in a @code{pragma c_code} declaration
+for any procedure whose determinism indicates that it could fail
+must assign a truth value to the macro @samp{SUCCESS_INDICATOR}.
+For example:
+
+ at example
+:- pred string__contains_char(string, character).
+:- mode string__contains_char(in, in) is semidet.
+
+:- pragma c_code(string__contains_char(Str::in, Ch::in),
+        [will_not_call_mercury],
+        "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
+ at end example
+
+ at code{SUCCESS_INDICATOR} should not be used other than as the target of
+an assignment.
+(For example, it may be @code{#define}d to a register, so you should not
+try to take its address.) 
+Procedures whose determinism indicates that that they cannot fail
+should not access @code{SUCCESS_INDICATOR}.
+
+Arguments whose mode is input will have their values set by the
+Mercury implementation on entry to the C code.  If the procedure
+succeeds, the C code must set the values of all output arguments
+before returning.  If the procedure fails, the C code need only
+set @code{SUCCESS_INDICATOR} to false (zero).
+
+
+ at c -----------------------------------------------------------------------
+
 
 @node C interface
 @chapter C interface


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list