[m-dev.] for review: pragma foreign_code for MC++ (part 1/2)

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Nov 15 18:35:05 AEDT 2000


On 10-Nov-2000, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> +handle_return_value(CodeModel, PredOrFunc, Args0, ModuleInfo, Args, C_Code0) :-
...
> +	; CodeModel = model_semi,
> +		% we treat semidet functions the same as semidet predicates,
> +		% which means that for Mercury functions the Mercury return
> +		% value becomes the last argument, and the C return value
> +		% is a bool that is used to indicate success or failure.
> +		C_Code0 = "SUCCESS_INDICATOR = ",
> +		Args2 = Args0

After Zoltan's MR_ prefix change, that should perhaps become
MR_SUCCESS_INDICATOR.  Be careful with cvs merging here.

> Index: compiler/globals.m
...
> +convert_foreign_language("C", c).
> +convert_foreign_language("c", c).
> +convert_foreign_language("MC++", managedcplusplus).
> +convert_foreign_language("mc++", managedcplusplus).
...
> +foreign_language_string(managedcplusplus) = "MC++".

Hmm, "MC++" is a bit cryptic for those who don't know what it means.
It might be good to also allow a longer version which spells out the
name more fully, e.g. "Managed C++".

> +globals__io_lookup_foreign_language_option(Option, ForeignLang) -->
> +	globals__io_lookup_string_option(Option, String),
> +	{ convert_foreign_language(String, ForeignLang0) ->
> +		ForeignLang = ForeignLang0
> +	;
> +		error("globals__io_lookup_foreign_language_option: invalid foreign_language option")
> +	}.

There doesn't seem to be any code in your change which would prevent
that from calling error/1 if the user types in the wrong name.

You should add some code somewhere (probably in handle_options.m) to
check that the value specified for the --use-foreign-language option
is actually a valid language option, and if not you should report a
nice readable error message.

> +++ compiler/handle_options.m	2000/11/09 05:35:17
> @@ -568,6 +568,32 @@
>  	% we are expecting some to be missing.
>  	option_implies(use_opt_files, warn_missing_opt_files, bool(no)),
>  
> +
> +	% The preferred backend foreign language depends on the target.
> +	( 	
> +		{ Target = c },
> +		{ BackendForeignLanguage = "c" }
> +	;
> +		{ Target = il },
> +		{ BackendForeignLanguage = "mc++" }
> +	;
> +		% we don't generate java or handle it as a foreign
> +		% language just yet, but if we did...
> +		{ Target = java },
> +		{ BackendForeignLanguage = "java" }
> +	),

