You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.7KB

  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. /*
  4. * Pig Latin Mode for CodeMirror 2
  5. * @author Prasanth Jayachandran
  6. * @link https://github.com/prasanthj/pig-codemirror-2
  7. * This implementation is adapted from PL/SQL mode in CodeMirror 2.
  8. */
  9. (function(mod) {
  10. if (typeof exports == "object" && typeof module == "object") // CommonJS
  11. mod(require("../../lib/codemirror"));
  12. else if (typeof define == "function" && define.amd) // AMD
  13. define(["../../lib/codemirror"], mod);
  14. else // Plain browser env
  15. mod(CodeMirror);
  16. })(function(CodeMirror) {
  17. "use strict";
  18. CodeMirror.defineMode("pig", function(_config, parserConfig) {
  19. var keywords = parserConfig.keywords,
  20. builtins = parserConfig.builtins,
  21. types = parserConfig.types,
  22. multiLineStrings = parserConfig.multiLineStrings;
  23. var isOperatorChar = /[*+\-%<>=&?:\/!|]/;
  24. function chain(stream, state, f) {
  25. state.tokenize = f;
  26. return f(stream, state);
  27. }
  28. function tokenComment(stream, state) {
  29. var isEnd = false;
  30. var ch;
  31. while(ch = stream.next()) {
  32. if(ch == "/" && isEnd) {
  33. state.tokenize = tokenBase;
  34. break;
  35. }
  36. isEnd = (ch == "*");
  37. }
  38. return "comment";
  39. }
  40. function tokenString(quote) {
  41. return function(stream, state) {
  42. var escaped = false, next, end = false;
  43. while((next = stream.next()) != null) {
  44. if (next == quote && !escaped) {
  45. end = true; break;
  46. }
  47. escaped = !escaped && next == "\\";
  48. }
  49. if (end || !(escaped || multiLineStrings))
  50. state.tokenize = tokenBase;
  51. return "error";
  52. };
  53. }
  54. function tokenBase(stream, state) {
  55. var ch = stream.next();
  56. // is a start of string?
  57. if (ch == '"' || ch == "'")
  58. return chain(stream, state, tokenString(ch));
  59. // is it one of the special chars
  60. else if(/[\[\]{}\(\),;\.]/.test(ch))
  61. return null;
  62. // is it a number?
  63. else if(/\d/.test(ch)) {
  64. stream.eatWhile(/[\w\.]/);
  65. return "number";
  66. }
  67. // multi line comment or operator
  68. else if (ch == "/") {
  69. if (stream.eat("*")) {
  70. return chain(stream, state, tokenComment);
  71. }
  72. else {
  73. stream.eatWhile(isOperatorChar);
  74. return "operator";
  75. }
  76. }
  77. // single line comment or operator
  78. else if (ch=="-") {
  79. if(stream.eat("-")){
  80. stream.skipToEnd();
  81. return "comment";
  82. }
  83. else {
  84. stream.eatWhile(isOperatorChar);
  85. return "operator";
  86. }
  87. }
  88. // is it an operator
  89. else if (isOperatorChar.test(ch)) {
  90. stream.eatWhile(isOperatorChar);
  91. return "operator";
  92. }
  93. else {
  94. // get the while word
  95. stream.eatWhile(/[\w\$_]/);
  96. // is it one of the listed keywords?
  97. if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
  98. //keywords can be used as variables like flatten(group), group.$0 etc..
  99. if (!stream.eat(")") && !stream.eat("."))
  100. return "keyword";
  101. }
  102. // is it one of the builtin functions?
  103. if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase()))
  104. return "variable-2";
  105. // is it one of the listed types?
  106. if (types && types.propertyIsEnumerable(stream.current().toUpperCase()))
  107. return "variable-3";
  108. // default is a 'variable'
  109. return "variable";
  110. }
  111. }
  112. // Interface
  113. return {
  114. startState: function() {
  115. return {
  116. tokenize: tokenBase,
  117. startOfLine: true
  118. };
  119. },
  120. token: function(stream, state) {
  121. if(stream.eatSpace()) return null;
  122. var style = state.tokenize(stream, state);
  123. return style;
  124. }
  125. };
  126. });
  127. (function() {
  128. function keywords(str) {
  129. var obj = {}, words = str.split(" ");
  130. for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
  131. return obj;
  132. }
  133. // builtin funcs taken from trunk revision 1303237
  134. var pBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
  135. + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
  136. + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
  137. + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
  138. + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
  139. + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
  140. + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
  141. + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
  142. + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
  143. + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER ";
  144. // taken from QueryLexer.g
  145. var pKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
  146. + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
  147. + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
  148. + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
  149. + "NEQ MATCHES TRUE FALSE DUMP";
  150. // data types
  151. var pTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP ";
  152. CodeMirror.defineMIME("text/x-pig", {
  153. name: "pig",
  154. builtins: keywords(pBuiltins),
  155. keywords: keywords(pKeywords),
  156. types: keywords(pTypes)
  157. });
  158. CodeMirror.registerHelper("hintWords", "pig", (pBuiltins + pTypes + pKeywords).split(" "));
  159. }());
  160. });