Author: pmichaud
Date: Wed May 4 12:38:55 2005
New Revision: 7977
Modified:
trunk/compilers/pge/PGE/Exp.pir
trunk/compilers/pge/PGE/P6Rule.pir
trunk/runtime/parrot/library/PGE/Dumper.pir
Log:
Added "firstchar" initial optimizations.
Modified: trunk/compilers/pge/PGE/Exp.pir
==============================================================================
--- trunk/compilers/pge/PGE/Exp.pir (original)
+++ trunk/compilers/pge/PGE/Exp.pir Wed May 4 12:38:55 2005
@@ -12,7 +12,7 @@
PGE::End - (successful) end of rule
PGE::Literal - match a literal string
PGE::Dot - match any character
- PGE::CharClass - match of characters in various classes
+ PGE::CCShortcut - character class shortcuts (\d, \D, \w, etc.)
PGE::Anchor - matching of ^, ^^, $, $$, \b, \B anchors
PGE::Cut - :: and :::
PGE::Concat - concatenation of expressions
@@ -40,14 +40,14 @@
$P0 = subclass expclass, "PGE::Exp::End"
$P0 = subclass expclass, "PGE::Exp::Literal"
$P0 = subclass expclass, "PGE::Exp::Dot"
- $P0 = subclass expclass, "PGE::Exp::CharClass"
+ $P0 = subclass expclass, "PGE::Exp::CCShortcut"
$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"
hash = new Hash
- store_global "PGE::Exp::CharClass", "%slashcode", hash
+ store_global "PGE::Exp::CCShortcut", "%slashcode", hash
hash['\d'] = "$I0=is_digit target, pos \n unless $I0 goto %s_f"
hash['\n'] = "$I0=is_newline target, pos \n unless $I0 goto %s_f"
hash['\s'] = "$I0=is_whitespace target, pos \n unless $I0 goto %s_f"
@@ -148,6 +148,34 @@
=cut
.sub "analyze" method
+ self["firstchars"] = ""
+.end
+
+
+=item C<firstchars(PMC exp1, PMC exp2)>
+
+The firstchars method sets the "firstchars" optimization hint
+based on the concatenation of the firstchars of any expressions
+provided. If either of the expressions has an empty firstchars
+hint, then we have have no firstchars either.
+
+=cut
+
+.sub "firstchars" method
+ .param pmc exp1
+ .param pmc exp2
+ $S0 = ""
+ if argcP < 1 goto end
+ $S0 = exp1["firstchars"]
+ if argcP < 2 goto end
+ $S1 = exp2["firstchars"]
+ unless $S1 > "" goto exp_1
+ concat $S0, $S1
+ goto end
+ exp_1:
+ $S0 = ""
+ end:
+ self["firstchars"] = $S0
.end
=item C<(INT, STR) = serno(INT start, STR prefix)>
@@ -326,9 +354,11 @@
.namespace [ "PGE::Exp::Start" ]
.sub analyze method
+ .param pmc next
.param int isarray
$P0 = self["exp1"]
- $P0.analyze(isarray)
+ $P0.analyze(self, isarray)
+ self.firstchars($P0)
.end
.sub "gen" method
@@ -337,6 +367,7 @@
.param string next
.local pmc emit
.local pmc exp1
+ .local string firstchars
emit = find_global "PGE::Exp", "emit"
emit(code, ".sub _pge_rule")
@@ -374,9 +405,18 @@
emit(code, " pos = 0")
emit(code, " try_match:")
emit(code, " if pos > lastpos goto fail_forever")
+ $I0 = exists self["firstchars"]
+ unless $I0 goto gen_1
+ firstchars = self["firstchars"]
+ unless firstchars > "" goto gen_1
+ emit(code, " $S0 = substr target, pos, 1")
+ emit(code, " $I0 = index \"%s\", $S0", firstchars)
+ emit(code, " if $I0 < 0 goto try_again")
+ gen_1:
emit(code, " from = pos")
self.emitsub(code, label, "pos", 0)
emit(code, " if cutting > 1 goto fail_forever")
+ emit(code, " try_again:")
emit(code, " inc pos")
emit(code, " goto try_match")
emit(code, " fail_forever:")
@@ -408,6 +448,18 @@
.namespace [ "PGE::Exp::Literal" ]
+.sub "analyze" method
+ .param pmc next
+ .param int isarray
+ $S0 = self["literal"] # set up firstchars
+ $S0 = substr $S0, 0, 1
+ self["firstchars"] = $S0
+ $I0 = self["min"] # if we allow zero reps
+ unless $I0 < 1 goto end # then add firstchars
+ self.firstchars(self, next) # of the following exp
+ end:
+.end
+
.sub "gen" method
.param pmc code
.param string label
@@ -479,7 +531,7 @@
emit(code, " goto %s_3", label)
.end
-.namespace [ "PGE::Exp::CharClass" ]
+.namespace [ "PGE::Exp::CCShortcut" ]
.sub gen method
.param pmc code
@@ -491,7 +543,7 @@
.local pmc hash
.local string test
(min, max, isgreedy, iscut) = self."_getattributes"()
- hash = find_global "PGE::Exp::CharClass", "%slashcode"
+ hash = find_global "PGE::Exp::CCShortcut", "%slashcode"
token = self["token"]
test = hash[token]
emit = find_global "PGE::Exp", "emit"
@@ -539,6 +591,12 @@
.namespace [ "PGE::Exp::Anchor" ]
+.sub "analyze" method
+ .param pmc next
+ .param int isarray
+ self.firstchars(next)
+.end
+
.sub "gen" method
.param pmc code
.param string label
@@ -587,12 +645,14 @@
.namespace [ "PGE::Exp::Concat" ]
.sub "analyze" method
+ .param pmc next
.param int isarray
.local pmc exp1, exp2
exp2 = self["exp2"]
- exp2.analyze(isarray)
+ exp2.analyze(next, isarray)
exp1 = self["exp1"]
- exp1.analyze(isarray)
+ exp1.analyze(exp2, isarray)
+ self.firstchars(exp1)
.end
.sub "gen" method
@@ -613,6 +673,12 @@
.namespace [ "PGE::Exp::Cut" ]
+.sub "analyze" method
+ .param pmc next
+ .param int isarray
+ self.firstchars(next)
+.end
+
.sub "gen" method
.param pmc code
.param string label
@@ -635,11 +701,14 @@
.namespace [ "PGE::Exp::Alt" ]
.sub "analyze" method
+ .param pmc next
.param int isarray
- $P0 = self["exp1"]
- $P0.analyze(isarray)
- $P0 = self["exp2"]
- $P0.analyze(isarray)
+ .local pmc exp1, exp2
+ exp1 = self["exp1"]
+ exp2 = self["exp2"]
+ exp1.analyze(next, isarray)
+ exp2.analyze(next, isarray)
+ self.firstchars(exp1, exp2)
.end
.sub "gen" method
@@ -664,9 +733,12 @@
.namespace [ "PGE::Exp::Group" ]
.sub "analyze" method
+ .param pmc next
.param int isarray
+ .local pmc exp1
- $I0 = self["isarray"]
+ self["firstchars"] = ""
+ $I0 = self["isarray"] # see if this is an array
isarray |= $I0
self["isarray"] = isarray
$I0 = self["cscope"]
@@ -674,10 +746,16 @@
isarray = 0
isarray_1:
$I0 = defined self["exp1"]
- unless $I0 goto isarray_2
- $P0 = self["exp1"]
- $P0.analyze(isarray)
+ unless $I0 goto end
+ exp1 = self["exp1"]
+ exp1.analyze(next, isarray)
+ $I0 = self["min"] # set up firstchars
+ if $I0 > 0 goto isarray_2
+ self.firstchars(exp1, next)
+ goto end
isarray_2:
+ self.firstchars(exp1)
+ end:
.end
.sub "gen" method
Modified: trunk/compilers/pge/PGE/P6Rule.pir
==============================================================================
--- trunk/compilers/pge/PGE/P6Rule.pir (original)
+++ trunk/compilers/pge/PGE/P6Rule.pir Wed May 4 12:38:55 2005
@@ -317,7 +317,7 @@
.param string token
.local pmc exp
$P0 = find_global "PGE::Exp", "new"
- exp = $P0("PGE::Exp::CharClass")
+ exp = $P0("PGE::Exp::CCShortcut")
exp["token"] = token
$I0 = length token
p6rule_parse_skip(pattern, lex, $I0)
Modified: trunk/runtime/parrot/library/PGE/Dumper.pir
==============================================================================
--- trunk/runtime/parrot/library/PGE/Dumper.pir (original)
+++ trunk/runtime/parrot/library/PGE/Dumper.pir Wed May 4 12:38:55 2005
@@ -26,6 +26,10 @@
.sub dump method
.param int indent
.local pmc exp1
+ $S0 = self["firstchars"]
+ print "firstchars: "
+ print $S0
+ print "\n"
exp1 = self["exp1"]
exp1."dump"(0)
.end