1 -- Copyright 2006-2016 Mitchell mitchell.att.foicica.com. See LICENSE.
3 -- Original written by Peter Odding, 2007/04/04.
5 local l
= require('lexer')
6 local token
, word_match
= l
.token
, l
.word_match
7 local P
, R
, S
= lpeg
.P
, lpeg
.R
, lpeg
.S
9 local M
= {_NAME
= 'lua'}
12 local ws
= token(l
.WHITESPACE
, l
.space^
1)
14 local longstring
= lpeg
.Cmt('[' * lpeg
.C(P('=')^
0) * '[',
15 function(input
, index
, eq
)
16 local _
, e
= input
:find(']'..eq
..']', index
, true)
17 return (e
or #input
) + 1
21 local line_comment
= '--' * l
.nonnewline^
0
22 local block_comment
= '--' * longstring
23 local comment
= token(l
.COMMENT
, block_comment
+ line_comment
)
26 local sq_str
= l
.delimited_range("'")
27 local dq_str
= l
.delimited_range('"')
28 local string = token(l
.STRING
, sq_str
+ dq_str
) +
29 token('longstring', longstring
)
32 local lua_integer
= P('-')^
-1 * (l
.hex_num
+ l
.dec_num
)
33 local number = token(l
.NUMBER
, l
.float
+ lua_integer
)
36 local keyword
= token(l
.KEYWORD
, word_match
{
37 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function',
38 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then',
39 'true', 'until', 'while'
43 local func
= token(l
.FUNCTION
, word_match
{
44 'assert', 'collectgarbage', 'dofile', 'error', 'getmetatable', 'ipairs',
45 'load', 'loadfile', 'next', 'pairs', 'pcall', 'print', 'rawequal', 'rawget',
46 'rawset', 'require', 'select', 'setmetatable', 'tonumber', 'tostring', 'type',
52 -- Deprecated functions.
53 local deprecated_func
= token('deprecated_function', word_match
{
55 'getfenv', 'loadstring', 'module', 'setfenv', 'unpack'
59 local constant
= token(l
.CONSTANT
, word_match
{
66 local library
= token('library', word_match({
68 'coroutine', 'coroutine.create', 'coroutine.resume', 'coroutine.running',
69 'coroutine.status', 'coroutine.wrap', 'coroutine.yield',
70 -- Coroutine added in 5.3.
71 'coroutine.isyieldable',
73 'package', 'package.cpath', 'package.loaded', 'package.loadlib',
74 'package.path', 'package.preload',
75 -- Module added in 5.2.
76 'package.config', 'package.searchers', 'package.searchpath',
77 -- UTF-8 added in 5.3.
78 'utf8', 'utf8.char', 'utf8.charpattern', 'utf8.codepoint', 'utf8.codes',
79 'utf8.len', 'utf8.offset',
81 'string', 'string.byte', 'string.char', 'string.dump', 'string.find',
82 'string.format', 'string.gmatch', 'string.gsub', 'string.len', 'string.lower',
83 'string.match', 'string.rep', 'string.reverse', 'string.sub', 'string.upper',
84 -- String added in 5.3.
85 'string.pack', 'string.packsize', 'string.unpack',
87 'table', 'table.concat', 'table.insert', 'table.remove', 'table.sort',
88 -- Table added in 5.2.
89 'table.pack', 'table.unpack',
90 -- Table added in 5.3.
93 'math', 'math.abs', 'math.acos', 'math.asin', 'math.atan', 'math.ceil',
94 'math.cos', 'math.deg', 'math.exp', 'math.floor', 'math.fmod', 'math.huge',
95 'math.log', 'math.max', 'math.min', 'math.modf', 'math.pi', 'math.rad',
96 'math.random', 'math.randomseed', 'math.sin', 'math.sqrt', 'math.tan',
98 'math.maxinteger', 'math.mininteger', 'math.tointeger', 'math.type',
101 'io', 'io.close', 'io.flush', 'io.input', 'io.lines', 'io.open', 'io.output',
102 'io.popen', 'io.read', 'io.stderr', 'io.stdin', 'io.stdout', 'io.tmpfile',
103 'io.type', 'io.write',
105 'os', 'os.clock', 'os.date', 'os.difftime', 'os.execute', 'os.exit',
106 'os.getenv', 'os.remove', 'os.rename', 'os.setlocale', 'os.time',
109 'debug', 'debug.debug', 'debug.gethook', 'debug.getinfo', 'debug.getlocal',
110 'debug.getmetatable', 'debug.getregistry', 'debug.getupvalue',
111 'debug.sethook', 'debug.setlocal', 'debug.setmetatable', 'debug.setupvalue',
113 -- Debug added in 5.2.
114 'debug.getuservalue', 'debug.setuservalue', 'debug.upvalueid',
118 -- Deprecated libraries.
119 local deprecated_library
= token('deprecated_library', word_match({
120 -- Module deprecated in 5.2.
121 'package.loaders', 'package.seeall',
122 -- Table deprecated in 5.2.
124 -- Math deprecated in 5.2.
126 -- Math deprecated in 5.3.
127 'math.atan2', 'math.cosh', 'math.frexp', 'math.ldexp', 'math.pow',
128 'math.sinh', 'math.tanh',
129 -- Bit32 deprecated in 5.3.
130 'bit32', 'bit32.arshift', 'bit32.band', 'bit32.bnot', 'bit32.bor',
131 'bit32.btest', 'bit32.extract', 'bit32.lrotate', 'bit32.lshift',
132 'bit32.replace', 'bit32.rrotate', 'bit32.rshift', 'bit32.xor',
133 -- Debug deprecated in 5.2.
134 'debug.getfenv', 'debug.setfenv'
138 local identifier
= token(l
.IDENTIFIER
, l
.word
)
141 local label
= token(l
.LABEL
, '::' * l
.word
* '::')
144 local operator
= token(l
.OPERATOR
, S('+-*/%^#=<>&|~;:,.{}[]()'))
148 {'keyword', keyword
},
149 {'function', func
+ deprecated_func
},
150 {'constant', constant
},
151 {'library', library
+ deprecated_library
},
152 {'identifier', identifier
},
154 {'comment', comment
},
157 {'operator', operator
},
161 longstring
= l
.STYLE_STRING
,
162 deprecated_function
= l
.STYLE_FUNCTION
..',italics',
163 library
= l
.STYLE_TYPE
,
164 deprecated_library
= l
.STYLE_TYPE
..',italics'
167 local function fold_longcomment(text
, pos
, line
, s
, match
)
169 if line
:find('^%[=*%[', s
) then return 1 end
170 elseif match
== ']' then
171 if line
:find('^%]=*%]', s
) then return -1 end
177 _patterns
= {'%l+', '[%({%)}]', '[%[%]]', '%-%-'},
179 ['if'] = 1, ['do'] = 1, ['function'] = 1, ['end'] = -1, ['repeat'] = 1,
183 ['['] = fold_longcomment
, [']'] = fold_longcomment
,
184 ['--'] = l
.fold_line_comments('--')
186 longstring
= {['['] = 1, [']'] = -1},
187 [l
.OPERATOR
] = {['('] = 1, ['{'] = 1, [')'] = -1, ['}'] = -1}