Skip to content

Instantly share code, notes, and snippets.

@iwatakeshi
Last active October 29, 2015 23:06
Show Gist options
  • Save iwatakeshi/d1973038c1417443749f to your computer and use it in GitHub Desktop.
Save iwatakeshi/d1973038c1417443749f to your computer and use it in GitHub Desktop.
An pseudo code for mr-doc.
'use strict';
class Source {
constructor(source) {
source = source[source.length - 1] === this.EOF ?
source : source += this.EOF;
this._source = [];
for(var i = 0; i < source.length; i++) { this._source[this._source.length] = source[i]; }
this._line = 1;
this._position = 0;
this._column = 1;
}
/**
* Returns the source
* @return {Array} The source
*/
get file () {
return this._source;
}
/**
* Sets the line number
* @param {Number} num The number to assign
*/
set line (num) {
this._line = num;
}
/**
* Returns the current line number
* @return {Number} The current line number
*/
get line () {
return this._line;
}
/**
* Sets the position number
* @param {Number} num The number to assign
*/
set position (num) {
this._position = num;
}
/**
* Returns the current position
* @return {Number} The current position
*/
get position () {
return this._position;
}
/**
* Sets the column number
* @param {Number} num The number to assign
*/
set column (num) {
this._column = num;
}
/**
* Returns the current column
* @return {Number} The current column
*/
get column () {
return this._column;
}
/**
* Returns the End of File character
*/
get EOF () {
return '\0';
}
toString () {
return `line: ${ this.line }, column: ${ this.column }, position: ${ this.position }`;
}
toJSON(){
return {
"source": {
"line": this.line,
"column": this.column,
"position": this.position
}
};
}
}
class Scanner extends Source {
constructor(source){
super(source);
this._stack = [];
this._stringBuffer = '';
this._isEOF = false;
}
set isEOF (truth) {
this._isEOF = truth;
}
get isEOF () {
return this._isEOF;
}
isWhiteSpace (char) {
return char === ' ';
}
scan (callback) {
this.ignoreWhiteSpace();
while(this.peekChar() !== this.EOF) {
var token = this.nextToken(callback);
if(token) this._stack[this._stack.length] = token;
this.ignoreWhiteSpace();
}
}
nextChar () {
// If we are at the end or over the length
// of the source then return EOF
if(this.position >= this.file.length) {
this.isEOF = true;
return this.EOF;
}
// If we reach a new line then
// increment the line and reset the column
// else increment the column
if(this.file[this.position] === '\n') {
this.line++;
this.column = 1;
} else this.column++;
return this.file[this.position++];
}
peekChar (peek) {
// If we peek and the we reach the end or over
// the length then return EOF
if (this.position + peek >= this.file.length){
this.isEOF = true;
return this.EOF;
}
return this.file[this.position + (peek ? peek : 0)];
}
nextToken (callback) {
if(typeof callback === 'function'){
var character = this.peekChar();
switch(character) {
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
return callback.apply(this, ['number', character]);
break;
default:
return callback.apply(this, ['default', character]);
break;
}
}
}
ignoreWhiteSpace () {
console.log('skipping whitespace');
while(this.isWhiteSpace(this.peekChar())) {
this.nextChar();
}
}
toStream () {
return this._stack;
}
}
class Token {
constructor (type, value, source) {
this._type = type;
this._value = value;
this._source = source;
}
get type () {
return this._type;
}
get value () {
return this._value;
}
get source () {
return this._source;
}
toJSON () {
return Object.assign(this._source, {
"token": {
"type": this.type,
"value": this.value
}
});
}
}
var scanner = new Scanner("var greet = 'Hello world';\n var greet2 = 'This is cool!'");
scanner.scan(function (type, char) {
switch(type) {
case 'number':
this.nextChar();
return new Token(type, char, this.toJSON());
break;
case 'default':
this.nextChar();
return new Token('other', char, this.toJSON());
break;
}
});
scanner.toStream().forEach(token => console.log(token ? token.toJSON() : ''));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment