File size: 5,001 Bytes
e111422
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
import * as CodeMirror from 'codemirror';
import 'codemirror/addon/mode/simple';

// "use strict";

// from where select predicate in as order by asc desc module result this super
// abstract cached external final library noopt private deprecated override query pragma language bindingset noinline nomagic monotonicAggregates transient
// not and or implies exists forall forex any none
// if then else
// int float string boolean date
// import
// class extends instanceof
// avg concat count max min rank strictconcat strictcount strictsum sum
// false true
var builtins_base = [
  "from", "where", "select", "predicate", "in", "as", "order", "by", "asc", "desc", "module", "result", "this", "super",
  "abstract", "cached", "external", "final", "library", "noopt", "private", "deprecated", "override", "query", "pragma", "language", "bindingset", "noinline", "nomagic", "monotonicAggregates", "transient",
  "not", "and", "or", "implies", "exists", "forall", "forex", "any", "none",
  "if", "then", "else",
  "int", "float", "string", "boolean", "date",
  "import",
  "class", "extends", "instanceof",
  "avg", "concat", "count", "max", "min", "rank", "strictconcat", "strictcount", "strictsum", "sum",
  "false", "true"
];
var builtins_str = '(' + builtins_base.join('|') + ')\\b';

var builtins_functions = [];
var builtins_fun_str = '(' + builtins_functions.join('|') + ')(?=\\()';

CodeMirror.defineSimpleMode("codeql", {
  // The start state contains the rules that are intially used
  start: [
    // Comments
    { regex: /\/\/\/?.*$/, token: 'comment', sol: true },
    { regex: /(\s)\/\/\/?.*$/, token: 'comment' },
    { regex: /\s*\*.*$/, token: 'comment', sol: true },
    { regex: /\/\*/, token: 'comment', push: 'comments_block' },

    // Strings
    { regex: /"/, token: 'string', push: 'string_regular' },
    { regex: /`"/, token: 'string', push: 'string_compound' },

    // Macros
    { regex: /`/, token: 'variable-2', push: 'macro_local' },
    { regex: /\$/, token: 'variable-2', push: 'macro_global' },

    // Decimal Numbers
    {
      regex: /\b[+-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+|\.)(?:[eE][+-]?[0-9]+)?[i]?\b/,
      token: 'number'
    },

    // Keywords
    // There are two separate dictionaries because the `\b` at the beginning of the regex seemed not to work. So instead, I either match the preceding space before the keyword or require the keyword to be at beginning of the string. I think this necessitates two different strings.
    { regex: new RegExp('\\s' + builtins_str), token: 'keyword' },
    { regex: new RegExp(builtins_str), token: 'keyword', sol: true },

    { regex: new RegExp('\\s' + builtins_fun_str), token: 'def' },
    { regex: /\s\w+(?=\()/, token: 'def' },

    { regex: /[\{]/, indent: true },
    { regex: /[\}]/, dedent: true },

    { regex: /-|==|<=|>=|<|>|&|!=/, token: 'operator' },
    { regex: /\*|\+|\^|\/|!|~|=|~=/, token: 'operator' },
  ],
  comments_block: [
    { regex: /\/\*/, token: 'comment', push: 'comments_block' },
    // this ends and restarts a comment block. but need to catch this so
    // that it doesn\'t start _another_ level of comment blocks
    { regex: /\*\/\*/, token: 'comment' },
    { regex: /(\*\/\s+\*(?!\/)[^\n]*)|(\*\/)/, token: 'comment', pop: true },
    // Match anything else as a character inside the comment
    { regex: /./, token: 'comment' },
  ],

  string_compound: [
    { regex: /`"/, token: 'string', push: 'string_compound' },
    { regex: /"'/, token: 'string', pop: true },
    { regex: /`/, token: 'variable-2', push: 'macro_local' },
    { regex: /\$/, token: 'variable-2', push: 'macro_global' },
    { regex: /./, token: 'string' }
  ],
  string_regular: [
    { regex: /"/, token: 'string', pop: true },
    { regex: /`/, token: 'variable-2', push: 'macro_local' },
    { regex: /\$/, token: 'variable-2', push: 'macro_global' },
    { regex: /./, token: 'string' }
  ],
  macro_local: [
    { regex: /`/, token: 'variable-2', push: 'macro_local' },
    { regex: /'/, token: 'variable-2', pop: true },
    { regex: /./, token: 'variable-2' },
  ],
  macro_global: [
    { regex: /\}/, token: 'variable-2', pop: true },
    { regex: /.(?=[^\w\{\}])/, token: 'variable-2', pop: true },
    { regex: /./, token: 'variable-2' },
  ],
  meta: {
    closeBrackets: { pairs: "()[]{}`'\"\"" },
    dontIndentStates: ['comment'],
    electricInput: /^\s*\}$/,
    blockCommentStart: '/*',
    blockCommentEnd: '*/',
    lineComment: '//',
    fold: 'brace'
  }
});

CodeMirror.defineMIME('text/x-codeql', 'codeql');
CodeMirror.defineMIME('text/codeql', 'codeql');

// When I paste this file in Jupyter, it won't work unless I include the
// following code, but when I leave this as a separate module, it won't work and
// raises an error.
CodeMirror.modeInfo.push({
  ext: ['do', 'ado'],
  mime: "text/x-codeql",
  mode: 'codeql',
  name: 'CodeQL'
});