1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
-- Copyright 2017 David B. Lamkins <david@lamkins.net>. See LICENSE.
-- Spin LPeg lexer, see https://www.parallax.com/microcontrollers/propeller
local l = require('lexer')
local token, word_match = l.token, l.word_match
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local M = {_NAME = 'spin'}
-- Whitespace.
local ws = token(l.WHITESPACE, l.space^1)
-- Comments.
local line_comment = (P("''") + P("'")) * l.nonnewline^0
local block_comment = P('{') * (l.any - P('}'))^0 * P('}')^-1
local block_doc_comment = P('{{') * (l.any - P('}}'))^0 * P('}}')^-1
local comment = token(l.COMMENT, line_comment + block_doc_comment + block_comment)
-- Strings.
local string = token(l.STRING, l.delimited_range('"', true))
-- Numbers.
local bin = '%' * S('01_')^1
local ter = P('%%') * (R('03') + P('_'))^1
local hex = P('$') * (R('09') + R('af') + R('AF') + P('_'))^1
local dec = (R('09') + P('_'))^1
local int = bin + ter + dec + hex
local rad = P('.') - P('..')
local exp = (S('Ee') * S('+-')^-1 * int)^-1
local flt = dec * (rad * dec)^-1 * exp + dec^-1 * rad * dec * exp
local number = token(l.NUMBER, flt + int)
-- Keywords.
local keyword = token(l.KEYWORD, word_match{
'_clkfreq', '_clkmode', '_free', '_stack', '_xinfreq', 'abort', 'abs',
'absneg', 'add', 'addabs', 'adds', 'addsx', 'addx', 'and', 'andn', 'byte',
'bytefill', 'bytemove', 'call', 'case', 'chipver', 'clkfreq', 'clkmode',
'clkset', 'cmp', 'cmps', 'cmpsub', 'cmpsx', 'cmpx', 'cnt', 'cogid',
'coginit', 'cognew', 'cogstop', 'con', 'constant', 'ctra', 'ctrb', 'dat',
'dira', 'dirb', 'djnz', 'else', 'elseif', 'elseifnot', 'enc', 'false',
'file', 'fit', 'float', 'from', 'frqa', 'frqb', 'hubop', 'if', 'ifnot',
'if_a', 'if_ae', 'if_always', 'if_b', 'if_be', 'if_c', 'if_c_and_nz',
'if_c_and_z', 'if_c_eq_z', 'if_c_ne_z', 'if_c_or_nz', 'if_c_or_z', 'if_e',
'if_nc', 'if_nc_and_nz', 'if_nc_and_z', 'if_nc_or_nz', 'if_nc_or_z',
'if_ne', 'if_never', 'if_nz', 'if_nz_and_c', 'if_nz_and_nc', 'if_nz_or_c',
'if_nz_or_nc', 'if_z', 'if_z_and_c', 'if_z_and_nc', 'if_z_eq_c',
'if_z_ne_c', 'if_z_or_c', 'if_z_or_nc', 'ina', 'inb', 'jmp', 'jmpret',
'lockclr', 'locknew', 'lockret', 'lockset', 'long', 'longfill', 'longmove',
'lookdown', 'lookdownz', 'lookup', 'lookupz', 'max', 'maxs', 'min', 'mins',
'mov', 'movd', 'movi', 'movs', 'mul', 'muls', 'muxc', 'muxnc', 'muxnz',
'muxz', 'neg', 'negc', 'negnc', 'negnz', 'negx', 'negz', 'next', 'nop',
'not', 'nr', 'obj', 'ones', 'or', 'org', 'other', 'outa', 'outb', 'par',
'phsa', 'phsb', 'pi', 'pll1x', 'pll2x', 'pll4x', 'pll8x', 'pll16x', 'posx',
'pri', 'pub', 'quit', 'rcfast', 'rcl', 'rcr', 'rcslow', 'rdbyte', 'rdlong',
'rdword', 'reboot', 'repeat', 'res', 'result', 'ret', 'return', 'rev',
'rol', 'ror', 'round', 'sar', 'shl', 'shr', 'spr', 'step', 'strcomp',
'string', 'strsize', 'sub', 'subabs', 'subs', 'subsx', 'subx', 'sumc',
'sumnc', 'sumnz', 'sumz', 'test', 'testn', 'tjnz', 'tjz', 'to', 'true',
'trunc', 'until', 'var', 'vcfg', 'vscl', 'waitcnt', 'waitpeq', 'waitpne',
'waitvid', 'wc', 'while', 'word', 'wordfill', 'wordmove', 'wr', 'wrbyte',
'wrlong', 'wz', 'xinput', 'xor', 'xtal1', 'xtal2', 'xtal3'
})
-- Identifiers.
local identifier = token(l.IDENTIFIER, l.word)
-- Operators.
local punct = S('+-/*<>~!&=^|?:.()[]@#\\')
local dec = P('--')
local inc = P('++')
local sqrt = P('^^')
local abs = P('||')
local sexw = P('~~')
local decode = P('|<')
local encode = P('>|')
local objref = P('@@')
local assign = P(':=')
local plus_a = P('+=')
local minus_a = P('-=')
local mull_a = P('*=')
local div_a = P('/=')
local mulu = P('**')
local mulu_a = P('**=')
local mod = P('//')
local mod_a = P('//=')
local limmin = P('#>')
local limmin_a = P('#>=')
local limmax = P('<#')
local limmax_a = P('<#=')
local sar = P('~>')
local sar_a = P('~>=')
local shl = P('<<')
local shl_a = P('<<=')
local shr = P('>>')
local shr_a = P('>>=')
local rol = P('<-')
local rol_a = P('<-=')
local ror = P('->')
local ror_a = P('->=')
local rev = P('><')
local rev_a = P('><=')
local band_a = P('&=')
local bor_a = P('|=')
local sand_a = P('and=')
local sor_a = P('or=')
local equal = P('==')
local equal_a = P('===')
local nequal = P('<>')
local nequal_a = P('<>=')
local less_a = P('<=')
local greater_a = P('>=')
local leq = P('=<')
local leq_a = P('=<=')
local geq = P('=>')
local geq_a = P('=>=')
local dots = P('..')
local operator = token(l.OPERATOR, dec + inc + sqrt + abs + sexw +
decode + encode + objref + assign + plus_a + minus_a + mull_a + div_a +
mulu + mulu_a + mod + mod_a + limmin + limmin_a + limmax + limmax_a +
sar + sar_a + shl + shl_a + shr + shr_a + rol + rol_a + ror + ror_a +
rev + rev_a + band_a + bor_a + sand_a + sor_a + equal + equal_a +
nequal + nequal_a + less_a + greater_a + leq + leq_a + geq + geq_a +
dots + punct)
M._rules = {
{'whitespace', ws},
{'comment', comment},
{'keyword', keyword},
{'number', number},
{'operator', operator},
{'identifier', identifier},
{'string', string},
}
return M
|