summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-05-19 16:25:32 +0000
committerMartin Odersky <odersky@gmail.com>2009-05-19 16:25:32 +0000
commitb3ce4c4f7d2e2016d7b71bea2df7aa6dc75bc3d5 (patch)
tree6920117580b355522f14bc168de0463f8677a3aa /src/compiler/scala/tools/nsc/util/CharArrayReader.scala
parent14fb2dfadd8ef9b433fed2599c1b32049d4c90e2 (diff)
downloadscala-b3ce4c4f7d2e2016d7b71bea2df7aa6dc75bc3d5.tar.gz
scala-b3ce4c4f7d2e2016d7b71bea2df7aa6dc75bc3d5.tar.bz2
scala-b3ce4c4f7d2e2016d7b71bea2df7aa6dc75bc3d5.zip
small modifications to collections.
Diffstat (limited to 'src/compiler/scala/tools/nsc/util/CharArrayReader.scala')
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/nsc/util/CharArrayReader.scala171
1 files changed, 72 insertions, 99 deletions
diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
index a6c10520bb..a6b59cdcae 100644..100755
--- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
+++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala
@@ -2,125 +2,89 @@
* Copyright 2005-2009 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
+// $Id: NewCharArrayReader.scala 16893 2009-01-13 13:09:22Z cunei $
package scala.tools.nsc.util
import scala.tools.nsc.util.SourceFile.{LF, FF, CR, SU}
-class CharArrayReader(buf: RandomAccessSeq[Char], start: Int, /* startline: int, startcol: int, */
- decodeUni: Boolean, error: String => Unit) extends Iterator[Char] with Cloneable {
+abstract class CharArrayReader { self =>
- def this(buf: RandomAccessSeq[Char], decodeUni: Boolean, error: String => Unit) =
- this(buf, 0, /* 1, 1, */ decodeUni, error)
+ val buf: Array[Char]
- /** produce a duplicate of this char array reader which starts reading
- * at current position, independent of what happens to original reader
- */
- def dup: CharArrayReader = clone().asInstanceOf[CharArrayReader]
+ def decodeUni: Boolean = true
- /** layout constant
- */
- val tabinc = 8
+ /** An error routine to call on bad unicode escapes \\uxxxx. */
+ protected def error(offset: Int, msg: String)
- /** the line and column position of the current character
- */
+ /** the last read character */
var ch: Char = _
- var bp = start
- var oldBp = -1
- var oldCh: Char = _
-
- //private var cline: Int = _
- //private var ccol: Int = _
- def cpos = bp
- var isUnicode: Boolean = _
- var lastLineStartPos: Int = 0
- var lineStartPos: Int = 0
- var lastBlankLinePos: Int = 0
-
- private var onlyBlankChars = false
- //private var nextline = startline
- //private var nextcol = startcol
-
- private def markNewLine() {
- lastLineStartPos = lineStartPos
- if (onlyBlankChars) lastBlankLinePos = lineStartPos
- lineStartPos = bp
- onlyBlankChars = true
- //nextline += 1
- //nextcol = 1
- }
- def hasNext: Boolean = if (bp < buf.length) true
- else {
- false
- }
+ /** The offset one past the last read character */
+ var charOffset: Int = 0
+
+ /** The start offset of the current line */
+ var lineStartOffset: Int = 0
+
+ /** The start offset of the line before the current one */
+ var lastLineStartOffset: Int = 0
- def last: Char = if (bp > start + 2) buf(bp - 2) else ' ' // XML literals
+ private var lastUnicodeOffset = -1
- def next: Char = {
- //cline = nextline
- //ccol = nextcol
- val buf = this.buf.asInstanceOf[runtime.BoxedCharArray].value
- if(!hasNext) {
+ /** Is last character a unicode escape \\uxxxx? */
+ def isUnicodeEscape = charOffset == lastUnicodeOffset
+
+ /** Advance one character */
+ final def nextChar() {
+ if (charOffset >= buf.length) {
ch = SU
- return SU // there is an endless stream of SU's at the end
- }
- oldBp = bp
- oldCh = ch
- ch = buf(bp)
- isUnicode = false
- bp = bp + 1
- ch match {
- case '\t' =>
- // nextcol = ((nextcol - 1) / tabinc * tabinc) + tabinc + 1;
- case CR =>
- if (bp < buf.size && buf(bp) == LF) {
- ch = LF
- bp += 1
- }
- markNewLine()
- case LF | FF =>
- markNewLine()
- case '\\' =>
- def evenSlashPrefix: Boolean = {
- var p = bp - 2
- while (p >= 0 && buf(p) == '\\') p -= 1
- (bp - p) % 2 == 0
- }
- def udigit: Int = {
- val d = digit2int(buf(bp), 16)
- if (d >= 0) { bp += 1; /* nextcol = nextcol + 1 */ }
- else error("error in unicode escape");
- d
- }
- // nextcol += 1
- if (buf(bp) == 'u' && decodeUni && evenSlashPrefix) {
- do {
- bp += 1 //; nextcol += 1
- } while (buf(bp) == 'u');
- val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit
- ch = code.asInstanceOf[Char]
- isUnicode = true
- }
- case _ =>
- if (ch > ' ') onlyBlankChars = false
- // nextcol += 1
+ } else {
+ val c = buf(charOffset)
+ ch = c
+ charOffset += 1
+ if (c == '\\') potentialUnicode()
+ else if (c < ' ') potentialLineEnd()
+// print("`"+ch+"'")
}
- ch
}
- def rewind {
- if (oldBp == -1) throw new IllegalArgumentException
- bp = oldBp
- ch = oldCh
- oldBp = -1
- oldCh = 'x'
+ /** Interpret \\uxxxx escapes */
+ private def potentialUnicode() {
+ def evenSlashPrefix: Boolean = {
+ var p = charOffset - 2
+ while (p >= 0 && buf(p) == '\\') p -= 1
+ (charOffset - p) % 2 == 0
+ }
+ def udigit: Int = {
+ val d = digit2int(buf(charOffset), 16)
+ if (d >= 0) charOffset += 1
+ else error(charOffset, "error in unicode escape")
+ d
+ }
+ if (charOffset < buf.length && buf(charOffset) == 'u' && decodeUni && evenSlashPrefix) {
+ do charOffset += 1
+ while (charOffset < buf.length && buf(charOffset) == 'u')
+ val code = udigit << 12 | udigit << 8 | udigit << 4 | udigit
+ lastUnicodeOffset = charOffset
+ ch = code.toChar
+ }
}
- def copy: CharArrayReader =
- new CharArrayReader(buf, bp, /* nextcol, nextline, */ decodeUni, error)
+ /** Handle line ends, replace CR+LF by LF */
+ private def potentialLineEnd() {
+ if (ch == CR)
+ if (charOffset < buf.length && buf(charOffset) == LF) {
+ charOffset += 1
+ ch = LF
+ }
+ if (ch == LF || ch == FF) {
+ lastLineStartOffset = lineStartOffset
+ lineStartOffset = charOffset
+ }
+ }
+ /** Convert a character digit to an Int according to given base,
+ * -1 if no success */
def digit2int(ch: Char, base: Int): Int = {
if ('0' <= ch && ch <= '9' && ch < '0' + base)
ch - '0'
@@ -131,4 +95,13 @@ class CharArrayReader(buf: RandomAccessSeq[Char], start: Int, /* startline: int,
else
-1
}
+
+ /** A new reader that takes off at the current character position */
+ def lookaheadReader = new CharArrayReader {
+ val buf = self.buf
+ charOffset = self.charOffset
+ ch = self.ch
+ override def decodeUni = self.decodeUni
+ def error(offset: Int, msg: String) = self.error(offset, msg)
+ }
}