StringStream.min.js (2799B)
1 import { countColumn } from "./misc.js" 2 3 // STRING STREAM 4 5 // Fed to the mode parsers, provides helper functions to make 6 // parsers more succinct. 7 8 class StringStream { 9 constructor(string, tabSize, lineOracle) { 10 this.pos = this.start = 0 11 this.string = string 12 this.tabSize = tabSize || 8 13 this.lastColumnPos = this.lastColumnValue = 0 14 this.lineStart = 0 15 this.lineOracle = lineOracle 16 } 17 18 eol() {return this.pos >= this.string.length} 19 sol() {return this.pos == this.lineStart} 20 peek() {return this.string.charAt(this.pos) || undefined} 21 next() { 22 if (this.pos < this.string.length) 23 return this.string.charAt(this.pos++) 24 } 25 eat(match) { 26 let ch = this.string.charAt(this.pos) 27 let ok 28 if (typeof match == "string") ok = ch == match 29 else ok = ch && (match.test ? match.test(ch) : match(ch)) 30 if (ok) {++this.pos; return ch} 31 } 32 eatWhile(match) { 33 let start = this.pos 34 while (this.eat(match)){} 35 return this.pos > start 36 } 37 eatSpace() { 38 let start = this.pos 39 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos 40 return this.pos > start 41 } 42 skipToEnd() {this.pos = this.string.length} 43 skipTo(ch) { 44 let found = this.string.indexOf(ch, this.pos) 45 if (found > -1) {this.pos = found; return true} 46 } 47 backUp(n) {this.pos -= n} 48 column() { 49 if (this.lastColumnPos < this.start) { 50 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue) 51 this.lastColumnPos = this.start 52 } 53 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) 54 } 55 indentation() { 56 return countColumn(this.string, null, this.tabSize) - 57 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) 58 } 59 match(pattern, consume, caseInsensitive) { 60 if (typeof pattern == "string") { 61 let cased = str => caseInsensitive ? str.toLowerCase() : str 62 let substr = this.string.substr(this.pos, pattern.length) 63 if (cased(substr) == cased(pattern)) { 64 if (consume !== false) this.pos += pattern.length 65 return true 66 } 67 } else { 68 let match = this.string.slice(this.pos).match(pattern) 69 if (match && match.index > 0) return null 70 if (match && consume !== false) this.pos += match[0].length 71 return match 72 } 73 } 74 current(){return this.string.slice(this.start, this.pos)} 75 hideFirstChars(n, inner) { 76 this.lineStart += n 77 try { return inner() } 78 finally { this.lineStart -= n } 79 } 80 lookAhead(n) { 81 let oracle = this.lineOracle 82 return oracle && oracle.lookAhead(n) 83 } 84 baseToken() { 85 let oracle = this.lineOracle 86 return oracle && oracle.baseToken(this.pos) 87 } 88 } 89 90 export default StringStream