Skip to main content
Module

x/ohm_js/src/InputStream.js

A library and language for building parsers, interpreters, compilers, etc.
Go to Latest
File
'use strict';
// --------------------------------------------------------------------// Imports// --------------------------------------------------------------------
const Interval = require('./Interval');
// --------------------------------------------------------------------// Private stuff// --------------------------------------------------------------------
function InputStream(source) { this.source = source; this.pos = 0; this.examinedLength = 0;}
InputStream.prototype = { atEnd() { const ans = this.pos === this.source.length; this.examinedLength = Math.max(this.examinedLength, this.pos + 1); return ans; },
next() { const ans = this.source[this.pos++]; this.examinedLength = Math.max(this.examinedLength, this.pos); return ans; },
nextCharCode() { const nextChar = this.next(); return nextChar && nextChar.charCodeAt(0); },
nextCodePoint() { const cp = this.source.slice(this.pos++).codePointAt(0); // If the code point is beyond plane 0, it takes up two characters. if (cp > 0xffff) { this.pos += 1; } this.examinedLength = Math.max(this.examinedLength, this.pos); return cp; },
matchString(s, optIgnoreCase) { let idx; if (optIgnoreCase) { /* Case-insensitive comparison is a tricky business. Some notable gotchas include the "Turkish I" problem (http://www.i18nguy.com/unicode/turkish-i18n.html) and the fact that the German Esszet (ß) turns into "SS" in upper case.
This is intended to be a locale-invariant comparison, which means it may not obey locale-specific expectations (e.g. "i" => "İ"). */ for (idx = 0; idx < s.length; idx++) { const actual = this.next(); const expected = s[idx]; if (actual == null || actual.toUpperCase() !== expected.toUpperCase()) { return false; } } return true; } // Default is case-sensitive comparison. for (idx = 0; idx < s.length; idx++) { if (this.next() !== s[idx]) { return false; } } return true; },
sourceSlice(startIdx, endIdx) { return this.source.slice(startIdx, endIdx); },
interval(startIdx, optEndIdx) { return new Interval(this.source, startIdx, optEndIdx ? optEndIdx : this.pos); },};
// --------------------------------------------------------------------// Exports// --------------------------------------------------------------------
module.exports = InputStream;