# New Ticket Created by  Florian Hatat 
# Please include the string:  [perl #59784]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=59784 >


Hi,

PGE currently only supports one operator table, while some languages
(for example the OCaml language, which has "type expressions") may need
more than one.

This patch updates Per6Grammar.pir to add support for multiple optables:
each rule with the option "is optable" now creates a new PGE::OPTable
with a unique identifier (using the "unique" method of CodeString).

In the generated "__onload" sub, the operators are still added to the
tables using the single "optable" variable, which holds the latest
defined optable.

This implies that once a new optable is defined, the previous ones
cannot be extended any more.

The diff on the code itself is actually quite small: it was mainly a
matter of moving some code around, and adding the unique identifier
instead of the "$optable" static name. It contains an update for
docs/pct/pct_optable_guide.pod as well. It was made against the 0.7.1
sources.

-- 
Florian,
http://openweb.eu.org/
http://www.linux-france.org/

--- runtime/parrot/library/PGE/Perl6Grammar.pir	2008-09-17 00:14:12.000000000 +0200
+++ runtime/parrot/library/PGE/Perl6Grammar.new	2008-10-10 12:57:53.000000000 +0200
@@ -192,8 +192,6 @@
   ns_optable:
     $P0 = ns['optable']
     if $P0 == '' goto iter_loop
-    initpir.emit("          optable = new 'PGE::OPTable'")
-    initpir.emit("          set_hll_global ['%0'], '$optable', optable", namespace)
     initpir .= $P0
     goto iter_loop
   iter_end:
@@ -290,16 +288,24 @@
     goto with_rulepir
   rulepir_optable:
     ##   this is a special rule generated via the 'is optable' trait
+    .local pmc optable
+    $P0 = nstable[namespace]
+    optable = $P0['optable']
+    $S0 = optable.unique('optable_')
+
     rulepir = new 'CodeString'
-    rulepir.emit(<<'      END', namespace, name)
+    rulepir.emit(<<'      END', namespace, name, $S0)
       .namespace [ "%0" ]
       .sub "%1"
         .param pmc mob
         .param pmc adverbs :named :slurpy
-        $P0 = get_hll_global ["%0"], "$optable"
+        $P0 = get_hll_global ["%0"], "$%2"
         .return $P0.'parse'(mob, 'rulename'=>"%1", adverbs :named :flat)
       .end
       END
+
+    optable.emit("          optable = new 'PGE::OPTable'")
+    optable.emit("          set_hll_global ['%0'], '$%1', optable", namespace, $S0)
   with_rulepir:
 
     ##   add to set of rules
--- docs/pct/pct_optable_guide.pod	2008-09-17 00:14:34.000000000 +0200
+++ docs/pct/pct_optable_guide.new	2008-10-10 13:23:41.000000000 +0200
@@ -426,7 +426,22 @@
 
 =item * How many operator tables can I use in my language?
 
-{{ XXX I think one only? Anybody? }}
+You can use as many operator tables as you like: each operator table is declared
+in a rule, as above. Operators automatically belong to the last operator table
+defined before their C<proto> rule. This means, in particular, that you cannot
+add any more operator to an optable once you've started another optable.
+
+The following example defines two optables C<expr> and C<otherexpr>, with some
+operators:
+
+ rule expr is optable { ... }
+ proto 'infix:+' is precedence('1') { ... }
+ proto 'infix:*' is tighter('infix:+') { ... }
+ proto 'term:' is tighter('infix:*') is parsed(&term) { ... }
+
+ rule otherexpr is optable { ... }
+ proto 'infix:+' is precedence('1')
+ proto 'term:' is tighter('infix:+') is parsed(&otherterm) { ... }
 
 =item * How does an optable parser work?
 

Attachment: signature.asc
Description: PGP signature

Reply via email to