1 -- Copyright 2006-2016 Mitchell mitchell.att.foicica.com. See LICENSE.
2 -- LPeg lexer for the Icon programming language.
3 -- http://www.cs.arizona.edu/icon
4 -- Contributed by Carl Sturtivant.
6 local l
= require('lexer')
7 local token
, word_match
= l
.token
, l
.word_match
8 local P
, R
, S
= lpeg
.P
, lpeg
.R
, lpeg
.S
10 local M
= {_NAME
= 'icon'}
13 local ws
= token(l
.WHITESPACE
, l
.space^
1)
16 local line_comment
= '#' * l
.nonnewline_esc^
0
17 local comment
= token(l
.COMMENT
, line_comment
)
20 local cset
= l
.delimited_range("'")
21 local str
= l
.delimited_range('"')
22 local string = token(l
.STRING
, cset
+ str
)
25 local radix_literal
= P('-')^
-1 * l
.dec_num
* S('rR') * l
.alnum^
1
26 local number = token(l
.NUMBER
, radix_literal
+ l
.float
+ l
.integer
)
29 local preproc_word
= word_match
{
30 'include', 'line', 'define', 'undef', 'ifdef', 'ifndef', 'else', 'endif',
33 local preproc
= token(l
.PREPROCESSOR
, S(' \t')^
0 * P('$') * preproc_word
)
36 local keyword
= token(l
.KEYWORD
, word_match
{
37 'break', 'by', 'case', 'create', 'default', 'do', 'else', 'end', 'every',
38 'fail', 'global', 'if', 'initial', 'invocable', 'link', 'local', 'next',
39 'not', 'of', 'procedure', 'record', 'repeat', 'return', 'static', 'suspend',
40 'then', 'to', 'until', 'while'
43 -- Icon Keywords: unique to Icon; use l.TYPE, as Icon is dynamically typed
44 local type = token(l
.TYPE
, P('&') * word_match
{
45 'allocated', 'ascii', 'clock', 'collections', 'cset', 'current', 'date',
46 'dateline', 'digits', 'dump', 'e', 'error', 'errornumber', 'errortext',
47 'errorvalue', 'errout', 'fail', 'features', 'file', 'host', 'input', 'lcase',
48 'letters', 'level', 'line', 'main', 'null', 'output', 'phi', 'pi', 'pos',
49 'progname', 'random', 'regions', 'source', 'storage', 'subject', 'time',
50 'trace', 'ucase', 'version'
54 local identifier
= token(l
.IDENTIFIER
, l
.word
)
57 local operator
= token(l
.OPERATOR
, S('+-/*%<>~!=^&|?~@:;,.()[]{}'))
63 {'identifier', identifier
},
68 {'operator', operator
},
72 _patterns
= {'%l+', '#'},
73 [l
.PREPROCESSOR
] = {ifdef
= 1, ifndef
= 1, endif
= -1},
74 [l
.KEYWORD
] = { procedure
= 1, ['end'] = -1},
75 [l
.COMMENT
] = {['#'] = l
.fold_line_comments('#')}