[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