/
decl.lua
98 lines (81 loc) · 2.35 KB
/
decl.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
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
-- Copyright 2010 Andreas Fredriksson
--
-- This file is part of Tundra.
--
-- Tundra is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- Tundra is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with Tundra. If not, see <http://www.gnu.org/licenses/>.
module(..., package.seeall)
local nodegen = require "tundra.nodegen"
local decl_meta = {}
decl_meta.__index = decl_meta
function make_decl_env()
local obj = {
Platforms = {},
Projects = {},
ProjectTypes = {},
SourceGen = {},
Results = {},
DefaultNames = {},
}
local outer_env = _G
local function indexfunc(tab, var)
-- Project types evaluate to functions that just store results
local p
p = obj.ProjectTypes[var]
if p then
if type(p) == "function" then
return p
else
return function (data)
obj.Results[#obj.Results + 1] = { Type = var, Decl = data }
end
end
end
-- Platform names evaluate to themselves
if obj.Platforms[var] then return var end
local fn = obj.SourceGen[var]
if fn then return fn end
if var == "Default" then
return function(default_name)
obj.DefaultNames[#obj.DefaultNames + 1] = default_name
end
end
return outer_env[var]
end
obj.FunctionMeta = { __index = indexfunc }
obj.FunctionEnv = setmetatable({}, obj.FunctionMeta)
return setmetatable(obj, decl_meta)
end
function decl_meta:add_platforms(list)
for i = 1, #list do
local name = list[i]
assert(name and type(name) == "string")
self.Platforms[name] = true
end
end
function decl_meta:add_project_type(name, fn)
assert(name and fn)
self.ProjectTypes[name] = setfenv(fn, self.FunctionEnv)
end
function decl_meta:add_source_generator(name, fn)
self.SourceGen[name] = fn
end
function decl_meta:parse(file)
local chunk = assert(loadfile(file))
for name, _ in pairs(nodegen._generator.evaluators) do
self.ProjectTypes[name] = true
end
setfenv(chunk, self.FunctionEnv)
chunk()
return self.Results, self.DefaultNames
end