Files
luos/gulliver/js/codemirrorOld/contrib/scheme/js/tokenizescheme.js
Marco Antonio Nina 08c8ee9f95 Codemirror IMPROVEMENT
- Codemirror tenia varias opciones que eran incompatibles con la version de procesmaker y ie.

- Se pudo el codmirror antiguo para las secciones del Designer en el xml y javascript para evitar esos errores.
- se pudo el mismo codigo para las 3 navegadores chrome, firefox, ie.
2013-11-29 14:50:01 -04:00

242 lines
5.7 KiB
JavaScript

/* Tokenizer for Scheme code */
/**
TODO: follow the definitions in:
http://docs.racket-lang.org/reference/reader.html
to the letter; at the moment, we've just done something quick-and-dirty.
*/
var tokenizeScheme = (function() {
var isWhiteSpace = function(ch) {
// The messy regexp is because IE's regexp matcher is of the
// opinion that non-breaking spaces are no whitespace.
return ch != "\n" && /^[\s\u00a0]*$/.test(ch);
};
// scanUntilUnescaped: string-stream char -> boolean
// Advances the stream until the given character (not preceded by a
// backslash) is encountered.
// Returns true if we hit end of line without closing.
// Returns false otherwise.
var scanUntilUnescaped = function(source, end) {
var escaped = false;
while (true) {
if (source.endOfLine()) {
return true;
}
var next = source.next();
if (next == end && !escaped)
return false;
escaped = !escaped && next == "\\";
}
return false;
}
// Advance the stream until endline.
var scanUntilEndline = function(source, end) {
while (!source.endOfLine()) {
source.next();
}
}
// Some helper regexps
var isHexDigit = /[0-9A-Fa-f]/;
var whitespaceChar = new RegExp("[\\s\\u00a0]");
var isDelimiterChar =
new RegExp("[\\s\\\(\\\)\\\[\\\]\\\{\\\}\\\"\\\,\\\'\\\`\\\;]");
var isNotDelimiterChar =
new RegExp("[^\\s\\\(\\\)\\\[\\\]\\\{\\\}\\\"\\\,\\\'\\\`\\\;]");
var numberHeader = ("(?:(?:\\d+\\/\\d+)|"+
( "(?:(?:\\d+\\.\\d+|\\d+\\.|\\.\\d+)(?:[eE][+\\-]?\\d+)?)|")+
( "(?:\\d+(?:[eE][+\\-]?\\d+)?))"));
var numberPatterns = [
// complex numbers
new RegExp("^((?:(?:\\#[ei])?[+\\-]?" + numberHeader +")?"
+ "(?:[+\\-]" + numberHeader + ")i$)"),
/^((?:\#[ei])?[+-]inf.0)$/,
/^((?:\#[ei])?[+-]nan.0)$/,
new RegExp("^((?:\\#[ei])?[+\\-]?" + numberHeader + "$)"),
new RegExp("^0[xX][0-9A-Fa-f]+$")];
// looksLikeNumber: string -> boolean
// Returns true if string s looks like a number.
var looksLikeNumber = function(s) {
for (var i = 0; i < numberPatterns.length; i++) {
if (numberPatterns[i].test(s)) {
return true;
}
}
return false;
};
var UNCLOSED_STRING = function(source, setState) {
var readNewline = function() {
var content = source.get();
return { type:'whitespace', style:'whitespace', content: content };
};
var ch = source.peek();
if (ch === '\n') {
source.next();
return readNewline();
} else {
var isUnclosedString = scanUntilUnescaped(source, '"');
if (isUnclosedString) {
setState(UNCLOSED_STRING);
} else {
setState(START);
}
var content = source.get();
return {type: "string", style: "scheme-string", content: content,
isUnclosed: isUnclosedString};
}
};
var START = function(source, setState) {
// Read a word, look it up in keywords. If not found, it is a
// variable, otherwise it is a keyword of the type found.
var readWordOrNumber = function() {
source.nextWhileMatches(isNotDelimiterChar);
var word = source.get();
if (looksLikeNumber(word)) {
return {type: "number", style: "scheme-number", content: word};
} else {
return {type: "variable", style: "scheme-symbol", content: word};
}
};
var readString = function(quote) {
var isUnclosedString = scanUntilUnescaped(source, quote);
if (isUnclosedString) {
setState(UNCLOSED_STRING);
}
var word = source.get();
return {type: "string", style: "scheme-string", content: word,
isUnclosed: isUnclosedString};
};
var readPound = function() {
var text;
// FIXME: handle special things here
if (source.equals(";")) {
source.next();
text = source.get();
return {type: text,
style:"scheme-symbol",
content: text};
} else {
text = source.get();
return {type : "symbol",
style: "scheme-symbol",
content: text};
}
};
var readLineComment = function() {
scanUntilEndline(source);
var text = source.get();
return { type: "comment", style: "scheme-comment", content: text};
};
var readWhitespace = function() {
source.nextWhile(isWhiteSpace);
var content = source.get();
return { type: 'whitespace', style:'whitespace', content: content };
};
var readNewline = function() {
var content = source.get();
return { type:'whitespace', style:'whitespace', content: content };
};
// Fetch the next token. Dispatches on first character in the
// stream, or first two characters when the first is a slash.
var ch = source.next();
if (ch === '\n') {
return readNewline();
} else if (whitespaceChar.test(ch)) {
return readWhitespace();
} else if (ch === "#") {
return readPound();
} else if (ch ===';') {
return readLineComment();
} else if (ch === "\"") {
return readString(ch);
} else if (isDelimiterChar.test(ch)) {
return {type: ch, style: "scheme-punctuation"};
} else {
return readWordOrNumber();
}
}
var makeTokenizer = function(source, state) {
// Newlines are always a separate token.
var tokenizer = {
state: state,
take: function(type) {
if (typeof(type) == "string")
type = {style: type, type: type};
type.content = (type.content || "") + source.get();
type.value = type.content;
return type;
},
next: function () {
if (!source.more()) throw StopIteration;
var type;
while (!type) {
type = tokenizer.state(source, function(s) {
tokenizer.state = s;
});
}
var result = this.take(type);
return result;
}
};
return tokenizer;
};
// The external interface to the tokenizer.
return function(source, startState) {
return makeTokenizer(source, startState || START);
};
})();