Skip to content

Commit

Permalink
[scheme] implement correct parsing of all numeric formats defined in …
Browse files Browse the repository at this point in the history
…R5RS
  • Loading branch information
Ken Rockot authored and marijnh committed Jun 20, 2012
1 parent 000d08a commit 714c057
Showing 1 changed file with 59 additions and 7 deletions.
66 changes: 59 additions & 7 deletions mode/scheme/scheme.js
Expand Up @@ -29,6 +29,30 @@ CodeMirror.defineMode("scheme", function (config, mode) {
state.indentStack = state.indentStack.prev;
}

var binaryMatcher = new RegExp(/^(?:[-+]i|[-+][01]+#*(?:\/[01]+#*)?i|[-+]?[01]+#*(?:\/[01]+#*)?@[-+]?[01]+#*(?:\/[01]+#*)?|[-+]?[01]+#*(?:\/[01]+#*)?[-+](?:[01]+#*(?:\/[01]+#*)?)?i|[-+]?[01]+#*(?:\/[01]+#*)?)(?=[()\s;"]|$)/i);
var octalMatcher = new RegExp(/^(?:[-+]i|[-+][0-7]+#*(?:\/[0-7]+#*)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?@[-+]?[0-7]+#*(?:\/[0-7]+#*)?|[-+]?[0-7]+#*(?:\/[0-7]+#*)?[-+](?:[0-7]+#*(?:\/[0-7]+#*)?)?i|[-+]?[0-7]+#*(?:\/[0-7]+#*)?)(?=[()\s;"]|$)/i);
var hexMatcher = new RegExp(/^(?:[-+]i|[-+][\da-f]+#*(?:\/[\da-f]+#*)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?@[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?[-+](?:[\da-f]+#*(?:\/[\da-f]+#*)?)?i|[-+]?[\da-f]+#*(?:\/[\da-f]+#*)?)(?=[()\s;"]|$)/i);
var decimalMatcher = new RegExp(/^(?:[-+]i|[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)i|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)@[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)|[-+]?(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)[-+](?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*)?i|(?:(?:(?:\d+#+\.?#*|\d+\.\d*#*|\.\d+#*|\d+)(?:[esfdl][-+]?\d+)?)|\d+#*\/\d+#*))(?=[()\s;"]|$)/i);

function isBinaryNumber (stream) {
return stream.match(binaryMatcher);
}

function isOctalNumber (stream) {
return stream.match(octalMatcher);
}

function isDecimalNumber (stream, backup) {
if (backup === true) {
stream.backUp(1);
}
return stream.match(decimalMatcher);
}

function isHexNumber (stream) {
return stream.match(hexMatcher);
}

return {
startState: function () {
return {
Expand Down Expand Up @@ -97,22 +121,50 @@ CodeMirror.defineMode("scheme", function (config, mode) {
} else if (ch == "'") {
returnType = ATOM;
} else if (ch == '#') {
if (stream.eat("|")) { // Multi-line comment
if (stream.eat("|")) { // Multi-line comment
state.mode = "comment"; // toggle to comment mode
returnType = COMMENT;
} else if (stream.eat(/[tf]/)) { // #t/#f (atom)
} else if (stream.eat(/[tf]/i)) { // #t/#f (atom)
returnType = ATOM;
} else if (stream.eat(';')) { // S-Expr comment
} else if (stream.eat(';')) { // S-Expr comment
state.mode = "s-expr-comment";
returnType = COMMENT;
} else {
var numTest = null, hasExactness = false, hasRadix = true;
if (stream.eat(/[ei]/i)) {
hasExactness = true;
} else {
stream.backUp(1); // must be radix specifier
}
if (stream.match(/^#b/i)) {
numTest = isBinaryNumber;
} else if (stream.match(/^#o/i)) {
numTest = isOctalNumber;
} else if (stream.match(/^#x/i)) {
numTest = isHexNumber;
} else if (stream.match(/^#d/i)) {
numTest = isDecimalNumber;
} else if (stream.match(/^[-+0-9.]/, false)) {
hasRadix = false;
numTest = isDecimalNumber;
// re-consume the intial # if all matches failed
} else if (!hasExactness) {
stream.eat('#');
}
if (numTest != null) {
if (hasRadix && !hasExactness) {
// consume optional exactness after radix
stream.match(/^#[ei]/i);
}
if (numTest(stream))
returnType = NUMBER;
}
}

} else if (/^[-+0-9.]/.test(ch) && isDecimalNumber(stream, true)) { // match non-prefixed number, must be decimal
returnType = NUMBER;
} else if (ch == ";") { // comment
stream.skipToEnd(); // rest of the line is a comment
returnType = COMMENT;
} else if (/\d/.test(ch) && stream.match(/$|^\d*(?:\/\d+|(?:\.\d+)?(?:[eE][+\-]?\d+)?)\b/) ||
ch == "-" && stream.match(/^\d+(?:\/\d+|(?:\.\d+)?(?:[eE][+\-]?\d+)?)\b/)) {
returnType = NUMBER;
} else if (ch == "(" || ch == "[") {
var keyWord = ''; var indentTemp = stream.column();
/**
Expand Down

0 comments on commit 714c057

Please sign in to comment.