postiats.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Artyom Shalkhakov. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *
  5. * Based on the ATS/Postiats lexer by Hongwei Xi.
  6. *--------------------------------------------------------------------------------------------*/
  7. export var conf = {
  8. comments: {
  9. lineComment: '//',
  10. blockComment: ['(*', '*)']
  11. },
  12. brackets: [
  13. ['{', '}'],
  14. ['[', ']'],
  15. ['(', ')'],
  16. ['<', '>']
  17. ],
  18. autoClosingPairs: [
  19. { open: '"', close: '"', notIn: ['string', 'comment'] },
  20. { open: '{', close: '}', notIn: ['string', 'comment'] },
  21. { open: '[', close: ']', notIn: ['string', 'comment'] },
  22. { open: '(', close: ')', notIn: ['string', 'comment'] }
  23. ]
  24. };
  25. export var language = {
  26. tokenPostfix: '.pats',
  27. // TODO: staload and dynload are followed by a special kind of string literals
  28. // with {$IDENTIFER} variables, and it also may make sense to highlight
  29. // the punctuation (. and / and \) differently.
  30. // Set defaultToken to invalid to see what you do not tokenize yet
  31. defaultToken: 'invalid',
  32. // keyword reference: https://github.com/githwxi/ATS-Postiats/blob/master/src/pats_lexing_token.dats
  33. keywords: [
  34. //
  35. 'abstype',
  36. 'abst0ype',
  37. 'absprop',
  38. 'absview',
  39. 'absvtype',
  40. 'absviewtype',
  41. 'absvt0ype',
  42. 'absviewt0ype',
  43. //
  44. 'as',
  45. //
  46. 'and',
  47. //
  48. 'assume',
  49. //
  50. 'begin',
  51. //
  52. /*
  53. "case", // CASE
  54. */
  55. //
  56. 'classdec',
  57. //
  58. 'datasort',
  59. //
  60. 'datatype',
  61. 'dataprop',
  62. 'dataview',
  63. 'datavtype',
  64. 'dataviewtype',
  65. //
  66. 'do',
  67. //
  68. 'end',
  69. //
  70. 'extern',
  71. 'extype',
  72. 'extvar',
  73. //
  74. 'exception',
  75. //
  76. 'fn',
  77. 'fnx',
  78. 'fun',
  79. //
  80. 'prfn',
  81. 'prfun',
  82. //
  83. 'praxi',
  84. 'castfn',
  85. //
  86. 'if',
  87. 'then',
  88. 'else',
  89. //
  90. 'ifcase',
  91. //
  92. 'in',
  93. //
  94. 'infix',
  95. 'infixl',
  96. 'infixr',
  97. 'prefix',
  98. 'postfix',
  99. //
  100. 'implmnt',
  101. 'implement',
  102. //
  103. 'primplmnt',
  104. 'primplement',
  105. //
  106. 'import',
  107. //
  108. /*
  109. "lam", // LAM
  110. "llam", // LLAM
  111. "fix", // FIX
  112. */
  113. //
  114. 'let',
  115. //
  116. 'local',
  117. //
  118. 'macdef',
  119. 'macrodef',
  120. //
  121. 'nonfix',
  122. //
  123. 'symelim',
  124. 'symintr',
  125. 'overload',
  126. //
  127. 'of',
  128. 'op',
  129. //
  130. 'rec',
  131. //
  132. 'sif',
  133. 'scase',
  134. //
  135. 'sortdef',
  136. /*
  137. // HX: [sta] is now deprecated
  138. */
  139. 'sta',
  140. 'stacst',
  141. 'stadef',
  142. 'static',
  143. /*
  144. "stavar", // T_STAVAR
  145. */
  146. //
  147. 'staload',
  148. 'dynload',
  149. //
  150. 'try',
  151. //
  152. 'tkindef',
  153. //
  154. /*
  155. "type", // TYPE
  156. */
  157. 'typedef',
  158. 'propdef',
  159. 'viewdef',
  160. 'vtypedef',
  161. 'viewtypedef',
  162. //
  163. /*
  164. "val", // VAL
  165. */
  166. 'prval',
  167. //
  168. 'var',
  169. 'prvar',
  170. //
  171. 'when',
  172. 'where',
  173. //
  174. /*
  175. "for", // T_FOR
  176. "while", // T_WHILE
  177. */
  178. //
  179. 'with',
  180. //
  181. 'withtype',
  182. 'withprop',
  183. 'withview',
  184. 'withvtype',
  185. 'withviewtype' // WITHVIEWTYPE
  186. //
  187. ],
  188. keywords_dlr: [
  189. '$delay',
  190. '$ldelay',
  191. //
  192. '$arrpsz',
  193. '$arrptrsize',
  194. //
  195. '$d2ctype',
  196. //
  197. '$effmask',
  198. '$effmask_ntm',
  199. '$effmask_exn',
  200. '$effmask_ref',
  201. '$effmask_wrt',
  202. '$effmask_all',
  203. //
  204. '$extern',
  205. '$extkind',
  206. '$extype',
  207. '$extype_struct',
  208. //
  209. '$extval',
  210. '$extfcall',
  211. '$extmcall',
  212. //
  213. '$literal',
  214. //
  215. '$myfilename',
  216. '$mylocation',
  217. '$myfunction',
  218. //
  219. '$lst',
  220. '$lst_t',
  221. '$lst_vt',
  222. '$list',
  223. '$list_t',
  224. '$list_vt',
  225. //
  226. '$rec',
  227. '$rec_t',
  228. '$rec_vt',
  229. '$record',
  230. '$record_t',
  231. '$record_vt',
  232. //
  233. '$tup',
  234. '$tup_t',
  235. '$tup_vt',
  236. '$tuple',
  237. '$tuple_t',
  238. '$tuple_vt',
  239. //
  240. '$break',
  241. '$continue',
  242. //
  243. '$raise',
  244. //
  245. '$showtype',
  246. //
  247. '$vcopyenv_v',
  248. '$vcopyenv_vt',
  249. //
  250. '$tempenver',
  251. //
  252. '$solver_assert',
  253. '$solver_verify' // T_DLRSOLVERIFY
  254. ],
  255. keywords_srp: [
  256. //
  257. '#if',
  258. '#ifdef',
  259. '#ifndef',
  260. //
  261. '#then',
  262. //
  263. '#elif',
  264. '#elifdef',
  265. '#elifndef',
  266. //
  267. '#else',
  268. '#endif',
  269. //
  270. '#error',
  271. //
  272. '#prerr',
  273. '#print',
  274. //
  275. '#assert',
  276. //
  277. '#undef',
  278. '#define',
  279. //
  280. '#include',
  281. '#require',
  282. //
  283. '#pragma',
  284. '#codegen2',
  285. '#codegen3' // T_SRPCODEGEN3 // for level-3 codegen
  286. //
  287. // HX: end of special tokens
  288. //
  289. ],
  290. irregular_keyword_list: [
  291. 'val+',
  292. 'val-',
  293. 'val',
  294. 'case+',
  295. 'case-',
  296. 'case',
  297. 'addr@',
  298. 'addr',
  299. 'fold@',
  300. 'free@',
  301. 'fix@',
  302. 'fix',
  303. 'lam@',
  304. 'lam',
  305. 'llam@',
  306. 'llam',
  307. 'viewt@ype+',
  308. 'viewt@ype-',
  309. 'viewt@ype',
  310. 'viewtype+',
  311. 'viewtype-',
  312. 'viewtype',
  313. 'view+',
  314. 'view-',
  315. 'view@',
  316. 'view',
  317. 'type+',
  318. 'type-',
  319. 'type',
  320. 'vtype+',
  321. 'vtype-',
  322. 'vtype',
  323. 'vt@ype+',
  324. 'vt@ype-',
  325. 'vt@ype',
  326. 'viewt@ype+',
  327. 'viewt@ype-',
  328. 'viewt@ype',
  329. 'viewtype+',
  330. 'viewtype-',
  331. 'viewtype',
  332. 'prop+',
  333. 'prop-',
  334. 'prop',
  335. 'type+',
  336. 'type-',
  337. 'type',
  338. 't@ype',
  339. 't@ype+',
  340. 't@ype-',
  341. 'abst@ype',
  342. 'abstype',
  343. 'absviewt@ype',
  344. 'absvt@ype',
  345. 'for*',
  346. 'for',
  347. 'while*',
  348. 'while'
  349. ],
  350. keywords_types: [
  351. 'bool',
  352. 'double',
  353. 'byte',
  354. 'int',
  355. 'short',
  356. 'char',
  357. 'void',
  358. 'unit',
  359. 'long',
  360. 'float',
  361. 'string',
  362. 'strptr'
  363. ],
  364. // TODO: reference for this?
  365. keywords_effects: [
  366. '0',
  367. 'fun',
  368. 'clo',
  369. 'prf',
  370. 'funclo',
  371. 'cloptr',
  372. 'cloref',
  373. 'ref',
  374. 'ntm',
  375. '1' // all effects
  376. ],
  377. operators: [
  378. '@',
  379. '!',
  380. '|',
  381. '`',
  382. ':',
  383. '$',
  384. '.',
  385. '=',
  386. '#',
  387. '~',
  388. //
  389. '..',
  390. '...',
  391. //
  392. '=>',
  393. // "=<", // T_EQLT
  394. '=<>',
  395. '=/=>',
  396. '=>>',
  397. '=/=>>',
  398. //
  399. '<',
  400. '>',
  401. //
  402. '><',
  403. //
  404. '.<',
  405. '>.',
  406. //
  407. '.<>.',
  408. //
  409. '->',
  410. //"-<", // T_MINUSLT
  411. '-<>' // T_MINUSLTGT
  412. //
  413. /*
  414. ":<", // T_COLONLT
  415. */
  416. ],
  417. brackets: [
  418. { open: ',(', close: ')', token: 'delimiter.parenthesis' },
  419. { open: '`(', close: ')', token: 'delimiter.parenthesis' },
  420. { open: '%(', close: ')', token: 'delimiter.parenthesis' },
  421. { open: "'(", close: ')', token: 'delimiter.parenthesis' },
  422. { open: "'{", close: '}', token: 'delimiter.parenthesis' },
  423. { open: '@(', close: ')', token: 'delimiter.parenthesis' },
  424. { open: '@{', close: '}', token: 'delimiter.brace' },
  425. { open: '@[', close: ']', token: 'delimiter.square' },
  426. { open: '#[', close: ']', token: 'delimiter.square' },
  427. { open: '{', close: '}', token: 'delimiter.curly' },
  428. { open: '[', close: ']', token: 'delimiter.square' },
  429. { open: '(', close: ')', token: 'delimiter.parenthesis' },
  430. { open: '<', close: '>', token: 'delimiter.angle' }
  431. ],
  432. // we include these common regular expressions
  433. symbols: /[=><!~?:&|+\-*\/\^%]+/,
  434. IDENTFST: /[a-zA-Z_]/,
  435. IDENTRST: /[a-zA-Z0-9_'$]/,
  436. symbolic: /[%&+-./:=@~`^|*!$#?<>]/,
  437. digit: /[0-9]/,
  438. digitseq0: /@digit*/,
  439. xdigit: /[0-9A-Za-z]/,
  440. xdigitseq0: /@xdigit*/,
  441. INTSP: /[lLuU]/,
  442. FLOATSP: /[fFlL]/,
  443. fexponent: /[eE][+-]?[0-9]+/,
  444. fexponent_bin: /[pP][+-]?[0-9]+/,
  445. deciexp: /\.[0-9]*@fexponent?/,
  446. hexiexp: /\.[0-9a-zA-Z]*@fexponent_bin?/,
  447. irregular_keywords: /val[+-]?|case[+-]?|addr\@?|fold\@|free\@|fix\@?|lam\@?|llam\@?|prop[+-]?|type[+-]?|view[+-@]?|viewt@?ype[+-]?|t@?ype[+-]?|v(iew)?t@?ype[+-]?|abst@?ype|absv(iew)?t@?ype|for\*?|while\*?/,
  448. ESCHAR: /[ntvbrfa\\\?'"\(\[\{]/,
  449. start: 'root',
  450. // The main tokenizer for ATS/Postiats
  451. // reference: https://github.com/githwxi/ATS-Postiats/blob/master/src/pats_lexing.dats
  452. tokenizer: {
  453. root: [
  454. // lexing_blankseq0
  455. { regex: /[ \t\r\n]+/, action: { token: '' } },
  456. // NOTE: (*) is an invalid ML-like comment!
  457. { regex: /\(\*\)/, action: { token: 'invalid' } },
  458. {
  459. regex: /\(\*/,
  460. action: { token: 'comment', next: 'lexing_COMMENT_block_ml' }
  461. },
  462. {
  463. regex: /\(/,
  464. action: '@brackets' /*{ token: 'delimiter.parenthesis' }*/
  465. },
  466. {
  467. regex: /\)/,
  468. action: '@brackets' /*{ token: 'delimiter.parenthesis' }*/
  469. },
  470. {
  471. regex: /\[/,
  472. action: '@brackets' /*{ token: 'delimiter.bracket' }*/
  473. },
  474. {
  475. regex: /\]/,
  476. action: '@brackets' /*{ token: 'delimiter.bracket' }*/
  477. },
  478. {
  479. regex: /\{/,
  480. action: '@brackets' /*{ token: 'delimiter.brace' }*/
  481. },
  482. {
  483. regex: /\}/,
  484. action: '@brackets' /*{ token: 'delimiter.brace' }*/
  485. },
  486. // lexing_COMMA
  487. {
  488. regex: /,\(/,
  489. action: '@brackets' /*{ token: 'delimiter.parenthesis' }*/
  490. },
  491. { regex: /,/, action: { token: 'delimiter.comma' } },
  492. { regex: /;/, action: { token: 'delimiter.semicolon' } },
  493. // lexing_AT
  494. {
  495. regex: /@\(/,
  496. action: '@brackets' /* { token: 'delimiter.parenthesis' }*/
  497. },
  498. {
  499. regex: /@\[/,
  500. action: '@brackets' /* { token: 'delimiter.bracket' }*/
  501. },
  502. {
  503. regex: /@\{/,
  504. action: '@brackets' /*{ token: 'delimiter.brace' }*/
  505. },
  506. // lexing_COLON
  507. {
  508. regex: /:</,
  509. action: { token: 'keyword', next: '@lexing_EFFECT_commaseq0' }
  510. },
  511. /*
  512. lexing_DOT:
  513. . // SYMBOLIC => lexing_IDENT_sym
  514. . FLOATDOT => lexing_FLOAT_deciexp
  515. . DIGIT => T_DOTINT
  516. */
  517. { regex: /\.@symbolic+/, action: { token: 'identifier.sym' } },
  518. // FLOATDOT case
  519. {
  520. regex: /\.@digit*@fexponent@FLOATSP*/,
  521. action: { token: 'number.float' }
  522. },
  523. { regex: /\.@digit+/, action: { token: 'number.float' } },
  524. // lexing_DOLLAR:
  525. // '$' IDENTFST IDENTRST* => lexing_IDENT_dlr, _ => lexing_IDENT_sym
  526. {
  527. regex: /\$@IDENTFST@IDENTRST*/,
  528. action: {
  529. cases: {
  530. '@keywords_dlr': { token: 'keyword.dlr' },
  531. '@default': { token: 'namespace' } // most likely a module qualifier
  532. }
  533. }
  534. },
  535. // lexing_SHARP:
  536. // '#' IDENTFST IDENTRST* => lexing_ident_srp, _ => lexing_IDENT_sym
  537. {
  538. regex: /\#@IDENTFST@IDENTRST*/,
  539. action: {
  540. cases: {
  541. '@keywords_srp': { token: 'keyword.srp' },
  542. '@default': { token: 'identifier' }
  543. }
  544. }
  545. },
  546. // lexing_PERCENT:
  547. { regex: /%\(/, action: { token: 'delimiter.parenthesis' } },
  548. {
  549. regex: /^%{(#|\^|\$)?/,
  550. action: {
  551. token: 'keyword',
  552. next: '@lexing_EXTCODE',
  553. nextEmbedded: 'text/javascript'
  554. }
  555. },
  556. { regex: /^%}/, action: { token: 'keyword' } },
  557. // lexing_QUOTE
  558. { regex: /'\(/, action: { token: 'delimiter.parenthesis' } },
  559. { regex: /'\[/, action: { token: 'delimiter.bracket' } },
  560. { regex: /'\{/, action: { token: 'delimiter.brace' } },
  561. [/(')(\\@ESCHAR|\\[xX]@xdigit+|\\@digit+)(')/, ['string', 'string.escape', 'string']],
  562. [/'[^\\']'/, 'string'],
  563. // lexing_DQUOTE
  564. [/"/, 'string.quote', '@lexing_DQUOTE'],
  565. // lexing_BQUOTE
  566. {
  567. regex: /`\(/,
  568. action: '@brackets' /* { token: 'delimiter.parenthesis' }*/
  569. },
  570. // TODO: otherwise, try lexing_IDENT_sym
  571. { regex: /\\/, action: { token: 'punctuation' } },
  572. // lexing_IDENT_alp:
  573. // NOTE: (?!regex) is syntax for "not-followed-by" regex
  574. // to resolve ambiguity such as foreach$fwork being incorrectly lexed as [for] [each$fwork]!
  575. {
  576. regex: /@irregular_keywords(?!@IDENTRST)/,
  577. action: { token: 'keyword' }
  578. },
  579. {
  580. regex: /@IDENTFST@IDENTRST*[<!\[]?/,
  581. action: {
  582. cases: {
  583. // TODO: dynload and staload should be specially parsed
  584. // dynload whitespace+ "special_string"
  585. // this special string is really:
  586. // '/' '\\' '.' => punctuation
  587. // ({\$)([a-zA-Z_][a-zA-Z_0-9]*)(}) => punctuation,keyword,punctuation
  588. // [^"] => identifier/literal
  589. '@keywords': { token: 'keyword' },
  590. '@keywords_types': { token: 'type' },
  591. '@default': { token: 'identifier' }
  592. }
  593. }
  594. },
  595. // lexing_IDENT_sym:
  596. {
  597. regex: /\/\/\/\//,
  598. action: { token: 'comment', next: '@lexing_COMMENT_rest' }
  599. },
  600. { regex: /\/\/.*$/, action: { token: 'comment' } },
  601. {
  602. regex: /\/\*/,
  603. action: { token: 'comment', next: '@lexing_COMMENT_block_c' }
  604. },
  605. // AS-20160627: specifically for effect annotations
  606. {
  607. regex: /-<|=</,
  608. action: { token: 'keyword', next: '@lexing_EFFECT_commaseq0' }
  609. },
  610. {
  611. regex: /@symbolic+/,
  612. action: {
  613. cases: {
  614. '@operators': 'keyword',
  615. '@default': 'operator'
  616. }
  617. }
  618. },
  619. // lexing_ZERO:
  620. // FIXME: this one is quite messy/unfinished yet
  621. // TODO: lexing_INT_hex
  622. // - testing_hexiexp => lexing_FLOAT_hexiexp
  623. // - testing_fexponent_bin => lexing_FLOAT_hexiexp
  624. // - testing_intspseq0 => T_INT_hex
  625. // lexing_INT_hex:
  626. {
  627. regex: /0[xX]@xdigit+(@hexiexp|@fexponent_bin)@FLOATSP*/,
  628. action: { token: 'number.float' }
  629. },
  630. { regex: /0[xX]@xdigit+@INTSP*/, action: { token: 'number.hex' } },
  631. {
  632. regex: /0[0-7]+(?![0-9])@INTSP*/,
  633. action: { token: 'number.octal' }
  634. },
  635. //{regex: /0/, action: { token: 'number' } }, // INTZERO
  636. // lexing_INT_dec:
  637. // - testing_deciexp => lexing_FLOAT_deciexp
  638. // - testing_fexponent => lexing_FLOAT_deciexp
  639. // - otherwise => intspseq0 ([0-9]*[lLuU]?)
  640. {
  641. regex: /@digit+(@fexponent|@deciexp)@FLOATSP*/,
  642. action: { token: 'number.float' }
  643. },
  644. {
  645. regex: /@digit@digitseq0@INTSP*/,
  646. action: { token: 'number.decimal' }
  647. },
  648. // DIGIT, if followed by digitseq0, is lexing_INT_dec
  649. { regex: /@digit+@INTSP*/, action: { token: 'number' } }
  650. ],
  651. lexing_COMMENT_block_ml: [
  652. [/[^\(\*]+/, 'comment'],
  653. [/\(\*/, 'comment', '@push'],
  654. [/\(\*/, 'comment.invalid'],
  655. [/\*\)/, 'comment', '@pop'],
  656. [/\*/, 'comment']
  657. ],
  658. lexing_COMMENT_block_c: [
  659. [/[^\/*]+/, 'comment'],
  660. // [/\/\*/, 'comment', '@push' ], // nested C-style block comments not allowed
  661. // [/\/\*/, 'comment.invalid' ], // NOTE: this breaks block comments in the shape of /* //*/
  662. [/\*\//, 'comment', '@pop'],
  663. [/[\/*]/, 'comment']
  664. ],
  665. lexing_COMMENT_rest: [
  666. [/$/, 'comment', '@pop'],
  667. [/.*/, 'comment']
  668. ],
  669. // NOTE: added by AS, specifically for highlighting
  670. lexing_EFFECT_commaseq0: [
  671. {
  672. regex: /@IDENTFST@IDENTRST+|@digit+/,
  673. action: {
  674. cases: {
  675. '@keywords_effects': { token: 'type.effect' },
  676. '@default': { token: 'identifier' }
  677. }
  678. }
  679. },
  680. { regex: /,/, action: { token: 'punctuation' } },
  681. { regex: />/, action: { token: '@rematch', next: '@pop' } }
  682. ],
  683. lexing_EXTCODE: [
  684. {
  685. regex: /^%}/,
  686. action: {
  687. token: '@rematch',
  688. next: '@pop',
  689. nextEmbedded: '@pop'
  690. }
  691. },
  692. { regex: /[^%]+/, action: '' }
  693. ],
  694. lexing_DQUOTE: [
  695. { regex: /"/, action: { token: 'string.quote', next: '@pop' } },
  696. // AS-20160628: additional hi-lighting for variables in staload/dynload strings
  697. {
  698. regex: /(\{\$)(@IDENTFST@IDENTRST*)(\})/,
  699. action: [
  700. { token: 'string.escape' },
  701. { token: 'identifier' },
  702. { token: 'string.escape' }
  703. ]
  704. },
  705. { regex: /\\$/, action: { token: 'string.escape' } },
  706. {
  707. regex: /\\(@ESCHAR|[xX]@xdigit+|@digit+)/,
  708. action: { token: 'string.escape' }
  709. },
  710. { regex: /[^\\"]+/, action: { token: 'string' } }
  711. ]
  712. }
  713. };