[m-rev.] for review: user-defined operator tables

Simon Taylor stayl at cs.mu.OZ.AU
Tue Nov 6 05:11:10 AEDT 2001


On 06-Nov-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 06-Nov-2001, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > 	Make the priority of operator terms (X `op` Y) 1, not 100.
> > 	The reference manual states that operator terms have
> > 	the highest precedence possible.
> ...
> NEWS:
> > +* We've fixed a bug in the parser. The Mercury Language Reference Manual
> > +  states that operator terms (X `op` Y) have the lowest possible priority,
> > +  however in the implementation they had a higher priority than the unary
> > +  prefix operator `^'.
> 
> For this one, I think the reference manual should change,
> rather than the implementation.
> 
> I think we discussed this explicitly when `^' was added,
> and decided that it ought to have a higher priority than back-quoted
> operators, it's just that this part of the reference manual
> wasn't updated to reflect that.

I don't recall that discussion, and the current precendences
suggest that I didn't consider back-quoted operators when I
chose the precedence of `^', but I don't really care either way.
The precedence of back-quoted operators should be stored in
the op_table anyway.

Simon.

diff -u NEWS NEWS
--- NEWS
+++ NEWS
@@ -36,6 +36,9 @@
   information, see the "Impurity" chapter of the Mercury Language
   Reference Manual.
 
+* We've fixed a bug in the Mercury Language Reference Manual.
+  Operator terms have a higher priority than `^'.
+
 * We've removed the undocumented operators `export_adt', `export_cons',
   `export_module', `export_op', `export_pred', `export_sym', `export_type',
   `import_adt', `import_cons', `import_op', `import_pred', `import_sym',
@@ -129,11 +132,6 @@
 
   This change will break some existing programs, but that is easily fixed
   by adding any necessary `:- import_module' or `:- use_module' declarations.
-
-* We've fixed a bug in the parser. The Mercury Language Reference Manual
-  states that operator terms (X `op` Y) have the lowest possible priority,
-  however in the implementation they had a higher priority than the unary
-  prefix operator `^'.
 
 * We've added a new optimization pass -- constraint propagation.
 
diff -u doc/reference_manual.texi doc/reference_manual.texi
--- doc/reference_manual.texi
+++ doc/reference_manual.texi
@@ -369,8 +369,9 @@
 accents (backquotes).  Any variable or name may
 be used as an operator in this way.  If @var{fun} is a variable or name,
 then a term of the form @code{@var{X} `@var{fun}` @var{Y}} is equivalent to 
- at code{@var{fun}(@var{X}, @var{Y})}.  The operator is treated as having the
-lowest priority possible and is left associative (@pxref{Builtin Operators}).
+ at code{@var{fun}(@var{X}, @var{Y})}. The operator is left associative,
+with a lower priority than every operator other than @samp{^}
+(@pxref{Builtin Operators}).
 
 A parenthesized term is just an open parenthesis
 followed by a term and a close parenthesis.
@@ -412,9 +413,9 @@
 
 Operator          Specifier Priority
 
-`@var{op}`              yfx       1         @footnote{Operator term (@pxref{Terms}).}
 ^                 xfy       99
 ^                 fx        100
+`@var{op}`              yfx       120       @footnote{Operator term (@pxref{Terms}).}
 **                xfy       200
 -                 fx        200
 \                 fx        200
reverted:
--- library/bitmap.m	5 Nov 2001 12:05:02 -0000
+++ library/bitmap.m	24 Oct 2001 07:27:40 -0000	1.5
@@ -237,7 +237,7 @@
 
 flip(BM, I) =
     ( if in_range(BM, I)
+      then BM ^ elem(int_offset(I)) := BM ^ elem(int_offset(I)) `xor` bitmask(I)
-      then BM ^ elem(int_offset(I)) := (BM ^ elem(int_offset(I))) `xor` bitmask(I)
       else throw(software_error("bitmap__flip: out of range"))
     ).
 
@@ -250,7 +250,7 @@
     BM ^ elem(int_offset(I)) := BM ^ elem(int_offset(I)) /\ \bitmask(I).
 
 unsafe_flip(BM, I) =
+    BM ^ elem(int_offset(I)) := BM ^ elem(int_offset(I)) `xor` bitmask(I).
-    BM ^ elem(int_offset(I)) := (BM ^ elem(int_offset(I))) `xor` bitmask(I).
 
 % ---------------------------------------------------------------------------- %
 
diff -u library/ops.m library/ops.m
--- library/ops.m
+++ library/ops.m
@@ -33,6 +33,14 @@
 			ops__assoc, ops__assoc),
 	mode ops__lookup_infix_op(in, in, out, out, out) is semidet,
 
+		% Operator terms are terms of the form `X `Op` Y',
+		% where `Op' is a variable or a name and `X' and `Y'
+		% are terms. If operator terms are included in `Table',
+		% return their precedence and associativity.
+	pred ops__lookup_operator_term(Table, ops__priority,
+			ops__assoc, ops__assoc),
+	mode ops__lookup_operator_term(in, out, out, out) is semidet,
+
 		% Check whether a string is the name of a prefix operator,
 		% and if it is, return its precedence and associativity.
 	pred ops__lookup_prefix_op(Table, string, ops__priority, ops__assoc),
@@ -168,6 +176,8 @@
 
 :- instance ops__op_table(ops__mercury_op_table) where [
 	pred(ops__lookup_infix_op/5) is ops__lookup_mercury_infix_op,
+	pred(ops__lookup_operator_term/4) is
+			ops__lookup_mercury_operator_term,
 	pred(ops__lookup_prefix_op/4) is ops__lookup_mercury_prefix_op,
 	pred(ops__lookup_binary_prefix_op/5) is
 			ops__lookup_mercury_binary_prefix_op,
@@ -185,6 +195,14 @@
 			LeftAssoc, RightAssoc) :-
 	ops__op_table(Name, after, Specifier, Priority),
 	ops__op_specifier_to_class(Specifier, infix(LeftAssoc, RightAssoc)).
+
+:- pred ops__lookup_mercury_operator_term(mercury_op_table, ops__priority,
+		ops__assoc, ops__assoc).
+:- mode ops__lookup_mercury_operator_term(in, out, out, out) is det.
+
+	% Left associative, lower priority than everything
+	% except record syntax.
+ops__lookup_mercury_operator_term(_OpTable, 120, y, x).
 
 :- pred ops__lookup_mercury_prefix_op(mercury_op_table,
 		string, ops__priority, ops__assoc).
diff -u library/parser.m library/parser.m
--- library/parser.m
+++ library/parser.m
@@ -421,8 +421,14 @@
 				% A token surrounded by backquotes is a
 				% prefix token being using in an
 				% infix manner.
-			{ Op0 = "`" }
+			{ Op0 = "`" },
+			parser__get_ops_table(OpTable),
+			{ ops__lookup_operator_term(OpTable, OpPriority0,
+				LeftAssoc0, RightAssoc0) }
 		->
+			{ OpPriority = OpPriority0 },
+			{ LeftAssoc = LeftAssoc0 },
+			{ RightAssoc = RightAssoc0 },
 			parser__get_token(OpToken, _),
 			(
 				{ OpToken = name(NameOp) }
@@ -435,11 +441,7 @@
 				parser__add_var(VariableOp, Var),
 				{ VariableTerm = [term__variable(Var)] }
 			),
-			parser__get_token(name("`"), _),
-
-			{ OpPriority = 1 },
-			{ LeftAssoc = y },
-			{ RightAssoc = x }
+			parser__get_token(name("`"), _)
 		;
 			{ Op = Op0 },
 			{ VariableTerm = [] },
diff -u samples/calculator2.m samples/calculator2.m
--- samples/calculator2.m
+++ samples/calculator2.m
@@ -164,6 +164,8 @@
 	ops__lookup_infix_op(_, "-", 500, y, x),
 	ops__lookup_infix_op(_, "=", 700, x, x),
 
+	ops__lookup_operator_term(_, _, _, _) :- fail,
+
 	ops__lookup_prefix_op(_, "-", 200, x),
 	ops__lookup_prefix_op(_, "+", 500, x),
 
--------------------------------------------------------------------------
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