Author: pmichaud
Date: Tue May  3 19:21:22 2005
New Revision: 7968

Modified:
   trunk/compilers/pge/PGE/Exp.pir
   trunk/compilers/pge/PGE/P6Rule.pir
Log:
Added and repaired :: and ::: cut operators.


Modified: trunk/compilers/pge/PGE/Exp.pir
==============================================================================
--- trunk/compilers/pge/PGE/Exp.pir     (original)
+++ trunk/compilers/pge/PGE/Exp.pir     Tue May  3 19:21:22 2005
@@ -14,6 +14,8 @@
     PGE::Dot       - match any character
     PGE::CharClass - match of characters in various classes
     PGE::Anchor    - matching of ^, ^^, $, $$ anchors
+    PGE::Cut       - :: and :::
+    PGE::Concat    - concatenation of expressions
     PGE::Alt       - alternations
     PGE::Group     - groups and captures
 
@@ -40,6 +42,7 @@
     $P0 = subclass expclass, "PGE::Exp::Dot"
     $P0 = subclass expclass, "PGE::Exp::CharClass"
     $P0 = subclass expclass, "PGE::Exp::Anchor"
+    $P0 = subclass expclass, "PGE::Exp::Cut"
     $P0 = subclass expclass, "PGE::Exp::Concat"
     $P0 = subclass expclass, "PGE::Exp::Alt"
     $P0 = subclass expclass, "PGE::Exp::Group"
@@ -187,7 +190,12 @@
     .param string str2
     .param string str3
     .param string str4
+    .param int docut
     .local pmc emit
+
+    unless argcI < 1 goto emitsub_0
+    docut = 1
+  emitsub_0:
     emit = find_global "PGE::Exp", "emit"
     $I0 = argcS
     if $I0 < 2 goto emitsub_1
@@ -212,6 +220,9 @@
     if $I0 < 2 goto emitsub_2
     emit(code, "    restore %s", str1)
   emitsub_2:
+    unless docut goto end
+    emit(code, "    if cutting > 0 goto fail")
+  end:
 .end
 
 =item C<genliteral(PMC code, STR label, STR next)>
@@ -312,6 +323,7 @@
     emit(code, "    .param string target")
     emit(code, "    .param int pos")
     emit(code, "    .param int lastpos")
+    emit(code, "    .param int cutting")
     emit(code, "    .local int rep, maxrep")
     emit(code, "    .local int litlen")
     emit(code, "    .local string lit")
@@ -324,6 +336,7 @@
     emit(code, "    cpad = new PerlArray")
     emit(code, "    push cpad, mob")
     emit(code, "    from = getattribute mob, \"PGE::Match\\x0$:from\"")
+    emit(code, "    cutting = 0")
     emit(code, "    unless argcI > 1 goto setpos")
     emit(code, "    lastpos = length target")
     emit(code, "  setpos:")
@@ -331,7 +344,8 @@
     emit(code, "  try_match:")
     emit(code, "    if pos > lastpos goto fail_forever")
     emit(code, "    from = pos")
-    self.emitsub(code, label, "pos")
+    self.emitsub(code, label, "pos", 0)
+    emit(code, "    if cutting > 1 goto fail_forever")
     emit(code, "    inc pos")
     emit(code, "    goto try_match")
     emit(code, "  fail_forever:")
@@ -393,7 +407,7 @@
     unless min > 0 goto dot_1
     emit(code, "    if maxrep < %d goto fail", min)
   dot_1:
-    unless min == max goto dot_2                   # XXX: error?
+    unless min == max goto dot_2
     emit(code, "    pos += %d", min)
     emit(code, "    goto %s", next)
     .return ()
@@ -462,6 +476,10 @@
     emit(code, "    goto %s_1", label)
     emit(code, "  %s_f:", label)
     emit(code, "    if rep < %d goto fail", min)
+    unless iscut goto greedy_1
+    emit(code, "    goto %s", next)
+    .return ()
+  greedy_1:
     emit(code, "    if rep == %d goto %s", min, next)
     self.emitsub(code, next, "pos", "rep")
     emit(code, "    dec pos")
@@ -471,8 +489,13 @@
   lazy:
     emit(code, "  %s_0:", label)
     emit(code, "    if rep < %d goto %s_1", min, label)
+    unless iscut goto lazy_1
+    emit(code, "    goto %s", next)
+    goto lazy_2
+  lazy_1:
     emit(code, "    if rep >= %d goto %s", max, next)
     self.emitsub(code, next, "pos", "rep")
+  lazy_2:
     emit(code, "  %s_1:", label)
     emit(code, test, label)
     emit(code, "    inc rep")
@@ -539,6 +562,27 @@
     exp2.gen(code, $S1, next)
 .end
 
+.namespace [ "PGE::Exp::Cut" ]
+
+.sub "gen" method
+    .param pmc code
+    .param string label
+    .param string next
+    .param string token
+    .local pmc emit
+    .local int cutting
+    token = self["token"]
+    cutting = 1                                    # :: cut alternation
+    unless token == ":::" goto cut_1               # ::: cut rule
+    cutting = 2
+  cut_1:
+    emit = find_global "PGE::Exp", "emit"
+    emit(code, "\n  %s:", label)
+    self.emitsub(code, next)
+    emit(code, "    cutting = %d", cutting)
+    emit(code, "    goto fail")
+.end
+
 .namespace [ "PGE::Exp::Alt" ]
 
 .sub "analyze" method
