-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlexer.lua
54 lines (47 loc) · 1 KB
/
lexer.lua
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
local Token = require("typecheck.Token")
local Tokens = require("typecheck.Tokens")
local lexer = {}
local token_patterns = {
{"id", "[%w_]+"},
{"leftparan", "%("},
{"rightparan", "%)"},
{"vararg", "%.%.%."},
{"array", "%[%]"},
{"colon", ":"},
{"point", "%."},
{"comma", "%,"},
{"question", "%?"},
{"pipe", "|"},
{"minus", "%-"},
{"at", "@"},
{"equal", "="},
{"asterisk", "*"},
{"plus", "+"},
{"{", "{"},
{"}", "}"},
}
---@param s string
---@return typecheck.Tokens? tokens
---@return string? error_message
function lexer.lex(s)
local pos = 1
local tokens = Tokens()
s = s:match("^%s*(.-)%s*$")
while pos <= #s do
local a, b, token
for _, p in ipairs(token_patterns) do
a, b, token = s:find("^(" .. p[2] .. ")%s*", pos)
if token then
table.insert(tokens, Token(p[1], token, pos))
break
end
end
if not token then
return nil, "unknown symbol '" .. s:sub(pos, pos) .. "' at position " .. pos
end
pos = b + 1
end
tokens.token = tokens[1]
return tokens
end
return lexer