1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-28 09:09:31 +00:00
anselme/ast/List.lua
2023-12-28 17:03:54 +01:00

81 lines
2.3 KiB
Lua

local ast = require("ast")
local Branched, Tuple
local operator_priority = require("common").operator_priority
local List
List = ast.abstract.Runtime {
type = "list",
format_priority = operator_priority["*_"],
-- note: yeah technically this isn't mutable, only .branched is
-- note: this a Branched of Tuple, and we *will* forcefully mutate the tuples, so make sure to not disseminate any reference to them outside the List
-- unless you want rumors about mutable tuples to spread
branched = nil,
init = function(self, state, from_tuple)
from_tuple = from_tuple or Tuple:new()
self.branched = Branched:new(state, from_tuple:copy())
end,
_format = function(self, ...)
return "*"..self.branched:format_right(...)
end,
traverse = function(self, fn, ...)
fn(self.branched, ...)
end,
-- List is always created from an evaluated Tuple, so no need to _eval here
-- create copy of the list in branch if not here
-- do this before any mutation
-- return the tuple for the current branch
_prepare_branch = function(self, state)
if not self.branched:in_branch(state) then
self.branched:set(state, self.branched:get(state):copy())
end
return self.branched:get(state)
end,
len = function(self, state)
return #self.branched:get(state).list
end,
iter = function(self, state)
return ipairs(self.branched:get(state).list)
end,
get = function(self, state, index)
local list = self.branched:get(state)
if index < 0 then index = #list.list + 1 + index end
if index > #list.list or index == 0 then error("list index out of bounds", 0) end
return list.list[index]
end,
set = function(self, state, index, val)
local list = self:_prepare_branch(state)
if index < 0 then index = #list.list + 1 + index end
if index > #list.list+1 or index == 0 then error("list index out of bounds", 0) end
list.list[index] = val
end,
insert = function(self, state, val)
local l = self:_prepare_branch(state)
table.insert(l.list, val)
end,
remove = function(self, state)
local l = self:_prepare_branch(state)
table.remove(l.list)
end,
to_tuple = function(self, state)
return self.branched:get(state):copy()
end,
to_lua = function(self, state)
return self.branched:get(state):to_lua(state)
end,
}
package.loaded[...] = List
Branched, Tuple = ast.Branched, ast.Tuple
return List