[m-dev.] New syntax proposal

Thomas Charles CONWAY conway at cs.mu.oz.au
Mon Oct 6 18:33:54 AEST 1997


Fergus Henderson, you write:
> Thomas Charles CONWAY, you wrote:
> > 
> > The following diff proposes new syntax for higher-order pred expressions
> > with DCG syntax. Comments on the new syntax very welcome.
> 
> > 	Pred = (pred(Arg1::Mode1, ..., ArgN::ModeN, DCGMode0, DCGMode1) is Det
> > 			--> Goal)
> 
> That syntax is OK with me.
> 
> > Index: compiler/prog_io_dcg.m
> 
> > +:- pred parse_dcg_pred_goal(term, varset, goal, var, var, varset).
> > +:- mode parse_dcg_pred_goal(in, in, out, out, out, out) is det.
> 
> You should document this predicate.
> 

Done.

> 
> The reference manual should define the syntax and semantics of language constructs;
> just giving an example is not sufficiently precise.
> 
> The syntax needs to be defined in the "Data-terms" section of the "Syntax" chapter.
> The semantics should probably be given there too, using the "DCG-transform" function
> defined in the "DCG-Rules" section.
> 

Done.

Full diff follows...
-- 
ZZ:wq!
^X^C
Thomas Conway               				      conway at cs.mu.oz.au
AD DEUM ET VINUM	  			      Every sword has two edges.


This change adds some new syntax for higher-order pred expressions
that use DCG notation. The newly accepted expressions have the form:

	Pred = (pred(Arg1::Mode1, ..., ArgN::ModeN, DCGMode0, DCGMode1) is Det
			--> Goal)

compiler/prog_io_goal.m:
	add a predicate for parsing dcg pred expressions.

compiler/prog_io_dcg.m:
	add an interface predicate for parsing dcg goals.

compiler/make_hlds.m:
	detect and expand higher-order dcg pred expressions.

doc/reference_manual.texi:
	mention the new syntax in the section on higher-order.

NEWS:
	mention the new syntax.

cvs diff: Diffing .
Index: NEWS
===================================================================
RCS file: /home/staff/zs/imp/mercury/NEWS,v
retrieving revision 1.77
diff -u -r1.77 NEWS
--- NEWS	1997/10/04 06:49:29	1.77
+++ NEWS	1997/10/06 05:56:41
@@ -102,3 +102,7 @@
   for providing the original version. 
 
 * We've added a new predicate to bag.m, bag__to_list/2.
+
+* We've introduced new syntax to allow higher-order predicate expressions
+  to use DCG notation.
+
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/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing bytecode/test
cvs diff: Diffing compiler
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/make_hlds.m,v
retrieving revision 1.240
diff -u -r1.240 make_hlds.m
--- make_hlds.m	1997/09/30 14:54:24	1.240
+++ make_hlds.m	1997/10/06 02:01:53
@@ -56,8 +56,8 @@
 
 :- implementation.
 
-:- import_module prog_io, prog_io_goal, prog_io_util, prog_out, hlds_out.
-:- import_module module_qual, prog_util, globals, options.
+:- import_module prog_io, prog_io_goal, prog_io_dcg, prog_io_util, prog_out.
+:- import_module module_qual, prog_util, globals, options, hlds_out.
 :- import_module make_tags, quantification, (inst).
 :- import_module code_util, unify_proc, special_pred, type_util, mode_util.
 :- import_module mercury_to_mercury, passes_aux, clause_to_proc, inst_match.
