[m-dev.] for review: nondet pragma C codes (part 1 of 2)

Fergus Henderson fjh at cs.mu.oz.au
Fri Jan 9 18:29:29 AEDT 1998


On 09-Jan-1998, Zoltan Somogyi <zs at cs.mu.oz.au> wrote:
> 
> compiler/{mercury_compile.m,modules.m}:
> 	Add a missing period after some progress messages.

That should be committed seperately.

> compiler/Mmakefile:
> 	Incidental change: add a new target "debug" that makes both the
> 	compiled and the SICStus versions of the compiler.

Ditto.

> -code_gen__generate_prolog(CodeModel, FrameInfo, PrologCode) -->
> +code_gen__generate_prolog(CodeModel, Goal, FrameInfo, PrologCode) -->
...
> +		(
> +			{ Goal = pragma_c_code(_,_,_,_,_,_, PragmaCode) - _},
> +			{ PragmaCode = nondet(Fields, FieldsContext,
> +				_,_,_,_,_,_,_) }
> +		->
> +			{ pragma_c_gen__struct_name(ModuleName, PredName,
> +				Arity, ProcId, StructName) },
> +			{ Struct = pragma_struct(StructName,
> +				Fields, FieldsContext) },
> +			{ string__format("#define\tMR_ORDINARY_SLOTS\t%d\n",
> +				[i(TotalSlots)], DefineStr) },
> +			{ DefineComps = [pragma_c_raw_code(DefineStr)] },
> +			{ AllocCode = node([
> +				mkframe(PushMsg, TotalSlots, yes(Struct),
> +					do_fail)
> +					- "Allocate stack frame",
> +				pragma_c([], DefineComps,
> +					will_not_call_mercury, no)
> +					- ""

Could you please use a more informative name than `DefineComps'?
(It took me a fair while to figure out what `Comps' stood for.)

> +	{ FrameInfo = frame(TotalSlots, MaybeSuccipSlot, NondetPragma) },
> +	( { NondetPragma = yes } ->
> +		{ UndefStr = "#undef\tMR_ORDINARY_SLOTS\n" },
> +		{ UndefComps = [pragma_c_raw_code(UndefStr)] },

Ditto here for `UndefComps'.

Also, would it be reasonable to split some of the code in generate_prolog
and generate_epilogue out into subroutines?  They're getting pretty long.

>  	;	pragma_c_code(
> -			string,		% The C code to do the work
>  			may_call_mercury,
>  					% Can the C code recursively
>  					% invoke Mercury code?
>  			pred_id,	% The called predicate
>  			proc_id, 	% The mode of the predicate
>  			list(var),	% The (Mercury) argument variables
> -			list(maybe(string)),
> -					% C variable names for each of the
> +			list(maybe(pair(string, mode))),
> +					% C variable names and the original
> +					% mode declaration for each of the
>  					% arguments. A no for a particular 
>  					% argument means that it is not used
>  					% by the C code.  (In particular, the
> @@ -173,25 +173,13 @@
>  			list(type),	% The original types of the arguments.
>  					% (With inlining, the actual types may
>  					% be instances of the original types.)
> -			extra_pragma_info
> -					% Extra information for model_non
> -					% pragma_c_codes; none for others.
> +			pragma_code	% Info about the code that does the
> +					% actual work.

Hmm, `pragma_code' is a bit too general a name.
I would prefer something like `pragma_c_code_info'
or `pragma_c_code' or `pragma_foreign_code'.

> +++ llds.m	1998/01/06 08:09:03
> @@ -126,9 +126,17 @@
> +	;	mkframe(string, int, maybe(pragma_struct), code_addr)
> +			% mkframe(Comment, SlotCount, MaybePragmaStruct,
> +			% FailureContinuation) creates a nondet stack frame.
> +			% Comment says what predicate creates the frame.
> +			% SlotCount says how many ordinary framevar slots
> +			% it ought to have. If MaybePragmaStruct is yes,
> +			% the argument gives the details of the structure
> +			% which occupies the rest of the framevar slots.
> +			% CodeAddr is the code address to branch to when
> +			% trying to generate the next solution from this
> +			% choice point.

I think `pragma_struct' should be named `pragma_c_struct'
or something like that.

> +:- type pragma_struct
> +	--->	pragma_struct(
> +			string,		% The name of the struct tag.
> +			string,		% The field declarations, supplied
> +					% by the user in the program.
> +			term__context	% Where the field declarations
> +					% originally appeared.
> +		).

Some documentation here about what this type is used for would be helpful.

Also s/program/`pragma c_code' declaration/.

> +output_instruction_decls(mkframe(_, _, MaybeStruct, FailureContinuation),
>  		DeclSet0, DeclSet) -->
> +	(
> +		{ MaybeStruct = yes(pragma_struct(StructName,
> +			StructFields, StructFieldsContext)) }
> +	->
> +		{ set__member(pragma_struct(StructName), DeclSet0) ->
> +			string__append_list(["struct ", StructName, " has been declared already"], Msg),
> +			error(Msg)

Please insert "llds_out.m: " at the start of the error message.

> +:- pred output_pragma_component_list_decls(list(pragma_c_component),
> +	decl_set, decl_set, io__state, io__state).
> +:- mode output_pragma_component_list_decls(in, in, out, di, uo) is det.
> +
> +output_pragma_component_list_decls([], DeclSet, DeclSet) --> [].
> +output_pragma_component_list_decls([Component | Components],
>  		DeclSet0, DeclSet) -->
> -	output_pragma_input_rval_decls(Inputs, DeclSet0, DeclSet1),
> -	output_pragma_output_lval_decls(Outputs, DeclSet1, DeclSet).
> +	output_pragma_component_decls(Component, DeclSet0, DeclSet1),
> +	output_pragma_component_list_decls(Components, DeclSet1, DeclSet).
> +
> +:- pred output_pragma_component_decls(pragma_c_component,
> +	decl_set, decl_set, io__state, io__state).
> +:- mode output_pragma_component_decls(in, in, out, di, uo) is det.
> +
> +output_pragma_component_decls(pragma_c_inputs(Inputs), DeclSet0, DeclSet) -->
> +	output_pragma_input_rval_decls(Inputs, DeclSet0, DeclSet).
> +output_pragma_component_decls(pragma_c_outputs(Outputs), DeclSet0, DeclSet) -->
> +	output_pragma_output_lval_decls(Outputs, DeclSet0, DeclSet).
> +output_pragma_component_decls(pragma_c_raw_code(_), DeclSet, DeclSet) --> [].
> +output_pragma_component_decls(pragma_c_user_code(_, _), DeclSet, DeclSet)
> +		--> [].

I suggest s/pragma/pragma_c/g

> +:- pred output_pragma_components(list(pragma_c_component),
> +	io__state, io__state).
> +:- mode output_pragma_components(in, di, uo) is det.
> +
> +output_pragma_components([]) --> [].
> +output_pragma_components([C | Cs]) -->
> +	output_pragma_component(C),
> +	output_pragma_components(Cs).
> +
> +:- pred output_pragma_component(pragma_c_component, io__state, io__state).
> +:- mode output_pragma_component(in, di, uo) is det.

Ditto.

> +output_pragma_component(pragma_c_inputs(Inputs)) -->
> +	output_pragma_inputs(Inputs).
> +output_pragma_component(pragma_c_outputs(Outputs)) -->
> +	output_pragma_outputs(Outputs).
> +output_pragma_component(pragma_c_user_code(Context0, C_Code)) -->
> +	( { C_Code = "" } ->
> +		[]
> +	;
> +			% We should start the C_Code on a new line,
> +			% just in case it starts with a proprocessor directive.
> +			% We must then account for the effect of the \n
> +			% on the context.
> +		{ Context0 = term__context(File, Line0) },
> +		{ Line is Line0 - 1 },
> +		{ Context = term__context(File, Line) },
> +		output_set_line_num(Context),
> +		io__write_string("{\t\t\n"),
> +		io__write_string(C_Code),

Change the above 10 lines to
		io__write_string("{\n"),
		output_set_line_num(Context),
		io__write_string(C_Code),

> +	% We never insert unifications of the form X = X.
> +	% If ForPragmaC is yes, we process unifications of the form
> +	% X = Y by substituting the var expected by the outside environment
> +	% (the head variable) for the variable inside the goal (which was
> +	% created just for the pragma_c_code goal), while giving the headvar
> +	% the name of the just eliminated variable. The result is will be

"is", "will be" -- please choose one ;-)

>  			% Should this be insert_... rather than append_...?
>  			% No, because that causes efficiency problems
> -			% with type-checking :-(
> +			% with type-checking :-|

?

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list