It would be better to use the canonical names here.  The canonical
names should be the ones that are properly capitalized.
Also if there are long and short alternatives (i.e.
"Managed C++" vs "MC++", you should use the long alternative here.

> +	globals__io_set_option(backend_foreign_language,
> +		string(BackendForeignLanguage)),
> +	% The default foreign language we use is the same as the backend.
> +	globals__io_lookup_string_option(use_foreign_language,
> +		UseForeignLanguage),
> +	( { UseForeignLanguage = "" } ->
> +		globals__io_set_option(use_foreign_language, 
> +			string(BackendForeignLanguage))
> +	;
> +		[]
> +	),

It would be no harder, I think, to make use_foreign_language an
accumulating list(string) option, thus allowing the user to give a
list of the languages desired in order of preference, rather than a
single string.

E.g. here instead of that if-then-else you can just have

	globals__io_lookup_string_option(use_foreign_language,
		UseForeignLanguage),
	globals__io_set_option(use_foreign_language, 
		UseForeignLanguage ++ [BackendForeignLanguage])

> +++ compiler/make_hlds.m	2000/11/08 06:39:31
> @@ -400,16 +400,17 @@
...
>  		% Handle pragma c_code decls later on (when we process
>  		% clauses).
> -		{ Pragma = foreign(_, _, _, _, _, _, _) },
> +		{ Pragma = foreign(_, _, _, _, _, _) },

The comment there has suffered documentation rot;
it should say something about foreign code, not c_code.

> +module_add_pragma_foreign_code(Attributes, PredName, PredOrFunc,
...
> +	globals__io_lookup_foreign_language_option(use_foreign_language,
> +		UseForeignLang),
...

To continue with my earlier remarks, that could be

	globals__get_foreign_languages_to_use(ForeignLangsToUse),

>  	;
> +			% Don't add clauses for foreign languages other
> +			% than the one we are using.
> +		{ foreign_language(Attributes, PragmaForeignLanguage) },
> +		{ UseForeignLang \= PragmaForeignLanguage }
> +	->

and that could be

		{ foreign_language(Attributes, PragmaForeignLanguage) },
		{ \+ list__member(PragmaForeignLanguage, ForeignLangsToUse) }
	->

> -warn_singletons_in_goal_2(pragma_foreign_code(_, _, _, _, _, ArgInfo, _,
> +warn_singletons_in_goal_2(pragma_foreign_code(_, _, _, _, ArgInfo, _,
>  		PragmaImpl), GoalInfo, _QuantVars, _VarSet, PredCallId, MI) --> 
>  	{ goal_info_get_context(GoalInfo, Context) },
>  	% XXX not just C code
> -	warn_singletons_in_pragma_c_code(PragmaImpl, ArgInfo, Context, 
> +	warn_singletons_in_pragma_foreign_code(PragmaImpl, ArgInfo, Context, 
>  		PredCallId, MI).

Is the XXX still needed?

> +	% warn_singletons_in_pragma_foreign_code checks to see if each
> +	% variable is mentioned at least once in the foreign code
> +	% fragments that ought to mention it. If not, it gives a
> +	% warning.
> +	% (note that for some foreign languages it might not be
> +	% appropriate to do this check, or you may been to add a
> +	% transformation to map Mercury variable names into identifiers
> +	% for that foreign language).

s/been/need/ ?

s/(note/(Note/

> +:- pred warn_singletons_in_pragma_foreign_code(pragma_foreign_code_impl,
>  	list(maybe(pair(string, mode))), prog_context, simple_call_id,
>  	module_info, io__state, io__state).
> -:- mode warn_singletons_in_pragma_c_code(in, in, in, in, in, di, uo) is det.
> +:- mode warn_singletons_in_pragma_foreign_code(in, in, in, in, in,
> +	di, uo) is det.
>  
> -warn_singletons_in_pragma_c_code(PragmaImpl, ArgInfo, 
> +warn_singletons_in_pragma_foreign_code(PragmaImpl, ArgInfo, 
>  		Context, PredOrFuncCallId, ModuleInfo) -->
>  	(
>  		{ PragmaImpl = ordinary(C_Code, _) },
> @@ -4848,18 +4688,18 @@
>  			io__stderr_stream(StdErr1),
>  			io__set_output_stream(StdErr1, OldStream1),
>  			prog_out__write_context(Context),
> -			io__write_string("In `:- pragma c_code' for "),
> +			io__write_string("In `:- pragma foreign_code' for "),
>  			hlds_out__write_simple_call_id(PredOrFuncCallId),
>  			io__write_string(":\n"),
>  			prog_out__write_context(Context),
>  			( { UnmentionedVars = [_] } ->
>  				io__write_string("  warning: variable `"),
>  				write_string_list(UnmentionedVars),
> -				io__write_string("' does not occur in the C code.\n")
> +				io__write_string("' does not occur in the foreign code.\n")

I think it would be nicer to say "in the %s code", where %s is
the name of the language, rather than "in the foreign code".

>  			;
>  				io__write_string("  warning: variables `"),
>  				write_string_list(UnmentionedVars),
> -				io__write_string("' do not occur in the C code.\n")
> +				io__write_string("' do not occur in the foreign code.\n")

Likewise here.

> +:- pred clauses_info_add_pragma_foreign_code(
> +	clauses_info, purity, pragma_foreign_code_attributes, pred_id,
> +	proc_id, prog_varset, list(pragma_var), list(type),
> +	pragma_foreign_code_impl, prog_context, pred_or_func, sym_name,
> +	arity, clauses_info, module_info, module_info, qual_info,
> +	qual_info, io__state, io__state) is det.
> +:- mode clauses_info_add_pragma_foreign_code(in, in, in, in, in, in, in,
> +	in, in, in, in, in, in, out, in, out, in, out, di, uo) is det.

I think it would be better to use the combined pred-mode declaration
syntax here.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list