vis: implement :set cursorline
[vis.git] / lexers / forth.lua
blob450f528ece0ef4e6911d9eaf8297bd82a7b54e12
1 -- Copyright 2006-2015 Mitchell mitchell.att.foicica.com. See LICENSE.
2 -- Forth LPeg lexer.
4 local l = require('lexer')
5 local token, word_match = l.token, l.word_match
6 local P, R, S = lpeg.P, lpeg.R, lpeg.S
8 local M = {_NAME = 'forth'}
10 -- Whitespace.
11 local ws = token(l.WHITESPACE, l.space^1)
13 -- Comments.
14 local line_comment = S('|\\') * l.nonnewline^0
15 local block_comment = '(*' * (l.any - '*)')^0 * P('*)')^-1
16 local comment = token(l.COMMENT, line_comment + block_comment)
18 -- Strings.
19 local s_str = 's' * l.delimited_range('"', true, true)
20 local dot_str = '.' * l.delimited_range('"', true, true)
21 local f_str = 'f' * l.delimited_range('"', true, true)
22 local dq_str = l.delimited_range('"', true, true)
23 local string = token(l.STRING, s_str + dot_str + f_str + dq_str)
25 -- Numbers.
26 local number = token(l.NUMBER, P('-')^-1 * l.digit^1 * (S('./') * l.digit^1)^-1)
28 -- Keywords.
29 local keyword = token(l.KEYWORD, word_match({
30 'swap', 'drop', 'dup', 'nip', 'over', 'rot', '-rot', '2dup', '2drop', '2over',
31 '2swap', '>r', 'r>',
32 'and', 'or', 'xor', '>>', '<<', 'not', 'negate', 'mod', '/mod', '1+', '1-',
33 'base', 'hex', 'decimal', 'binary', 'octal',
34 '@', '!', 'c@', 'c!', '+!', 'cell+', 'cells', 'char+', 'chars',
35 'create', 'does>', 'variable', 'variable,', 'literal', 'last', '1,', '2,',
36 '3,', ',', 'here', 'allot', 'parse', 'find', 'compile',
37 -- Operators.
38 'if', '=if', '<if', '>if', '<>if', 'then', 'repeat', 'until', 'forth', 'macro'
39 }, '2><1-@!+3,='))
41 -- Identifiers.
42 local identifier = token(l.IDENTIFIER, (l.alnum + S('+-*=<>.?/\'%,_$'))^1)
44 -- Operators.
45 local operator = token(l.OPERATOR, S(':;<>+*-/()[]'))
47 M._rules = {
48 {'whitespace', ws},
49 {'keyword', keyword},
50 {'string', string},
51 {'identifier', identifier},
52 {'comment', comment},
53 {'number', number},
54 {'operator', operator},
57 return M