Author: pmichaud
Date: Tue Oct 25 23:55:38 2005
New Revision: 9573

Added:
   trunk/compilers/pge/PGE/OPTable.pir
Modified:
   trunk/MANIFEST
   trunk/compilers/pge/PGE.pir
   trunk/compilers/pge/PGE/Match.pir
   trunk/config/gen/makefiles/pge.in
   trunk/lib/Parrot/Test/PGE.pm
   trunk/runtime/parrot/library/PGE/Dumper.pir
Log:
Added PGE::OPTable (shift+reduce parsing w/operator precedence) and 
moved dumper functions to PGE/Dumper.pir .


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Tue Oct 25 23:55:38 2005
@@ -141,6 +141,7 @@ compilers/pge/mklib.pir                 
 compilers/pge/PGE.pir                             []
 compilers/pge/PGE/Exp.pir                         []
 compilers/pge/PGE/Match.pir                       []
+compilers/pge/PGE/OPTable.pir                     []
 compilers/pge/PGE/P6Rule.pir                      []
 compilers/pge/PGE/Rule.pir                        []
 compilers/pge/PGE/TokenHash.pir                   []

Modified: trunk/compilers/pge/PGE.pir
==============================================================================
--- trunk/compilers/pge/PGE.pir (original)
+++ trunk/compilers/pge/PGE.pir Tue Oct 25 23:55:38 2005
@@ -28,6 +28,8 @@ defined.
     load()
     load = find_global "PGE::Rule", "__onload"
     load()
+    load = find_global "PGE::OPTable", "__onload"
+    load()
 .end
 
 .include "compilers/pge/PGE/TokenHash.pir"
@@ -36,3 +38,4 @@ defined.
 .include "compilers/pge/PGE/Rule.pir"
 .include "compilers/pge/PGE/P6Rule.pir"
 .include "compilers/pge/PGE/Library.pir"
+.include "compilers/pge/PGE/OPTable.pir"

Modified: trunk/compilers/pge/PGE/Match.pir
==============================================================================
--- trunk/compilers/pge/PGE/Match.pir   (original)
+++ trunk/compilers/pge/PGE/Match.pir   Tue Oct 25 23:55:38 2005
@@ -303,104 +303,6 @@ Returns the array component of the match
     .return (array)
 .end
 
-=item C<dump()>
-
-Produces a data dump of the match object and all of its subcaptures.
-
-=cut
-
-.sub "dump" method
-    .param string prefix       :optional           # name of match variable
-    .param int has_prefix      :opt_flag
-    .param string b1           :optional           # bracket open
-    .param int has_b1          :opt_flag
-    .param string b2           :optional           # bracket close
-    .param int has_b2          :opt_flag
-
-    .local pmc capt
-    .local int spi, spc
-    .local pmc iter
-    .local string prefix1, prefix2
-
-    if has_b2 goto start
-    b2 = "]"
-    if has_b1 goto start
-    b1 = "["
-  start:
-    print prefix
-    print ":"
-    unless self goto subpats
-    print " <"
-    print self
-    print " @ "
-    $I0 = self."from"()
-    print $I0
-    print "> "
-
-  subpats:
-    $I0 = self
-    print $I0
-    print "\n"
-    capt = getattribute self, "PGE::Match\x0@:capt"
-    if_null capt, subrules
-    spi = 0
-    spc = elements capt
-  subpats_1:
-    unless spi < spc goto subrules
-    prefix1 = concat prefix, b1
-    $S0 = spi
-    concat prefix1, $S0
-    concat prefix1, b2
-    $I0 = defined capt[spi]
-    unless $I0 goto subpats_2
-    $P0 = capt[spi]
-    bsr dumper
-  subpats_2:
-    inc spi
-    goto subpats_1
-
-  subrules:
-    capt = getattribute self, "PGE::Match\x0%:capt"
-    if_null capt, end
-    iter = new Iterator, capt
-    iter = 0
-  subrules_1:
-    unless iter goto end
-    $S0 = shift iter
-    prefix1 = concat prefix, "<"
-    concat prefix1, $S0
-    concat prefix1, ">"
-    $I0 = defined capt[$S0]
-    unless $I0 goto subrules_1
-    $P0 = capt[$S0]
-    bsr dumper
-    goto subrules_1
-
-  dumper:
-    $I0 = isa $P0, "Array"
-    if $I0 goto dumper_0
-    $P0."dump"(prefix1, b1, b2)
-    ret
-  dumper_0:
-    $I0 = 0
-    $I1 = elements $P0
-  dumper_1:
-    if $I0 >= $I1 goto dumper_2
-    $P1 = $P0[$I0]
-    prefix2 = concat prefix1, b1
-    $S0 = $I0
-    concat prefix2, $S0
-    concat prefix2, b2
-    $P1."dump"(prefix2, b1, b2)
-    inc $I0
-    goto dumper_1
-  dumper_2:
-    ret
-
-  end:
-    .return ()
-.end
-
 =head1 AUTHOR
 
 Patrick Michaud ([EMAIL PROTECTED]) is the author and maintainer.

