ocaml.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. CodeMirror.defineMode('ocaml', function() {
  2. var words = {
  3. 'true': 'atom',
  4. 'false': 'atom',
  5. 'let': 'keyword',
  6. 'rec': 'keyword',
  7. 'in': 'keyword',
  8. 'of': 'keyword',
  9. 'and': 'keyword',
  10. 'succ': 'keyword',
  11. 'if': 'keyword',
  12. 'then': 'keyword',
  13. 'else': 'keyword',
  14. 'for': 'keyword',
  15. 'to': 'keyword',
  16. 'while': 'keyword',
  17. 'do': 'keyword',
  18. 'done': 'keyword',
  19. 'fun': 'keyword',
  20. 'function': 'keyword',
  21. 'val': 'keyword',
  22. 'type': 'keyword',
  23. 'mutable': 'keyword',
  24. 'match': 'keyword',
  25. 'with': 'keyword',
  26. 'try': 'keyword',
  27. 'raise': 'keyword',
  28. 'begin': 'keyword',
  29. 'end': 'keyword',
  30. 'open': 'builtin',
  31. 'trace': 'builtin',
  32. 'ignore': 'builtin',
  33. 'exit': 'builtin',
  34. 'print_string': 'builtin',
  35. 'print_endline': 'builtin'
  36. };
  37. function tokenBase(stream, state) {
  38. var ch = stream.next();
  39. if (ch === '"') {
  40. state.tokenize = tokenString;
  41. return state.tokenize(stream, state);
  42. }
  43. if (ch === '(') {
  44. if (stream.eat('*')) {
  45. state.commentLevel++;
  46. state.tokenize = tokenComment;
  47. return state.tokenize(stream, state);
  48. }
  49. }
  50. if (ch === '~') {
  51. stream.eatWhile(/\w/);
  52. return 'variable-2';
  53. }
  54. if (ch === '`') {
  55. stream.eatWhile(/\w/);
  56. return 'quote';
  57. }
  58. if (/\d/.test(ch)) {
  59. stream.eatWhile(/[\d]/);
  60. if (stream.eat('.')) {
  61. stream.eatWhile(/[\d]/);
  62. }
  63. return 'number';
  64. }
  65. if ( /[+\-*&%=<>!?|]/.test(ch)) {
  66. return 'operator';
  67. }
  68. stream.eatWhile(/\w/);
  69. var cur = stream.current();
  70. return words[cur] || 'variable';
  71. }
  72. function tokenString(stream, state) {
  73. var next, end = false, escaped = false;
  74. while ((next = stream.next()) != null) {
  75. if (next === '"' && !escaped) {
  76. end = true;
  77. break;
  78. }
  79. escaped = !escaped && next === '\\';
  80. }
  81. if (end && !escaped) {
  82. state.tokenize = tokenBase;
  83. }
  84. return 'string';
  85. };
  86. function tokenComment(stream, state) {
  87. var prev, next;
  88. while(state.commentLevel > 0 && (next = stream.next()) != null) {
  89. if (prev === '(' && next === '*') state.commentLevel++;
  90. if (prev === '*' && next === ')') state.commentLevel--;
  91. prev = next;
  92. }
  93. if (state.commentLevel <= 0) {
  94. state.tokenize = tokenBase;
  95. }
  96. return 'comment';
  97. }
  98. return {
  99. startState: function() {return {tokenize: tokenBase, commentLevel: 0};},
  100. token: function(stream, state) {
  101. if (stream.eatSpace()) return null;
  102. return state.tokenize(stream, state);
  103. },
  104. blockCommentStart: "(*",
  105. blockCommentEnd: "*)"
  106. };
  107. });
  108. CodeMirror.defineMIME('text/x-ocaml', 'ocaml');