-
Notifications
You must be signed in to change notification settings - Fork 0
/
runtime.lua
51 lines (44 loc) · 1.61 KB
/
runtime.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
local input = io.read("*all") -- should take place at module call time
local loc = 1 -- beginning of the input
local function forward(n) loc = loc + n end
local function getchar(String, i) return string.sub(String, i, i) end
local function skip_whitespace()
while (string.find(" \t\n\r", getchar(input, loc), 1, true)
and loc < string.len(input)) do
forward(1)
end
end
-- Tries to extract the next token. If found, returns it and advances past it
local function read(finder)
skip_whitespace()
local token = finder() -- extract the token with the finder
if token
then
forward(string.len(token)) -- token fond => advance past it
_switch = true
else
_switch = false
end
return token -- returns the token or nil
end
local function match(pattern)
return function() return string.match(input, pattern, loc) end
end
function test_prefix(String)
return function()
local prefix = string.sub(input, loc, loc + string.len(String) - 1)
return prefix == String and prefix or nil
end
end
local function testSTR (String) return read(test_prefix(String)) end
local function parseID () return read(match("^%a[%a%d_]*")) end
local function parseNUM() return read(match("^%d+") ) end
local function parseSTR() return read(match("^'[^']*'")) or read(match('^"[^"]*"')) end
local function parseCMT() return read(match("^[^\n%]]*")) end
local M = {} -- public interface
M.testSTR = testSTR
M.parseID = parseID
M.parseNUM = parseNUM
M.parseSTR = parseSTR
M.parseCMT = parseCMT
return M