2015-01-09 08:25:40 +03:00
|
|
|
local table = require('table')
|
|
|
|
local types = require('types')
|
2024-08-22 06:53:59 +03:00
|
|
|
local printer = require('printer')
|
2015-01-09 08:25:40 +03:00
|
|
|
|
|
|
|
local Env = {}
|
|
|
|
|
|
|
|
function Env:new(outer, binds, exprs)
|
2024-08-22 06:53:59 +03:00
|
|
|
-- binds is a MAL sequence of MAL symbols
|
|
|
|
-- exprs is an LUA table of MAL forms
|
2015-01-09 08:25:40 +03:00
|
|
|
local data = {}
|
|
|
|
local newObj = {outer = outer, data = data}
|
|
|
|
self.__index = self
|
|
|
|
if binds then
|
|
|
|
for i, b in ipairs(binds) do
|
|
|
|
if binds[i].val == '&' then
|
2024-08-22 07:47:11 +03:00
|
|
|
data[binds[i+1].val] = types.List.slice(exprs, i)
|
2015-01-09 08:25:40 +03:00
|
|
|
break
|
|
|
|
end
|
|
|
|
data[binds[i].val] = exprs[i]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return setmetatable(newObj, self)
|
|
|
|
end
|
2024-08-22 06:53:59 +03:00
|
|
|
|
|
|
|
function Env:get(sym)
|
|
|
|
-- sym is an LUA string
|
|
|
|
-- returns nil if the key is not found
|
|
|
|
local env = self
|
|
|
|
local result
|
|
|
|
while true do
|
|
|
|
result = env.data[sym]
|
|
|
|
if result ~= nil then return result end
|
|
|
|
env = env.outer
|
|
|
|
if env == nil then return nil end
|
2015-01-09 08:25:40 +03:00
|
|
|
end
|
|
|
|
end
|
2024-08-22 06:53:59 +03:00
|
|
|
|
2015-01-09 08:25:40 +03:00
|
|
|
function Env:set(sym,val)
|
2024-08-22 06:53:59 +03:00
|
|
|
-- sym is an LUA string
|
|
|
|
self.data[sym] = val
|
2015-01-09 08:25:40 +03:00
|
|
|
return val
|
|
|
|
end
|
2024-08-22 06:53:59 +03:00
|
|
|
|
|
|
|
function Env:debug()
|
|
|
|
local env = self
|
|
|
|
while env.outer ~=nil do
|
|
|
|
line = ' ENV:'
|
|
|
|
for k, v in pairs(env.data) do
|
|
|
|
line = line .. ' ' .. k .. '=' .. printer._pr_str(v)
|
|
|
|
end
|
|
|
|
print(line)
|
|
|
|
env = env.outer
|
2015-01-09 08:25:40 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return Env
|