@@ -2803,6 +2803,34 @@
 			HLDS_Goal0, VarSet3, HLDS_Goal, VarSet, Info2, Info),
 		{ create_atomic_unification(X,
 			lambda_goal(predicate, Vars, Modes, Det, HLDS_Goal),
+			Context, MainContext, SubContext, Goal) }
+	;
+	    {
+		% handle higher-order dcg pred expressions -
+		% same semantics as higher-order pred expressions,
+		% but has two extra arguments, and the goal is expanded
+		% as a DCG goal.
+		F = term__atom("-->"),
+		Args = [PredTerm, GoalTerm],
+		parse_dcg_pred_expression(PredTerm, Vars0, Modes0, Det)
+	    }
+	->
+		{ qual_info_get_mq_info(Info0, MQInfo0) },
+		module_qual__qualify_lambda_mode_list(Modes0, Modes, Context,
+			MQInfo0, MQInfo1),
+		{ qual_info_set_mq_info(Info0, MQInfo1, Info1) },
+		{ parse_dcg_pred_goal(GoalTerm, VarSet0, ParsedGoal,
+			DCG0, DCGn, VarSet1) },
+		{ make_fresh_arg_vars(Vars1, VarSet1, Vars, VarSet2) },
+		{ list__append(Vars0,
+			[term__variable(DCG0), term__variable(DCGn)], Vars1) },
+		{ map__init(Substitution) },
+		transform_goal(ParsedGoal, VarSet2, Substitution,
+			HLDS_Goal0, VarSet3, Info1, Info2),
+		insert_arg_unifications(Vars, Vars1, Context, head,
+			HLDS_Goal0, VarSet3, HLDS_Goal, VarSet, Info2, Info),
+		{ create_atomic_unification(X,
+		lambda_goal(predicate, Vars, Modes, Det, HLDS_Goal),
 			Context, MainContext, SubContext, Goal) }
 	;
 	    {
Index: compiler/prog_io_dcg.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_dcg.m,v
retrieving revision 1.5
diff -u -r1.5 prog_io_dcg.m
--- prog_io_dcg.m	1997/07/27 15:01:27	1.5
+++ prog_io_dcg.m	1997/10/06 07:48:39
@@ -21,6 +21,15 @@
 			maybe_item_and_context).
 :- mode parse_dcg_clause(in, in, in, in, in, out) is det.
 
+	% parse_dcg_pred_goal(GoalTerm, VarSet0, Goal,
+	%	DCGVarInitial, DCGVarFinal, Varset)
+	% parses `GoalTerm' and expands it as a DCG goal,
+	% `VarSet0' is the initial varset, and `VarSet' is
+	% the final varset. `DCGVarInitial' is the first DCG variable,
+	% and `DCGVarFinal' is the final DCG variable.
+:- pred parse_dcg_pred_goal(term, varset, goal, var, var, varset).
+:- mode parse_dcg_pred_goal(in, in, out, out, out, out) is det.
+
 :- implementation.
 
 :- import_module prog_io_goal, prog_util, prog_data.
@@ -37,6 +46,13 @@
 			HeadResult),
 	process_dcg_clause(HeadResult, VarSet, DCG_0_Var, DCG_Var, Body, R),
 	add_context(R, DCG_Context, Result).
+
+%-----------------------------------------------------------------------------%
+
+parse_dcg_pred_goal(GoalTerm, VarSet0, Goal, DCGVar0, DCGVar, VarSet) :-
+	new_dcg_var(VarSet0, 0, VarSet1, N0, DCGVar0),
+	parse_dcg_goal(GoalTerm, VarSet1, N0, DCGVar0,
+			Goal, VarSet, _N, DCGVar).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/prog_io_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_io_goal.m,v
retrieving revision 1.5
diff -u -r1.5 prog_io_goal.m
--- prog_io_goal.m	1997/07/27 15:01:28	1.5
+++ prog_io_goal.m	1997/10/06 06:57:53
@@ -49,6 +49,17 @@
 :- pred parse_pred_expression(term, list(term), list(mode), determinism).
 :- mode parse_pred_expression(in, out, out, out) is semidet.
 
