summaryrefslogtreecommitdiff
path: root/src/matcher/definition.lua
blob: 41ad9f8a93ac2770c4aa48f03ea8ccf0186f14da (plain)
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
local parser = require 'parser'

local pos
local defs = {}
local scopes
local result

local function getResult(name, p)
    result = {name, p}
end

local function scopeInit()
    scopes = {{}}
end

local function scopeSet(name, p)
    local scope = scopes[#scopes]
    scope[name] = p
end

local function scopeGet(name)
    for i = #scopes, 1, -1 do
        local scope = scopes[i]
        local p = scope[name]
        if p then
            return p
        end
    end
    return nil
end

local function scopePush()
    scopes[#scopes+1] = {}
end

local function scopePop()
    scopes[#scopes] = nil
end

local function checkDifinition(name, p)
    if pos < p or pos > p + #name then
        return
    end
    getResult(name, scopeGet(name))
end

function defs.Name(p, str)
    checkDifinition(str, p)
    return {str, p}
end

function defs.LocalVar(name)
    scopeSet(name[1], name[2])
end

function defs.LocalSet(name)
    scopeSet(name[1], name[2])
end

function defs.Function(func)
    local names = func.name
    if names and #names == 1 then
        local name = names[1]
        scopeSet(name[1], name[2])
    end
    return func
end

function defs.DoStart()
    scopePush()
end

function defs.Do()
    scopePop()
end

function defs.IfStart()
    scopePush()
end

function defs.If()
    scopePop()
end

function defs.ElseIfStart()
    scopePush()
end

function defs.ElseIf()
    scopePop()
end

function defs.ElseStart()
    scopePush()
end

function defs.Else()
    scopePop()
end

return function (buf, pos_)
    pos = pos_
    result = nil
    scopeInit()

    parser.grammar(buf, 'Lua', defs)

    if not result then
        return false, 'No word'
    end
    local name, start = result[1], result[2]
    if not start then
        return false, 'No match'
    end
    return true, start, start + #name - 1
end