123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://codemirror.net/LICENSE
- ;(function (mod) {
- if (typeof exports == 'object' && typeof module == 'object')
- // CommonJS
- mod(require('../../lib/codemirror'))
- else if (typeof define == 'function' && define.amd)
- // AMD
- define(['../../lib/codemirror'], mod)
- // Plain browser env
- else mod(CodeMirror)
- })(function (CodeMirror) {
- 'use strict'
- CodeMirror.defineMode('haskell', function (_config, modeConfig) {
- function switchState(source, setState, f) {
- setState(f)
- return f(source, setState)
- }
- // These should all be Unicode extended, as per the Haskell 2010 report
- var smallRE = /[a-z_]/
- var largeRE = /[A-Z]/
- var digitRE = /\d/
- var hexitRE = /[0-9A-Fa-f]/
- var octitRE = /[0-7]/
- var idRE = /[a-z_A-Z0-9'\xa1-\uffff]/
- var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/
- var specialRE = /[(),;[\]`{}]/
- var whiteCharRE = /[ \t\v\f]/ // newlines are handled in tokenizer
- function normal(source, setState) {
- if (source.eatWhile(whiteCharRE)) {
- return null
- }
- var ch = source.next()
- if (specialRE.test(ch)) {
- if (ch == '{' && source.eat('-')) {
- var t = 'comment'
- if (source.eat('#')) {
- t = 'meta'
- }
- return switchState(source, setState, ncomment(t, 1))
- }
- return null
- }
- if (ch == "'") {
- if (source.eat('\\')) {
- source.next() // should handle other escapes here
- } else {
- source.next()
- }
- if (source.eat("'")) {
- return 'string'
- }
- return 'string error'
- }
- if (ch == '"') {
- return switchState(source, setState, stringLiteral)
- }
- if (largeRE.test(ch)) {
- source.eatWhile(idRE)
- if (source.eat('.')) {
- return 'qualifier'
- }
- return 'variable-2'
- }
- if (smallRE.test(ch)) {
- source.eatWhile(idRE)
- return 'variable'
- }
- if (digitRE.test(ch)) {
- if (ch == '0') {
- if (source.eat(/[xX]/)) {
- source.eatWhile(hexitRE) // should require at least 1
- return 'integer'
- }
- if (source.eat(/[oO]/)) {
- source.eatWhile(octitRE) // should require at least 1
- return 'number'
- }
- }
- source.eatWhile(digitRE)
- var t = 'number'
- if (source.match(/^\.\d+/)) {
- t = 'number'
- }
- if (source.eat(/[eE]/)) {
- t = 'number'
- source.eat(/[-+]/)
- source.eatWhile(digitRE) // should require at least 1
- }
- return t
- }
- if (ch == '.' && source.eat('.')) return 'keyword'
- if (symbolRE.test(ch)) {
- if (ch == '-' && source.eat(/-/)) {
- source.eatWhile(/-/)
- if (!source.eat(symbolRE)) {
- source.skipToEnd()
- return 'comment'
- }
- }
- var t = 'variable'
- if (ch == ':') {
- t = 'variable-2'
- }
- source.eatWhile(symbolRE)
- return t
- }
- return 'error'
- }
- function ncomment(type, nest) {
- if (nest == 0) {
- return normal
- }
- return function (source, setState) {
- var currNest = nest
- while (!source.eol()) {
- var ch = source.next()
- if (ch == '{' && source.eat('-')) {
- ++currNest
- } else if (ch == '-' && source.eat('}')) {
- --currNest
- if (currNest == 0) {
- setState(normal)
- return type
- }
- }
- }
- setState(ncomment(type, currNest))
- return type
- }
- }
- function stringLiteral(source, setState) {
- while (!source.eol()) {
- var ch = source.next()
- if (ch == '"') {
- setState(normal)
- return 'string'
- }
- if (ch == '\\') {
- if (source.eol() || source.eat(whiteCharRE)) {
- setState(stringGap)
- return 'string'
- }
- if (source.eat('&')) {
- } else {
- source.next() // should handle other escapes here
- }
- }
- }
- setState(normal)
- return 'string error'
- }
- function stringGap(source, setState) {
- if (source.eat('\\')) {
- return switchState(source, setState, stringLiteral)
- }
- source.next()
- setState(normal)
- return 'error'
- }
- var wellKnownWords = (function () {
- var wkw = {}
- function setType(t) {
- return function () {
- for (var i = 0; i < arguments.length; i++) wkw[arguments[i]] = t
- }
- }
- setType('keyword')(
- 'case',
- 'class',
- 'data',
- 'default',
- 'deriving',
- 'do',
- 'else',
- 'foreign',
- 'if',
- 'import',
- 'in',
- 'infix',
- 'infixl',
- 'infixr',
- 'instance',
- 'let',
- 'module',
- 'newtype',
- 'of',
- 'then',
- 'type',
- 'where',
- '_'
- )
- setType('keyword')('..', ':', '::', '=', '\\', '<-', '->', '@', '~', '=>')
- setType('builtin')('!!', '$!', '$', '&&', '+', '++', '-', '.', '/', '/=', '<', '<*', '<=', '<$>', '<*>', '=<<', '==', '>', '>=', '>>', '>>=', '^', '^^', '||', '*', '*>', '**')
- setType('builtin')(
- 'Applicative',
- 'Bool',
- 'Bounded',
- 'Char',
- 'Double',
- 'EQ',
- 'Either',
- 'Enum',
- 'Eq',
- 'False',
- 'FilePath',
- 'Float',
- 'Floating',
- 'Fractional',
- 'Functor',
- 'GT',
- 'IO',
- 'IOError',
- 'Int',
- 'Integer',
- 'Integral',
- 'Just',
- 'LT',
- 'Left',
- 'Maybe',
- 'Monad',
- 'Nothing',
- 'Num',
- 'Ord',
- 'Ordering',
- 'Rational',
- 'Read',
- 'ReadS',
- 'Real',
- 'RealFloat',
- 'RealFrac',
- 'Right',
- 'Show',
- 'ShowS',
- 'String',
- 'True'
- )
- setType('builtin')(
- 'abs',
- 'acos',
- 'acosh',
- 'all',
- 'and',
- 'any',
- 'appendFile',
- 'asTypeOf',
- 'asin',
- 'asinh',
- 'atan',
- 'atan2',
- 'atanh',
- 'break',
- 'catch',
- 'ceiling',
- 'compare',
- 'concat',
- 'concatMap',
- 'const',
- 'cos',
- 'cosh',
- 'curry',
- 'cycle',
- 'decodeFloat',
- 'div',
- 'divMod',
- 'drop',
- 'dropWhile',
- 'either',
- 'elem',
- 'encodeFloat',
- 'enumFrom',
- 'enumFromThen',
- 'enumFromThenTo',
- 'enumFromTo',
- 'error',
- 'even',
- 'exp',
- 'exponent',
- 'fail',
- 'filter',
- 'flip',
- 'floatDigits',
- 'floatRadix',
- 'floatRange',
- 'floor',
- 'fmap',
- 'foldl',
- 'foldl1',
- 'foldr',
- 'foldr1',
- 'fromEnum',
- 'fromInteger',
- 'fromIntegral',
- 'fromRational',
- 'fst',
- 'gcd',
- 'getChar',
- 'getContents',
- 'getLine',
- 'head',
- 'id',
- 'init',
- 'interact',
- 'ioError',
- 'isDenormalized',
- 'isIEEE',
- 'isInfinite',
- 'isNaN',
- 'isNegativeZero',
- 'iterate',
- 'last',
- 'lcm',
- 'length',
- 'lex',
- 'lines',
- 'log',
- 'logBase',
- 'lookup',
- 'map',
- 'mapM',
- 'mapM_',
- 'max',
- 'maxBound',
- 'maximum',
- 'maybe',
- 'min',
- 'minBound',
- 'minimum',
- 'mod',
- 'negate',
- 'not',
- 'notElem',
- 'null',
- 'odd',
- 'or',
- 'otherwise',
- 'pi',
- 'pred',
- 'print',
- 'product',
- 'properFraction',
- 'pure',
- 'putChar',
- 'putStr',
- 'putStrLn',
- 'quot',
- 'quotRem',
- 'read',
- 'readFile',
- 'readIO',
- 'readList',
- 'readLn',
- 'readParen',
- 'reads',
- 'readsPrec',
- 'realToFrac',
- 'recip',
- 'rem',
- 'repeat',
- 'replicate',
- 'return',
- 'reverse',
- 'round',
- 'scaleFloat',
- 'scanl',
- 'scanl1',
- 'scanr',
- 'scanr1',
- 'seq',
- 'sequence',
- 'sequence_',
- 'show',
- 'showChar',
- 'showList',
- 'showParen',
- 'showString',
- 'shows',
- 'showsPrec',
- 'significand',
- 'signum',
- 'sin',
- 'sinh',
- 'snd',
- 'span',
- 'splitAt',
- 'sqrt',
- 'subtract',
- 'succ',
- 'sum',
- 'tail',
- 'take',
- 'takeWhile',
- 'tan',
- 'tanh',
- 'toEnum',
- 'toInteger',
- 'toRational',
- 'truncate',
- 'uncurry',
- 'undefined',
- 'unlines',
- 'until',
- 'unwords',
- 'unzip',
- 'unzip3',
- 'userError',
- 'words',
- 'writeFile',
- 'zip',
- 'zip3',
- 'zipWith',
- 'zipWith3'
- )
- var override = modeConfig.overrideKeywords
- if (override) for (var word in override) if (override.hasOwnProperty(word)) wkw[word] = override[word]
- return wkw
- })()
- return {
- startState: function () {
- return { f: normal }
- },
- copyState: function (s) {
- return { f: s.f }
- },
- token: function (stream, state) {
- var t = state.f(stream, function (s) {
- state.f = s
- })
- var w = stream.current()
- return wellKnownWords.hasOwnProperty(w) ? wellKnownWords[w] : t
- },
- blockCommentStart: '{-',
- blockCommentEnd: '-}',
- lineComment: '--',
- }
- })
- CodeMirror.defineMIME('text/x-haskell', 'haskell')
- })
|