Skip to content
Snippets Groups Projects
Commit 714c0575 authored by Ken Rockot's avatar Ken Rockot Committed by Marijn Haverbeke
Browse files

[scheme] implement correct parsing of all numeric formats defined in R5RS

parent 000d08a6
No related branches found
No related tags found
No related merge requests found
......@@ -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 {
......@@ -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();
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment