logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

sml.lua (3274B)


  1. -- Copyright 2017-2024 Murray Calavera. See LICENSE.
  2. -- Standard ML LPeg lexer.
  3. local lexer = require('lexer')
  4. local token, word_match = lexer.token, lexer.word_match
  5. local P, S = lpeg.P, lpeg.S
  6. local lex = lexer.new('sml')
  7. -- Whitespace.
  8. local ws = token(lexer.WHITESPACE, lexer.space^1)
  9. lex:add_rule('whitespace', ws)
  10. -- Structures.
  11. local id = (lexer.alnum + "'" + '_')^0
  12. local aid = lexer.alpha * id
  13. local longid = (aid * '.')^0 * aid
  14. local struct_dec = token(lexer.KEYWORD, 'structure') * ws * token(lexer.CLASS, aid) * ws *
  15. token(lexer.OPERATOR, '=') * ws
  16. lex:add_rule('struct_new', struct_dec * token(lexer.KEYWORD, 'struct'))
  17. lex:add_rule('struct_alias', struct_dec * token(lexer.CLASS, longid))
  18. lex:add_rule('structure', token(lexer.CLASS, aid * '.'))
  19. -- Open.
  20. lex:add_rule('open', token(lexer.KEYWORD, word_match('open structure functor')) * ws *
  21. token(lexer.CLASS, longid))
  22. -- Keywords.
  23. lex:add_rule('keyword', token(lexer.KEYWORD, word_match{
  24. 'abstype', 'and', 'andalso', 'as', 'case', 'do', 'datatype', 'else', 'end', 'exception', 'fn',
  25. 'fun', 'handle', 'if', 'in', 'infix', 'infixr', 'let', 'local', 'nonfix', 'of', 'op', 'orelse',
  26. 'raise', 'rec', 'then', 'type', 'val', 'with', 'withtype', 'while', --
  27. 'eqtype', 'functor', 'include', 'sharing', 'sig', 'signature', 'struct', 'structure'
  28. }))
  29. -- Types.
  30. lex:add_rule('type', token(lexer.TYPE, word_match{
  31. 'int', 'real', 'word', 'bool', 'char', 'string', 'unit', 'array', 'exn', 'list', 'option',
  32. 'order', 'ref', 'substring', 'vector'
  33. }))
  34. -- Functions.
  35. -- `real`, `vector` and `substring` are a problem.
  36. lex:add_rule('function', token(lexer.FUNCTION, word_match{
  37. 'app', 'before', 'ceil', 'chr', 'concat', 'exnMessage', 'exnName', 'explode', 'floor', 'foldl',
  38. 'foldr', 'getOpt', 'hd', 'ignore', 'implode', 'isSome', 'length', 'map', 'not', 'null', 'ord',
  39. 'print', 'real', 'rev', 'round', 'size', 'str', 'substring', 'tl', 'trunc', 'valOf', 'vector',
  40. 'o', 'abs', 'mod', 'div'
  41. }))
  42. -- Constants.
  43. lex:add_rule('constant', token(lexer.CONSTANT, word_match('true false nil') + lexer.upper * id))
  44. -- Indentifiers (non-symbolic).
  45. lex:add_rule('identifier', token(lexer.IDENTIFIER, lexer.lower * id))
  46. -- Strings.
  47. lex:add_rule('string', token(lexer.STRING, P('#')^-1 * lexer.range('"', true)))
  48. -- Comments.
  49. local line_comment = lexer.to_eol('(*)')
  50. local block_comment = lexer.range('(*', '*)', false, false, true)
  51. lex:add_rule('comment', token(lexer.COMMENT, line_comment + block_comment))
  52. -- Numbers.
  53. local function num(digit) return digit * (digit^0 * '_')^0 * digit^1 + digit end
  54. local int = num(lexer.digit)
  55. local frac = '.' * int
  56. local minus = lpeg.P('~')^-1
  57. local exp = lpeg.S('eE') * minus * int
  58. local real = int * frac^-1 * exp + int * frac * exp^-1
  59. local hex = num(lexer.xdigit)
  60. local bin = num(lpeg.S('01'))
  61. -- LuaFormatter off
  62. lex:add_rule('number', token(lexer.NUMBER,
  63. '0w' * int +
  64. (P('0wx') + '0xw') * hex +
  65. (P('0wb') + '0bw') * bin +
  66. minus * '0x' * hex +
  67. minus * '0b' * bin +
  68. minus * real +
  69. minus * int))
  70. -- LuaFormatter on
  71. -- Type variables.
  72. lex:add_rule('typevar', token(lexer.VARIABLE, "'" * id))
  73. -- Operators.
  74. lex:add_rule('operator', token(lexer.OPERATOR, S('!*/+-^:@=<>()[]{},;._|#%&$?~`\\')))
  75. lexer.property['scintillua.comment'] = '(*)'
  76. return lex