+	% parse_dcg_pred_expression/3 converts the first argument to a -->/2
+	% higher-order dcg pred expression into a list of variables, a list
+	% of their corresponding modes and the two dcg argument modes, and a
+	% determinism.
+	% This is a variant of the higher-order pred syntax:
+	%	`(pred(Var1::Mode1, ..., VarN::ModeN, DCG0Mode, DCGMode)
+	%		is Det --> Goal)'.
+	%
+:- pred parse_dcg_pred_expression(term, list(term), list(mode), determinism).
+:- mode parse_dcg_pred_expression(in, out, out, out) is semidet.
+
 	% parse_func_expression/3 converts the first argument to a :-/2
 	% higher-order func expression into a list of variables, a list
 	% of their corresponding modes, and a determinism.  The syntax
@@ -276,6 +287,13 @@
 	PredArgsTerm = term__functor(term__atom("pred"), PredArgsList, _),
 	parse_pred_expr_args(PredArgsList, Vars, Modes).
 
+parse_dcg_pred_expression(PredTerm, Vars, Modes, Det) :-
+	PredTerm = term__functor(term__atom("is"), [PredArgsTerm, DetTerm], _),
+	DetTerm = term__functor(term__atom(DetString), [], _),
+	standard_det(DetString, Det),
+	PredArgsTerm = term__functor(term__atom("pred"), PredArgsList, _),
+	parse_dcg_pred_expr_args(PredArgsList, Vars, Modes).
+
 parse_func_expression(FuncTerm, Vars, Modes, Det) :-
 	%
 	% parse a func expression with specified modes and determinism
@@ -316,6 +334,21 @@
 parse_pred_expr_args([Term|Terms], [Arg|Args], [Mode|Modes]) :-
 	parse_lambda_arg(Term, Arg, Mode),
 	parse_pred_expr_args(Terms, Args, Modes).
+
+	% parse_dcg_pred_expr_args is like parse_pred_expr_args except
+	% that the last two elements of the list are the modes of the
+	% two dcg arguments.
+:- pred parse_dcg_pred_expr_args(list(term), list(term), list(mode)).
+:- mode parse_dcg_pred_expr_args(in, out, out) is semidet.
+
+parse_dcg_pred_expr_args([DCGModeTerm0, DCGModeTerm1], [],
+		[DCGMode0, DCGMode1]) :-
+	convert_mode(DCGModeTerm0, DCGMode0),
+	convert_mode(DCGModeTerm1, DCGMode1).
+parse_dcg_pred_expr_args([Term|Terms], [Arg|Args], [Mode|Modes]) :-
+	Terms = [_, _|_],
+	parse_lambda_arg(Term, Arg, Mode),
+	parse_dcg_pred_expr_args(Terms, Args, Modes).
 
 %-----------------------------------------------------------------------------%
 
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/reference_manual.texi,v
retrieving revision 1.73
diff -u -r1.73 reference_manual.texi
--- reference_manual.texi	1997/09/27 19:53:41	1.73
+++ reference_manual.texi	1997/10/06 08:24:00
@@ -681,6 +681,7 @@
 @example
 lambda([Var1::Mode1, Var2::Mode2, @dots{}] is Det, Goal)
 pred(Var1::Mode1, Var2::Mode2, @dots{}) is Det :- Goal
+pred(Var1::Mode1, Var2::Mode2, @dots{}, DCGMode0, DCGMode1) is Det --> DCGGoal
 func(Var1::Mode1, Var2::Mode2, @dots{}) = (Var::Mode) is Det :- Goal
 func(Var1, Var2, @dots{}) = Var :- Goal
 @end example
@@ -688,13 +689,34 @@
 @noindent
 where Var1, Var2, @dots{} are zero or more variables,
 Mode1, Mode2, @dots{} are zero or more modes (@pxref{Modes}),
+DCGMode0 and DCGMode1 are modes (@pxref{Modes}),
 Det is a determinism (@pxref{Determinism}),
-and Goal is a goal (@pxref{Goals}). 
+Goal is a goal (@pxref{Goals}),
+and DCGGoal is a DCG Goal (@pxref{DCG-goals}). 
 The @samp{:- Goal} part is optional;
 if it is not specified, then @samp{:- true} is assumed.
 A lambda expression denotes a higher-order predicate or function term
 whose value is the predicate or function of the specified arguments
 determined by the specified goal.
+The form of lambda expression using @samp{-->} as its top level functor
+is a syntactic abbreviation: an expression of the form
+
+ at example
+pred(Var1::Mode1, Var2::Mode2, @dots{}, DCGMode0, DCGMode1) is Det --> DCGGoal
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+pred(Var1::Mode1, Var2::Mode2, @dots{},
+    DCGVar0::DCGMode0, DCGVar1::DCGMode1) is Det :- Goal
+ at end example
+
+ at noindent
+where DCGVar0 and DCGVar1 are fresh variables,
+and Goal is the result of @samp{DCG-transform(DCGVar0, DCGVar1, DCGGoal)}
+where DCG-transform is the function specified in @pxref{DCG-goals}.
 @xref{Higher-order}.
 
 A higher-order function application is a compound term of one
@@ -2136,6 +2158,31 @@
 @noindent
 binds @samp{Double} to a higher-order function term of type
 @samp{func(list(int)) = list(int)}.
+
+For higher-order predicate expressions that thread an accumulator
+pair, we have syntax that allows you to use DCG notation in the
+goal of the expression.  For example,
+
+ at example
+Pred = (pred(Strings::in, Num::out, di, uo) is det -->
+    io__write_string("The strings are: "),
+    @{ list__length(Strings, Num) @},
+    io__write_strings(Strings),
+    io__nl
+)
+ at end example
+
+ at noindent
+is equivalent to
+
+ at example
+Pred = (pred(Strings::in, Num::out, IO0::di, IO::uo) is det -->
+    io__write_string("The strings are: ", IO0, IO1),
+    list__length(Strings, Num),
+    io__write_strings(Strings, IO1, IO2),
+    io__nl(IO2, IO)
+)
+ at end example
 
 Higher-order function terms of zero arity can only be created using
 an explicit lambda expression; you have to use e.g. @samp{(func) = foo}



More information about the developers mailing list