@@ -660,6 +704,8 @@
     emit(code, "    unless iscreator goto fail")
     emit(code, "    delete cobcapt[%s]", captname)
   init_2:
+    emit(code, "    if cutting != 1 goto fail")
+    emit(code, "    cutting = 0")
     emit(code, "    goto fail")
     emit(code, "  %s_1:", label)
     emit(code, "    rep = gpad[-2]")
@@ -677,6 +723,10 @@
     emit(code, "    inc rep")
     emit(code, "    gpad[-2] = rep")
     self.emitsub(code, sublabel, "pos", "rep")
+    unless iscut goto greedy_1
+    emit(code, "    $I0 = gpad[-2]")
+    emit(code, "    if $I0 < 0 goto fail")
+  greedy_1:
     emit(code, "    dec rep")
     emit(code, "  %s_g1:", label)
     emit(code, "    if rep < %d goto fail", min)
@@ -684,10 +734,10 @@
     emit(code, "    $I0 = pop gpad")
     emit(code, "    $P0 = pop gpad")
     emit(code, "    $P0 = pop cpad")
-    self.emitsub(code, next, "capt", "rep", "$P0")
+    self.emitsub(code, next, "capt", "rep", "$P0", 0)
     emit(code, "    push cpad, $P0")
     emit(code, "    push gpad, capt")
-    emit(code, "    push gpad, rep")
+    emit(code, "    push gpad, -1")
     emit(code, "    push gpad, '%s'", label)
     emit(code, "    goto fail")
     goto subpat
@@ -697,11 +747,14 @@
     emit(code, "    $I0 = pop gpad")
     emit(code, "    $P0 = pop gpad")
     emit(code, "    $P0 = pop cpad")
-    self.emitsub(code, next, "capt", "rep", "pos", "$P0")
+    self.emitsub(code, next, "capt", "rep", "pos", "$P0", 0)
     emit(code, "    push cpad, $P0")
     emit(code, "    push gpad, capt")
     emit(code, "    push gpad, rep")
     emit(code, "    push gpad, '%s'", label)
+    unless iscut goto lazy_1
+    emit(code, "    goto fail")
+  lazy_1:
     emit(code, "  %s_l1:", label)
     emit(code, "    if rep >= %d goto fail", max)
     emit(code, "    inc rep")
@@ -743,10 +796,11 @@
     emit(code, "    restoreall")
     emit(code, "    restore pos")
     emit(code, "    restore $P0")
-    emit(code, "    unless $P0 goto %s_s3", label)
+    emit(code, "    unless $P0 goto %s_s4", label)
     emit(code, "    push capt, $P0")
     emit(code, "  %s_s2:", label)
-    self.emitsub(code, label, "pos", "$P0")
+    self.emitsub(code, label, "pos", "$P0", 0)
+    emit(code, "    if cutting > 0 goto %s_s3", label)
     emit(code, "    saveall")
     emit(code, "    $P0.next()")
     emit(code, "    pos = $P0.to()")
@@ -754,8 +808,9 @@
     emit(code, "    restoreall")
     emit(code, "    restore pos")
     emit(code, "    if $P0 goto %s_s2", label)
-    emit(code, "    $P1 = pop capt")
     emit(code, "  %s_s3:", label)
+    emit(code, "    $P1 = pop capt")
+    emit(code, "  %s_s4:", label)
     emit(code, "    ret")
   end:
 .end

Modified: trunk/compilers/pge/PGE/P6Rule.pir
==============================================================================
--- trunk/compilers/pge/PGE/P6Rule.pir  (original)
+++ trunk/compilers/pge/PGE/P6Rule.pir  Tue May  3 19:21:22 2005
@@ -44,6 +44,9 @@
     p6meta['^^'] = $P0
     p6meta['$'] = $P0
     p6meta['$$'] = $P0
+    $P0 = find_global "PGE::P6Rule", "p6rule_parse_cut"
+    p6meta['::'] = $P0
+    p6meta[':::'] = $P0
     $P0 = find_global "PGE::P6Rule", "p6rule_parse_group"
     p6meta['['] = $P0
     p6meta[']'] = u
@@ -317,6 +320,27 @@
     exp["token"] = token
     $I0 = length token
     p6rule_parse_skip(pattern, lex, $I0)
+    .return (exp)
+.end
+
+=item C<p6rule_parse_cut(STR pattern, PMC lex)>
+
+Parse one of the cut terms (::, :::) in a rule expression.
+The single-colon cut (cut previous expression) is actually
+handled as a special quantifier.
+
+=cut
+
+.sub p6rule_parse_cut
+    .param string pattern
+    .param pmc lex
+    .param string token
+    .local pmc exp
+    $P0 = find_global "PGE::Exp", "new"
+    exp = $P0("PGE::Exp::Cut")
+    exp["token"] = token
+    $I0 = length token
+    p6rule_parse_skip(pattern, lex, $I0)
     .return (exp)
 .end
 

Reply via email to