-- SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
-- For more information, please refer to <https://unlicense.org/>
-- SPDX-License-Identifier: Unlicense
math = require "math"
require "decoy.model"
local Module = require "decoy.module"
local make_list_module = function()
local env = {}
env["car"] = function(args)
return args[1]:head()
end
env["cdr"] = function(args)
return args[1]:tail()
end
env["cons"] = function(args)
return Cons.new(args[1], args[2])
end
local list_p
list_p = function(value)
if type(value) == "function" then
return False
elseif value == Nil then
return True
elseif Cons.is_class_of(value) then
return list_p(value:tail())
else
return False
end
end
env["list?"] = function(args)
return list_p(args[1])
end
env["pair?"] = function(args)
if Cons.is_class_of(args[1]) then
return True
else
return False
end
end
env["null?"] = function(args)
if args[1] == Nil then
return True
else
return False
end
end
env["list"] = function(args)
return Cons.table_to_list(args)
end
env["length"] = function(args)
local c = args[1]
local n = 0
while c ~= Nil do
if Cons.is_class_of(c) then
n = n + 1
c = c:tail()
else
c = Nil
end
end
return Number.new(n)
end
env["map"] = function(args)
local fn = args[1]
local c = 0
local t = {}
while c ~= Nil do
if Cons.is_class_of(c) then
table.insert(t, c) -- FIXME fn(c) !!
c = c.tail()
else
c = Nil
end
end
return Cons.table_to_list(t)
end
-- Note: not in R5RS
env["fold"] = function(args)
local fn = args[1]
local acc = args[2]
local c = args[3]
while c ~= Nil do
if Cons.is_class_of(c) then
acc = fn({ c:head(), acc })
c = c:tail()
else
c = Nil
end
end
return acc
end
env["list-ref"] = function(args)
local c = args[1]
local n = args[2]
while n > 0 do
if Cons.is_class_of(c) then
n = n - 1
c = c:tail()
else
n = 0
end
end
return c:head()
end
local m = Module.new()
-- FIXME this is horrible
m.symbols = env
return m
end
return make_list_module