5
if (typeof exports == "object" && typeof module == "object")
6
mod(require("../../lib/codemirror"));
7
else if (typeof define == "function" && define.amd)
8
define(["../../lib/codemirror"], mod);
11
})(function(CodeMirror) {
14
CodeMirror.defineMode("oz", function (conf) {
16
function wordRegexp(words) {
17
return new RegExp("^((" + words.join(")|(") + "))\\b");
20
var singleOperators = /[\^@!\|<>#~\.\*\-\+\\/,=]/;
21
var doubleOperators = /(<-)|(:=)|(=<)|(>=)|(<=)|(<:)|(>:)|(=:)|(\\=)|(\\=:)|(!!)|(==)|(::)/;
22
var tripleOperators = /(:::)|(\.\.\.)|(=<:)|(>=:)/;
24
var middle = ["in", "then", "else", "of", "elseof", "elsecase", "elseif", "catch",
25
"finally", "with", "require", "prepare", "import", "export", "define", "do"];
28
var atoms = wordRegexp(["true", "false", "nil", "unit"]);
29
var commonKeywords = wordRegexp(["andthen", "at", "attr", "declare", "feat", "from", "lex",
30
"mod", "div", "mode", "orelse", "parser", "prod", "prop", "scanner", "self", "syn", "token"]);
31
var openingKeywords = wordRegexp(["local", "proc", "fun", "case", "class", "if", "cond", "or", "dis",
32
"choice", "not", "thread", "try", "raise", "lock", "for", "suchthat", "meth", "functor"]);
33
var middleKeywords = wordRegexp(middle);
34
var endKeywords = wordRegexp(end);
37
function tokenBase(stream, state) {
38
if (stream.eatSpace()) {
43
if(stream.match(/[{}]/)) {
48
if (stream.match('[]')) {
53
if (stream.match(tripleOperators) || stream.match(doubleOperators)) {
58
if(stream.match(atoms)) {
63
var matched = stream.match(openingKeywords);
65
if (!state.doInCurrentLine)
66
state.currentIndent++;
68
state.doInCurrentLine = false;
71
if(matched[0] == "proc" || matched[0] == "fun")
72
state.tokenize = tokenFunProc;
73
else if(matched[0] == "class")
74
state.tokenize = tokenClass;
75
else if(matched[0] == "meth")
76
state.tokenize = tokenMeth;
82
if (stream.match(middleKeywords) || stream.match(commonKeywords)) {
87
if (stream.match(endKeywords)) {
88
state.currentIndent--;
93
var ch = stream.next();
96
if (ch == '"' || ch == "'") {
97
state.tokenize = tokenString(ch);
98
return state.tokenize(stream, state);
102
if (/[~\d]/.test(ch)) {
104
if(! /^[0-9]/.test(stream.peek()))
106
else if (( stream.next() == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) || stream.match(/^[0-9]*(\.[0-9]+)?([eE][~+]?[0-9]+)?/))
110
if ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) || stream.match(/^[0-9]*(\.[0-9]+)?([eE][~+]?[0-9]+)?/))
121
else if (ch == "/") {
122
if (stream.eat("*")) {
123
state.tokenize = tokenComment;
124
return tokenComment(stream, state);
129
if(singleOperators.test(ch)) {
134
stream.eatWhile(/\w/);
139
function tokenClass(stream, state) {
140
if (stream.eatSpace()) {
143
stream.match(/([A-Z][A-Za-z0-9_]*)|(`.+`)/);
144
state.tokenize = tokenBase;
148
function tokenMeth(stream, state) {
149
if (stream.eatSpace()) {
152
stream.match(/([a-zA-Z][A-Za-z0-9_]*)|(`.+`)/);
153
state.tokenize = tokenBase;
157
function tokenFunProc(stream, state) {
158
if (stream.eatSpace()) {
162
if(!state.hasPassedFirstStage && stream.eat("{")) {
163
state.hasPassedFirstStage = true;
166
else if(state.hasPassedFirstStage) {
167
stream.match(/([A-Z][A-Za-z0-9_]*)|(`.+`)|\$/);
168
state.hasPassedFirstStage = false;
169
state.tokenize = tokenBase;
173
state.tokenize = tokenBase;
178
function tokenComment(stream, state) {
179
var maybeEnd = false, ch;
180
while (ch = stream.next()) {
181
if (ch == "/" && maybeEnd) {
182
state.tokenize = tokenBase;
185
maybeEnd = (ch == "*");
190
function tokenString(quote) {
191
return function (stream, state) {
192
var escaped = false, next, end = false;
193
while ((next = stream.next()) != null) {
194
if (next == quote && !escaped) {
198
escaped = !escaped && next == "\\";
201
state.tokenize = tokenBase;
206
function buildElectricInputRegEx() {
209
var allClosings = middle.concat(end);
210
return new RegExp("[\\[\\]]|(" + allClosings.join("|") + ")$");
215
startState: function () {
219
doInCurrentLine: false,
220
hasPassedFirstStage: false
224
token: function (stream, state) {
226
state.doInCurrentLine = 0;
228
return state.tokenize(stream, state);
231
indent: function (state, textAfter) {
232
var trueText = textAfter.replace(/^\s+|\s+$/g, '');
234
if (trueText.match(endKeywords) || trueText.match(middleKeywords) || trueText.match(/(\[])/))
235
return conf.indentUnit * (state.currentIndent - 1);
237
if (state.currentIndent < 0)
240
return state.currentIndent * conf.indentUnit;
243
electricInput: buildElectricInputRegEx(),
245
blockCommentStart: "/*",
246
blockCommentEnd: "*/"
250
CodeMirror.defineMIME("text/x-oz", "oz");