ttcn.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. (function(mod) {
  4. if (typeof exports == "object" && typeof module == "object") // CommonJS
  5. mod(require("../../lib/codemirror"));
  6. else if (typeof define == "function" && define.amd) // AMD
  7. define(["../../lib/codemirror"], mod);
  8. else // Plain browser env
  9. mod(CodeMirror);
  10. })(function(CodeMirror) {
  11. "use strict";
  12. CodeMirror.defineMode("ttcn", function(config, parserConfig) {
  13. var indentUnit = config.indentUnit,
  14. keywords = parserConfig.keywords || {},
  15. builtin = parserConfig.builtin || {},
  16. timerOps = parserConfig.timerOps || {},
  17. portOps = parserConfig.portOps || {},
  18. configOps = parserConfig.configOps || {},
  19. verdictOps = parserConfig.verdictOps || {},
  20. sutOps = parserConfig.sutOps || {},
  21. functionOps = parserConfig.functionOps || {},
  22. verdictConsts = parserConfig.verdictConsts || {},
  23. booleanConsts = parserConfig.booleanConsts || {},
  24. otherConsts = parserConfig.otherConsts || {},
  25. types = parserConfig.types || {},
  26. visibilityModifiers = parserConfig.visibilityModifiers || {},
  27. templateMatch = parserConfig.templateMatch || {},
  28. multiLineStrings = parserConfig.multiLineStrings,
  29. indentStatements = parserConfig.indentStatements !== false;
  30. var isOperatorChar = /[+\-*&@=<>!\/]/;
  31. var curPunc;
  32. function tokenBase(stream, state) {
  33. var ch = stream.next();
  34. if (ch == '"' || ch == "'") {
  35. state.tokenize = tokenString(ch);
  36. return state.tokenize(stream, state);
  37. }
  38. if (/[\[\]{}\(\),;\\:\?\.]/.test(ch)) {
  39. curPunc = ch;
  40. return "punctuation";
  41. }
  42. if (ch == "#"){
  43. stream.skipToEnd();
  44. return "atom preprocessor";
  45. }
  46. if (ch == "%"){
  47. stream.eatWhile(/\b/);
  48. return "atom ttcn3Macros";
  49. }
  50. if (/\d/.test(ch)) {
  51. stream.eatWhile(/[\w\.]/);
  52. return "number";
  53. }
  54. if (ch == "/") {
  55. if (stream.eat("*")) {
  56. state.tokenize = tokenComment;
  57. return tokenComment(stream, state);
  58. }
  59. if (stream.eat("/")) {
  60. stream.skipToEnd();
  61. return "comment";
  62. }
  63. }
  64. if (isOperatorChar.test(ch)) {
  65. if(ch == "@"){
  66. if(stream.match("try") || stream.match("catch")
  67. || stream.match("lazy")){
  68. return "keyword";
  69. }
  70. }
  71. stream.eatWhile(isOperatorChar);
  72. return "operator";
  73. }
  74. stream.eatWhile(/[\w\$_\xa1-\uffff]/);
  75. var cur = stream.current();
  76. if (keywords.propertyIsEnumerable(cur)) return "keyword";
  77. if (builtin.propertyIsEnumerable(cur)) return "builtin";
  78. if (timerOps.propertyIsEnumerable(cur)) return "def timerOps";
  79. if (configOps.propertyIsEnumerable(cur)) return "def configOps";
  80. if (verdictOps.propertyIsEnumerable(cur)) return "def verdictOps";
  81. if (portOps.propertyIsEnumerable(cur)) return "def portOps";
  82. if (sutOps.propertyIsEnumerable(cur)) return "def sutOps";
  83. if (functionOps.propertyIsEnumerable(cur)) return "def functionOps";
  84. if (verdictConsts.propertyIsEnumerable(cur)) return "string verdictConsts";
  85. if (booleanConsts.propertyIsEnumerable(cur)) return "string booleanConsts";
  86. if (otherConsts.propertyIsEnumerable(cur)) return "string otherConsts";
  87. if (types.propertyIsEnumerable(cur)) return "builtin types";
  88. if (visibilityModifiers.propertyIsEnumerable(cur))
  89. return "builtin visibilityModifiers";
  90. if (templateMatch.propertyIsEnumerable(cur)) return "atom templateMatch";
  91. return "variable";
  92. }
  93. function tokenString(quote) {
  94. return function(stream, state) {
  95. var escaped = false, next, end = false;
  96. while ((next = stream.next()) != null) {
  97. if (next == quote && !escaped){
  98. var afterQuote = stream.peek();
  99. //look if the character after the quote is like the B in '10100010'B
  100. if (afterQuote){
  101. afterQuote = afterQuote.toLowerCase();
  102. if(afterQuote == "b" || afterQuote == "h" || afterQuote == "o")
  103. stream.next();
  104. }
  105. end = true; break;
  106. }
  107. escaped = !escaped && next == "\\";
  108. }
  109. if (end || !(escaped || multiLineStrings))
  110. state.tokenize = null;
  111. return "string";
  112. };
  113. }
  114. function tokenComment(stream, state) {
  115. var maybeEnd = false, ch;
  116. while (ch = stream.next()) {
  117. if (ch == "/" && maybeEnd) {
  118. state.tokenize = null;
  119. break;
  120. }
  121. maybeEnd = (ch == "*");
  122. }
  123. return "comment";
  124. }
  125. function Context(indented, column, type, align, prev) {
  126. this.indented = indented;
  127. this.column = column;
  128. this.type = type;
  129. this.align = align;
  130. this.prev = prev;
  131. }
  132. function pushContext(state, col, type) {
  133. var indent = state.indented;
  134. if (state.context && state.context.type == "statement")
  135. indent = state.context.indented;
  136. return state.context = new Context(indent, col, type, null, state.context);
  137. }
  138. function popContext(state) {
  139. var t = state.context.type;
  140. if (t == ")" || t == "]" || t == "}")
  141. state.indented = state.context.indented;
  142. return state.context = state.context.prev;
  143. }
  144. //Interface
  145. return {
  146. startState: function(basecolumn) {
  147. return {
  148. tokenize: null,
  149. context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
  150. indented: 0,
  151. startOfLine: true
  152. };
  153. },
  154. token: function(stream, state) {
  155. var ctx = state.context;
  156. if (stream.sol()) {
  157. if (ctx.align == null) ctx.align = false;
  158. state.indented = stream.indentation();
  159. state.startOfLine = true;
  160. }
  161. if (stream.eatSpace()) return null;
  162. curPunc = null;
  163. var style = (state.tokenize || tokenBase)(stream, state);
  164. if (style == "comment") return style;
  165. if (ctx.align == null) ctx.align = true;
  166. if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
  167. && ctx.type == "statement"){
  168. popContext(state);
  169. }
  170. else if (curPunc == "{") pushContext(state, stream.column(), "}");
  171. else if (curPunc == "[") pushContext(state, stream.column(), "]");
  172. else if (curPunc == "(") pushContext(state, stream.column(), ")");
  173. else if (curPunc == "}") {
  174. while (ctx.type == "statement") ctx = popContext(state);
  175. if (ctx.type == "}") ctx = popContext(state);
  176. while (ctx.type == "statement") ctx = popContext(state);
  177. }
  178. else if (curPunc == ctx.type) popContext(state);
  179. else if (indentStatements &&
  180. (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
  181. (ctx.type == "statement" && curPunc == "newstatement")))
  182. pushContext(state, stream.column(), "statement");
  183. state.startOfLine = false;
  184. return style;
  185. },
  186. electricChars: "{}",
  187. blockCommentStart: "/*",
  188. blockCommentEnd: "*/",
  189. lineComment: "//",
  190. fold: "brace"
  191. };
  192. });
  193. function words(str) {
  194. var obj = {}, words = str.split(" ");
  195. for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
  196. return obj;
  197. }
  198. function def(mimes, mode) {
  199. if (typeof mimes == "string") mimes = [mimes];
  200. var words = [];
  201. function add(obj) {
  202. if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
  203. words.push(prop);
  204. }
  205. add(mode.keywords);
  206. add(mode.builtin);
  207. add(mode.timerOps);
  208. add(mode.portOps);
  209. if (words.length) {
  210. mode.helperType = mimes[0];
  211. CodeMirror.registerHelper("hintWords", mimes[0], words);
  212. }
  213. for (var i = 0; i < mimes.length; ++i)
  214. CodeMirror.defineMIME(mimes[i], mode);
  215. }
  216. def(["text/x-ttcn", "text/x-ttcn3", "text/x-ttcnpp"], {
  217. name: "ttcn",
  218. keywords: words("activate address alive all alt altstep and and4b any" +
  219. " break case component const continue control deactivate" +
  220. " display do else encode enumerated except exception" +
  221. " execute extends extension external for from function" +
  222. " goto group if import in infinity inout interleave" +
  223. " label language length log match message mixed mod" +
  224. " modifies module modulepar mtc noblock not not4b nowait" +
  225. " of on optional or or4b out override param pattern port" +
  226. " procedure record recursive rem repeat return runs select" +
  227. " self sender set signature system template testcase to" +
  228. " type union value valueof var variant while with xor xor4b"),
  229. builtin: words("bit2hex bit2int bit2oct bit2str char2int char2oct encvalue" +
  230. " decomp decvalue float2int float2str hex2bit hex2int" +
  231. " hex2oct hex2str int2bit int2char int2float int2hex" +
  232. " int2oct int2str int2unichar isbound ischosen ispresent" +
  233. " isvalue lengthof log2str oct2bit oct2char oct2hex oct2int" +
  234. " oct2str regexp replace rnd sizeof str2bit str2float" +
  235. " str2hex str2int str2oct substr unichar2int unichar2char" +
  236. " enum2int"),
  237. types: words("anytype bitstring boolean char charstring default float" +
  238. " hexstring integer objid octetstring universal verdicttype timer"),
  239. timerOps: words("read running start stop timeout"),
  240. portOps: words("call catch check clear getcall getreply halt raise receive" +
  241. " reply send trigger"),
  242. configOps: words("create connect disconnect done kill killed map unmap"),
  243. verdictOps: words("getverdict setverdict"),
  244. sutOps: words("action"),
  245. functionOps: words("apply derefers refers"),
  246. verdictConsts: words("error fail inconc none pass"),
  247. booleanConsts: words("true false"),
  248. otherConsts: words("null NULL omit"),
  249. visibilityModifiers: words("private public friend"),
  250. templateMatch: words("complement ifpresent subset superset permutation"),
  251. multiLineStrings: true
  252. });
  253. });