You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
2.6 KiB
115 lines
2.6 KiB
#! /usr/bin/node
|
|
|
|
// Tokenization, with no regular expressions, ala Rob Pike :)
|
|
|
|
function isDigit(a) {
|
|
if (!a)
|
|
return false;
|
|
var code = a.charCodeAt();
|
|
if (46 < code && code < 58 || code < 58 && code > 46)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
var TokenStream = {
|
|
lookahead :
|
|
function(n) {
|
|
return this.tokstream[this.tokstream.length-n];
|
|
},
|
|
next :
|
|
function() {
|
|
return this.lookahead(2);
|
|
},
|
|
empty :
|
|
function() {
|
|
return this.tokstream.length === 0;
|
|
},
|
|
current :
|
|
function() {
|
|
return this.tokstream[this.tokstream.length-1];
|
|
},
|
|
pop :
|
|
function() {
|
|
this.tokstream.pop();
|
|
}
|
|
}
|
|
|
|
function MakeTokStream(tokens) {
|
|
this.tokstream = tokens;
|
|
}
|
|
MakeTokStream.prototype = TokenStream;
|
|
|
|
function tokenizeNum(tokstream) {
|
|
var number = [];
|
|
tokstream.pop();
|
|
while (isDigit(tokstream.current()) && !tokstream.empty()) {
|
|
number.push(tokstream.current());
|
|
tokstream.pop();
|
|
}
|
|
if (tokstream.current() === '.' && isDigit(tokstream.next())) {
|
|
number.push('.');
|
|
number.push(tokstream.next());
|
|
tokstream.pop();
|
|
tokstream.pop();
|
|
while (isDigit(tokstream.current()) && !tokstream.empty()) {
|
|
number.push(tokstream.current());
|
|
tokstream.pop();
|
|
}
|
|
return ["Float", parseFloat(number.join(''), 10)];
|
|
}
|
|
return ["Integer", parseInt(number.join(''), 10)];
|
|
}
|
|
|
|
function tokenize(tokstream) {
|
|
var tokens = [];
|
|
|
|
while (!tokstream.empty()) {
|
|
switch (tokstream.current()) {
|
|
case '(':
|
|
tokens.push(["left_paren", '(']);
|
|
break;
|
|
case ')':
|
|
tokens.push(["right_paren", ')']);
|
|
break;
|
|
case '{':
|
|
tokens.push(["left_brace", '{']);
|
|
break;
|
|
case '}':
|
|
tokens.push(["right_brace", '}']);
|
|
break;
|
|
case '[':
|
|
tokens.push(["left_square", '[']);
|
|
break;
|
|
case ']':
|
|
tokens.push(["right_square", ']']);
|
|
break;
|
|
case '+':
|
|
var num = tokenizeNum(tokstream);
|
|
if (num !== NaN)
|
|
tokens.push(num);
|
|
break;
|
|
case '-':
|
|
var num = tokenizeNum(tokstream);
|
|
if (num !== NaN)
|
|
tokens.push(num);
|
|
break;
|
|
case '.':
|
|
var num = tokenizeNum(tokstream);
|
|
if (num !== NaN)
|
|
tokens.push(num);
|
|
break;
|
|
default:
|
|
tokens.push(["identifier", tokstream.current()]);
|
|
tokstream.pop();
|
|
}
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
var input = process.argv.slice(2).reduce(function(acc, x) {return acc + " " + x}, "").trim().split('').reverse();
|
|
|
|
var test = new MakeTokStream(input);
|
|
|
|
console.log(tokenize(test));
|
|
//console.log(isDigit('0'));
|
|
|
|
|