Added: trunk/compilers/pge/PGE/OPTable.pir
==============================================================================
--- (empty file)
+++ trunk/compilers/pge/PGE/OPTable.pir Tue Oct 25 23:55:38 2005
@@ -0,0 +1,376 @@
+=head1 Title
+
+PGE::OPTable - PGE operator precedence table and parser
+
+=head1 DESCRIPTION
+
+This file implements the operator precedence table used to perform
+shift/reduce parsing of strings.  To get a parser, first create an
+instance of C<PGE::OPTable>, then make calls to the C<addtok>
+method to add operator tokens into the table:
+
+    .local pmc optable, digit
+    $I0 = find_type "PGE::OPTable"
+    digit = find_global "PGE::Rule", "digit"
+    optable."addtok"(" infix:+", "PGE::Match")
+    optable."addtok"(" infix:-", "PGE::Match", "infix:+")
+    optable."addtok"(" infix:*", "PGE::Match", ">infix:+")
+    optable."addtok"(" infix:/", "PGE::Match", "infix:*")
+    optable."addtok"(" term:", digit, ">infix:*")
+    optable."addtok"(" circumfix:( )", "PGE::Match", "term:")
+
+The C<parse> method can then be used to obtain a Match object
+representing the parse of a string:
+
+    $P0 = optable."parse"("1 + 2 * 3")
+
+To make a parser callable from a rule, create a custom rule
+subroutine that calls the parser:
+
+    .sub "expr"
+        .param pmc mob
+        .local pmc optable
+        optable = find_name "optable"
+        $P0 = optable."parse"(mob)
+        .return ($P0)
+    .end
+
+=cut
+
+.namespace [ "PGE::OPTable" ]
+
+.const int PGE_OPTABLE_CLOSE = 0
+.const int PGE_OPTABLE_TERM = 1
+.const int PGE_OPTABLE_POSTFIX = 2
+.const int PGE_OPTABLE_PREFIX = 3
+.const int PGE_OPTABLE_INFIX = 4
+.const int PGE_OPTABLE_CIRCUMFIX = 5
+.const int PGE_OPTABLE_POSTCIRCUMFIX = 6
+
+.include "cclass.pasm"
+
+=head1 Methods
+
+=item C<__onload()>
+
+Creates the PGE::OPTable and PGE::Op classes.
+
+=cut
+
+.sub "__onload" 
+    .local pmc base
+    base = newclass "PGE::OPTable"
+    addattribute base, "%:toktable"
+    addattribute base, "%:termtable"
+    addattribute base, "%:opertable"
+    addattribute base, "%:wstermtable"
+    addattribute base, "%:wsopertable"
+    $P0 = getclass "PGE::Match"
+    $P0 = subclass $P0, "PGE::Op"
+.end
+
+=item C<__init()>
+
+Initializes a PGE::OPTable object.
+
+=cut
+
+.sub "__init" :method
+    $P0 = new Hash
+    setattribute self, "PGE::OPTable\x0%:toktable", $P0
+    $I0 = find_type "PGE::TokenHash"
+    $P0 = new $I0
+    setattribute self, "PGE::OPTable\x0%:termtable", $P0
+    $P0 = new $I0
+    setattribute self, "PGE::OPTable\x0%:wstermtable", $P0
+    $P0 = new $I0
+    setattribute self, "PGE::OPTable\x0%:opertable", $P0
+    $P0 = new $I0
+    setattribute self, "PGE::OPTable\x0%:wsopertable", $P0
+.end
+
+=head2 Methods
+
+=item C<addtok(STR name, PMC match, STR rel, STR opts)>
+
+Adds a new token to the operator precedence table.  Operators are
+named as strings representing the syntactic category of the operator
+and the operator token(s).  Available syntactic categories include
+"infix:", "prefix:", "postfix:", "term:", "circumfix:", and
+"postcircumfix:".  
+
+The C<match> argument is either a string identifying the class of 
+Match object to create for this operator, or a (rule) subroutine 
+to be called that will parse the complete token and return an 
+appropriate match object.  
+
+The C<rel> argument specifies the precedence of this operator 
+relative to another operator, with a leading ">" or "<" used to indicate
+tighter or looser precedence.  Finally, the C<opts> parameter
+can be used to indicate the associativity of the operator ("left" or 
+"right").
+
+=cut
+
+.sub "addtok" :method
+    .param string name
+    .param pmc match
+    .param string rel          :optional
+    .param int has_rel         :opt_flag
+    .param string opts         :optional
+    .param int has_opts        :opt_flag
+    .local string equiv, syncat
+    .local pmc toktable, termtable, wstermtable, opertable, wsopertable
+    .local pmc tok
+    .local string tok1, tok2
+    .local int isws
+
+    toktable = getattribute self, "PGE::OPTable\x0%:toktable"
+    termtable = getattribute self, "PGE::OPTable\x0%:termtable"
+    opertable = getattribute self, "PGE::OPTable\x0%:opertable"
+    wstermtable = getattribute self, "PGE::OPTable\x0%:wstermtable"
+    wsopertable = getattribute self, "PGE::OPTable\x0%:wsopertable"
+
+    if has_opts goto addtok_1
+    opts = "left"
+  addtok_1:
+    equiv = "="
+    if has_rel == 0 goto addtok_2
+    $S0 = substr rel, 0, 1
+    $I0 = index "=<>", $S0
+    if $I0 == -1 goto addtok_3
+    $S1 = substr rel, 1
+    $P0 = toktable[$S1]
+    equiv = $P0['equiv']
+    equiv = clone equiv
+    substr equiv, -1, 0, $S0
+    goto addtok_2
+  addtok_3:
+    $P0 = toktable[rel]
+    equiv = $P0['equiv']
+
+  addtok_2:
+    isws = 0
+    $S0 = substr name, 0, 1
+    if $S0 != " " goto addtok_4
+    isws = 1
+    name = substr name, 1
+
+  addtok_4:
+    tok = new Hash
+    tok["name"] = name
+    tok["opts"] = opts
+    tok["equiv"] = equiv
+    tok["match"] = match
+    tok["arity"] = 1
+    $I0 = index name, ":"
+    inc $I0
+    syncat = substr name, 0, $I0
+    tok1 = substr name, $I0
+    $I0 = index tok1, " "
+    if $I0 < 0 goto addtok_5
+    $I1 = $I0 + 1
+    tok2 = substr tok1, $I1
+    tok1 = substr tok1, 0, $I0
+    tok["tok2"] = tok2
+    $P0 = clone tok
+    $P0["syncat"] = PGE_OPTABLE_CLOSE
+    opertable[tok2] = $P0
+    wsopertable[tok2] = $P0
+  addtok_5:
+    tok["tok1"] = tok1
+    toktable[name] = tok
+    if syncat == "infix:" goto infix
+    if syncat == "postfix:" goto postfix
+    if syncat == "circumfix:" goto circumfix
+    if syncat == "prefix:" goto prefix
+    if syncat == "postcircumfix:" goto postcircumfix
+  term:
+    tok["syncat"] = PGE_OPTABLE_TERM
+    goto expect_term
+  infix:
+    tok["syncat"] = PGE_OPTABLE_INFIX
+    tok["arity"] = 2
+    goto expect_op
+  prefix:
+    tok["syncat"] = PGE_OPTABLE_PREFIX
+    goto expect_term
+  postfix:
+    tok["syncat"] = PGE_OPTABLE_POSTFIX
+    goto expect_op
+  circumfix:
+    tok["syncat"] = PGE_OPTABLE_CIRCUMFIX
+    goto expect_term
+  postcircumfix:
+    tok["syncat"] = PGE_OPTABLE_POSTCIRCUMFIX
+    tok["arity"] = 2
+    goto expect_op
+  expect_term:
+    termtable[tok1] = tok 
+    if isws == 0 goto end
+    wstermtable[tok1] = tok 
+    goto end
+  expect_op:
+    opertable[tok1] = tok 
+    if isws == 0 goto end
+    wsopertable[tok1] = tok
+  end:
+.end
+
+=item C<parse(PMC mob)>
+
+Parse the string or match given by C<mob>, and return a Match object
+representing the result of the parse.
+
+=cut
+
+.sub "parse" :method
+    .param pmc mob
+    .local string target
+    .local int pos, lastpos, wspos
+    .local pmc mobpos
+    .local pmc termtable, opertable, wstermtable, wsopertable
+    .local pmc oper
+    .local pmc tok, match, top
+    .local pmc termstack, operstack, tokstack
+    .local int arity
+    .local pmc args
+    .local string key
+    .local pmc newfrom
+
+    termtable = getattribute self, "PGE::OPTable\x0%:termtable"
+    opertable = getattribute self, "PGE::OPTable\x0%:opertable"
+    wstermtable = getattribute self, "PGE::OPTable\x0%:wstermtable"
+    wsopertable = getattribute self, "PGE::OPTable\x0%:wsopertable"
+    termstack = new PerlArray
+    operstack = new PerlArray
+    tokstack = new PerlArray
+
+    newfrom = find_global "PGE::Match", "newfrom"
+    mob = newfrom(mob, 0)
+    $P0 = getattribute mob, "PGE::Match\x0$:from"
+    pos = $P0
+    $P0 = getattribute mob, "PGE::Match\x0$:target"
+    mobpos = getattribute mob, "PGE::Match\x0$:pos"
+    target = $P0
+    lastpos = length target
+
+  expect_term:
+    $P0 = wstermtable
+    wspos = find_not_cclass .CCLASS_WHITESPACE, target, pos, lastpos
+    if wspos > pos goto expect_term_1
+    $P0 = termtable
+  expect_term_1:
+    key = $P0."lkey"(target, wspos)
+    tok = $P0[key]
+    bsr tok_match
+    unless oper goto term_error
+    $P0 = tok["syncat"]
+    if $P0 == PGE_OPTABLE_PREFIX goto oper_shift
+    if $P0 == PGE_OPTABLE_CIRCUMFIX goto oper_shift
+    push termstack, oper
+    pos = oper.to()
+    
+  expect_oper:
+    $P0 = wsopertable
+    wspos = find_not_cclass .CCLASS_WHITESPACE, target, pos, lastpos
+    if wspos > pos goto expect_oper_1
+    $P0 = opertable
+  expect_oper_1:
+    key = $P0."lkey"(target, wspos)
+    if key == "" goto end
+    tok = $P0[key]
+    bsr tok_match
+    unless oper goto end
+  expect_oper_2:
+    $I0 = elements tokstack
+    if $I0 < 1 goto oper_shift
+    top = tokstack[-1]
+    $P0 = top["syncat"]
+    if $P0 <= PGE_OPTABLE_POSTFIX goto oper_reduce
+    if $P0 >= PGE_OPTABLE_CIRCUMFIX goto oper_shift
+    $P0 = tok["syncat"]
+    if $P0 == PGE_OPTABLE_CLOSE goto oper_reduce
+    $P0 = tok["equiv"]
+    $P1 = top["equiv"]
+    if $P1 < $P0 goto oper_shift
+    if $P1 > $P0 goto oper_reduce
+    $S0 = top["opts"]
+    $I0 = index $S0, "right"
+    if $I0 >= 0 goto oper_shift
+  oper_reduce:
+    bsr reduce
+    goto expect_oper_2
+  oper_shift:
+    push tokstack, tok
+    push operstack, oper
+    pos = oper.to()
+    $P0 = tok["syncat"]
+    if $P0 >= PGE_OPTABLE_PREFIX goto expect_term
+    goto expect_oper
+  oper_close:
+
+  reduce:
+    $P0 = pop tokstack
+    $P1 = $P0["syncat"]
+    if $P1 != PGE_OPTABLE_CLOSE goto reduce_1
+    $P0 = pop tokstack
+    $P1 = pop operstack
+  reduce_1:
+    arity = $P0["arity"]
+    $P0 = pop operstack
+    args = new PerlArray
+    $P0["args"] = args
+  reduce_args:
+    if arity < 1 goto reduce_end
+    $P1 = pop termstack
+    unshift args, $P1
+    dec arity
+    goto reduce_args
+  reduce_end:
+    push termstack, $P0
+    ret
+
+  tok_match:
+    mobpos = wspos
+    match = tok["match"]
+    $I0 = isa match, "Sub"
+    if $I0 goto tok_match_sub
+    oper = newfrom(mob, wspos, match)
+    $I0 = length key
+    $I0 += wspos
+    $P0 = getattribute oper, "PGE::Match\x0$:pos"
+    $P0 = $I0
+    goto tok_match_end
+  tok_match_sub:
+    oper = match(mob)
+  tok_match_end:
+    $P0 = tok["name"]
+    $P0 = clone $P0
+    oper["name"] = $P0
+    ret
+
+  end:
+    $I0 = elements tokstack
+    if $I0 < 1 goto end_1
+    bsr reduce
+    goto end
+  end_1:
+    $P0 = pop termstack
+    mob["expr"] = $P0
+    mobpos = pos
+    .return (mob)
+
+  term_error:
+    $P0 = new Exception
+    $S0 = "Missing term at offset "
+    $S1 = wspos
+    $S0 .= $S1
+    $S0 .= "\n"
+    $P0["_message"] = $S0
+    throw $P0
+    mobpos = -1
+    .return (mob)
+.end
+
+

Modified: trunk/config/gen/makefiles/pge.in
==============================================================================
--- trunk/config/gen/makefiles/pge.in   (original)
+++ trunk/config/gen/makefiles/pge.in   Tue Oct 25 23:55:38 2005
@@ -16,7 +16,7 @@ all: $(PARROT_LIBRARY)${slash}PGE.pbc
 $(PARROT_LIBRARY)${slash}PGE.pbc: PGE.pbc
        $(CP) PGE.pbc $(PARROT_LIBRARY)
 
-PGE.pbc: PGE.pir PGE/Exp.pir PGE/Match.pir PGE/Rule.pir PGE/P6Rule.pir 
PGE/TokenHash.pir mklib.pir library.pge
+PGE.pbc: PGE.pir PGE/Exp.pir PGE/Match.pir PGE/Rule.pir PGE/P6Rule.pir 
PGE/TokenHash.pir PGE/OPTable.pir mklib.pir library.pge
        $(PARROT) mklib.pir >PGE/Library.pir
        $(PARROT) -o PGE.pbc --output-pbc PGE.pir 
 

Modified: trunk/lib/Parrot/Test/PGE.pm
==============================================================================
--- trunk/lib/Parrot/Test/PGE.pm        (original)
+++ trunk/lib/Parrot/Test/PGE.pm        Tue Oct 25 23:55:38 2005
@@ -147,6 +147,7 @@ sub _generate_pir_for {
         .sub _PGE_Test
             .local pmc p6rule_compile
             load_bytecode "PGE.pbc"
+            load_bytecode "PGE/Dumper.pir"
             load_bytecode "PGE/Text.pir"
             find_global p6rule_compile, "PGE", "p6rule"
 

Modified: trunk/runtime/parrot/library/PGE/Dumper.pir
==============================================================================
--- trunk/runtime/parrot/library/PGE/Dumper.pir (original)
+++ trunk/runtime/parrot/library/PGE/Dumper.pir Tue Oct 25 23:55:38 2005
@@ -7,6 +7,199 @@ PGE::Dumper - various methods for displa
 .sub __onload
 .end
 
+.namespace [ "PGE::Match" ]
+
+=head2 C<PGE::Match> Methods
+
+=item C<__dump(PMC dumper, STR label)>
+
+This method enables Data::Dumper to work on Match objects.
+
+=cut
+
+.sub "__dump" :method
+    .param pmc dumper
+    .param string label
+    .local string indent, subindent
+    
+    (indent, subindent) = dumper."newIndent"()
+    print "=> "
+    $S0 = self
+    dumper."genericString"("", $S0)
+    print " @ "
+    $I0 = self.from()
+    print $I0
+    $P0 = self."get_array"()
+    if_null $P0, dump_1
+    print "\n"
+    print indent
+    dumper."dump"(label, $P0)
+  dump_1:
+    $P0 = self."get_hash"()
+    if_null $P0, dump_end
+    print "\n"
+    print indent
+    dumper."dump"(label, $P0)
+    goto dump_end
+  dump_end:
+    dumper."deleteIndent"()
+.end
+
+=item C<dump()>
+
+An alternate dump output for a Match object and all of its subcaptures.
+
+=cut
+
+.sub "dump" method
+    .param string prefix       :optional           # name of match variable
+    .param int has_prefix      :opt_flag
+    .param string b1           :optional           # bracket open
+    .param int has_b1          :opt_flag
+    .param string b2           :optional           # bracket close
+    .param int has_b2          :opt_flag
+
+    .local pmc capt
+    .local int spi, spc
+    .local pmc iter
+    .local string prefix1, prefix2
+
+    if has_b2 goto start
+    b2 = "]"
+    if has_b1 goto start
+    b1 = "["
+  start:
+    print prefix
+    print ":"
+    unless self goto subpats
+    print " <"
+    print self
+    print " @ "
+    $I0 = self."from"()
+    print $I0
+    print "> "
+
+  subpats:
+    $I0 = self
+    print $I0
+    print "\n"
+    capt = getattribute self, "PGE::Match\x0@:capt"
+    if_null capt, subrules
+    spi = 0
+    spc = elements capt
+  subpats_1:
+    unless spi < spc goto subrules
+    prefix1 = concat prefix, b1
+    $S0 = spi
+    concat prefix1, $S0
+    concat prefix1, b2
+    $I0 = defined capt[spi]
+    unless $I0 goto subpats_2
+    $P0 = capt[spi]
+    bsr dumper
+  subpats_2:
+    inc spi
+    goto subpats_1
+
+  subrules:
+    capt = getattribute self, "PGE::Match\x0%:capt"
+    if_null capt, end
+    iter = new Iterator, capt
+    iter = 0
+  subrules_1:
+    unless iter goto end
+    $S0 = shift iter
+    prefix1 = concat prefix, "<"
+    concat prefix1, $S0
+    concat prefix1, ">"
+    $I0 = defined capt[$S0]
+    unless $I0 goto subrules_1
+    $P0 = capt[$S0]
+    bsr dumper
+    goto subrules_1
+
+  dumper:
+    $I0 = isa $P0, "Array"
+    if $I0 goto dumper_0
+    $I0 = isa $P0, "PGE::Match"
+    unless $I0 goto dumper_3
+    $P0."dump"(prefix1, b1, b2)
+    ret
+  dumper_0:
+    $I0 = 0
+    $I1 = elements $P0
+  dumper_1:
+    if $I0 >= $I1 goto dumper_2
+    $P1 = $P0[$I0]
+    prefix2 = concat prefix1, b1
+    $S0 = $I0
+    concat prefix2, $S0
+    concat prefix2, b2
+    $P1."dump"(prefix2, b1, b2)
+    inc $I0
+    goto dumper_1
+  dumper_2:
+    ret
+  dumper_3:
+    print prefix1
+    print ": "
+    print $P0
+    print "\n"
+    ret
+
+  end:
+    .return ()
+.end
+
+.namespace [ "PGE::Op" ]
+
+=head2 C<PGE::Op> methods
+
+=item C<__dump(PMC dumper, STR label)>
+
+For C<PGE::Op> objects (often produced by the shift/reduce 
+parser in C<PGE::OPTable>), it's perhaps useful to have an 
+alternate Data::Dumper format that makes the operator 
+precedence more obvious.
+
+=cut
+
+.sub "__dump" :method
+    .param pmc dumper
+    .param string label
+    .local string indent, subindent
+
+    (indent, subindent) = dumper."newIndent"()
+    $P0 = self["name"]
+    print "=> "
+    print $P0
+    print " => "
+    $S0 = self
+    dumper."genericString"("", $S0)
+    $I0 = defined self["args"]
+    if $I0 == 0 goto end
+    $P0 = self["args"]
+    $I1 = elements $P0
+    $I0 = 0
+  dump_args:
+    if $I0 >= $I1 goto end
+    print "\n"
+    print indent
+    $P1 = $P0[$I0]
+    dumper."dump"(label, $P1)
+    inc $I0
+    goto dump_args
+  end:
+    dumper."deleteIndent"()
+.end
+    
+=head2 C<PGE::Exp> methods
+
+These methods print out a PGE expression tree.  They may be
+obsoleted in favor of a Data::Dumper method.
+
+=cut
+
 .namespace [ "PGE::Exp" ]
 
 .sub "dumpindent" method

Reply via email to