local traits = require "traits"
local terms = require "terms"
local gen = require "terms-generators"
local evaluator = require "evaluator"
local U = require "alicorn-utils"
local value = terms.value
local typed = terms.typed_term
local fitsinto = evaluator.fitsinto
local val_array = gen.declare_array(value)
local spanned_name_array = terms.spanned_name_array
local function val_tup_cons(...)
return U.notail(value.tuple_value(val_array(...)))
end
local function val_desc_elem(x)
return U.notail(value.enum_value("cons", x))
end
local val_desc_empty = value.enum_value("empty", val_tup_cons())
local function expect_error(fn, err_txt, ...)
local ok, err = pcall(fn, ...)
assert(not ok)
if err_txt then
assert(
err_txt == err or tostring(err):find(err_txt),
"err didn't contain " .. err_txt .. " was instead " .. err
)
end
end
local passed, failed, total = (require "tap")(function(test)
test("should fail for non-type which don't match content", function(expect)
expect_error(function()
fitsinto(value.number(1), value.number(2))
end, "isn't a type")
end)
test("should fail for non-type which do match content", function(expect)
local one = value.number(1)
expect_error(function()
fitsinto(one, one)
end, "isn't a type")
expect_error(function()
fitsinto(value.number(1), value.number(1))
end, "isn't a type")
end)
test("should fail for unrelated non-type values", function(expect)
expect_error(function()
fitsinto(value.number(1), value.operative_value(value.number(1)))
end, "isn't a type")
end)
test("prim_number_type into prim_number_type should fitsinto", function(expect)
assert(fitsinto(value.prim_number_type, value.prim_number_type))
end)
test("prim_number_type into prim_string_type should not fitsinto", function(expect)
assert(not fitsinto(value.prim_number_type, value.prim_string_type))
end)
test("prim_string_type into prim_number_type should not fitsinto", function(expect)
assert(not fitsinto(value.prim_string_type, value.prim_number_type))
end)
test("type into star", function(expect)
local initial = value.prim_type_type
local successor = value.star(0)
assert(fitsinto(initial, successor))
end)
test("type into star", function(expect)
local initial = value.prim_number_type
local successor = value.star(0)
assert(not fitsinto(initial, successor))
end)
test("prim_type_type into star(0..5)", function(expect)
for i = 0, 5 do
local initial = value.prim_type_type
local successor = value.star(i)
assert(fitsinto(initial, successor))
end
end)
test("star successors", function(expect)
for i = 1, 5 do
local initial = value.star(i)
local successor = value.star(i + 1)
assert(fitsinto(initial, successor))
end
end)
test("star successors with gap", function(expect)
for i = 0, 5 do
local initial = value.star(i)
local successor = value.star(i * 3)
assert(fitsinto(initial, successor))
end
end)
test("star prevs", function(expect)
for i = 0, 5 do
local initial = value.star(i + 2)
local successor = value.star(i)
assert(not fitsinto(initial, successor))
end
end)
test("tuple type decl", function(expect)
local names = gen.declare_array(gen.builtin_string)
local decl_a = value.tuple_type(
val_desc_elem(
val_tup_cons(
val_desc_elem(
val_tup_cons(
val_desc_empty,
value.closure(
"#A",
typed.tuple_elim(names(), typed.bound_variable(1, U.here()), 0, typed.star(1)),
terms.runtime_context()
)
)
),
value.closure(
"#B",
terms.typed_term.tuple_elim(
names("#FOO"),
terms.typed_term.bound_variable(1, U.here()),
1,
typed.bound_variable(2, U.here())
),
terms.runtime_context()
)
)
)
)
local decl_b = value.tuple_type(
val_desc_elem(
val_tup_cons(
val_desc_elem(
val_tup_cons(
val_desc_empty,
value.closure(
"#C",
typed.tuple_elim(names(), typed.bound_variable(1, U.here()), 0, typed.star(1)),
terms.runtime_context()
)
)
),
value.closure(
"#D",
terms.typed_term.tuple_elim(
names("#BAR"),
terms.typed_term.bound_variable(1, U.here()),
1,
typed.bound_variable(2, U.here())
),
terms.runtime_context()
)
)
)
)
assert(fitsinto(decl_a, decl_b))
end)
end)