mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
319 lines
7.1 KiB
Lua
319 lines
7.1 KiB
Lua
local format, to_lua, from_lua, events, anselme, escape, hash, mark_constant, update_hashes
|
|
|
|
local types = {}
|
|
types.lua = {
|
|
["nil"] = {
|
|
to_anselme = function(val)
|
|
return {
|
|
type = "nil",
|
|
value = nil
|
|
}
|
|
end
|
|
},
|
|
boolean = {
|
|
to_anselme = function(val)
|
|
return {
|
|
type = "number",
|
|
value = val and 1 or 0
|
|
}
|
|
end
|
|
},
|
|
number = {
|
|
to_anselme = function(val)
|
|
return {
|
|
type = "number",
|
|
value = val
|
|
}
|
|
end
|
|
},
|
|
string = {
|
|
to_anselme = function(val)
|
|
return {
|
|
type = "string",
|
|
value = val
|
|
}
|
|
end
|
|
},
|
|
table = {
|
|
to_anselme = function(val)
|
|
local is_map = false
|
|
local l = {}
|
|
local m = {}
|
|
for _, v in ipairs(val) do
|
|
local r, e = from_lua(v)
|
|
if not r then return r, e end
|
|
table.insert(l, r)
|
|
end
|
|
for k, v in pairs(val) do
|
|
if not l[k] then
|
|
is_map = true
|
|
local kv, ke = from_lua(k)
|
|
if not k then return k, ke end
|
|
local vv, ve = from_lua(v)
|
|
if not v then return v, ve end
|
|
local h, err = hash(kv)
|
|
if not h then return nil, err end
|
|
m[h] = { kv, vv }
|
|
end
|
|
end
|
|
if is_map then
|
|
for i, v in ipairs(l) do
|
|
local key = { type = "number", value = i }
|
|
local h, err = hash(key)
|
|
if not h then return nil, err end
|
|
m[h] = { key, v }
|
|
end
|
|
return {
|
|
type = "map",
|
|
value = m
|
|
}
|
|
else
|
|
return {
|
|
type = "list",
|
|
value = l
|
|
}
|
|
end
|
|
end
|
|
}
|
|
}
|
|
|
|
types.anselme = {
|
|
["nil"] = {
|
|
format = function()
|
|
return ""
|
|
end,
|
|
to_lua = function()
|
|
return nil
|
|
end,
|
|
hash = function()
|
|
return "nil()"
|
|
end,
|
|
mark_constant = function() end,
|
|
},
|
|
number = {
|
|
format = function(val)
|
|
return tostring(val)
|
|
end,
|
|
to_lua = function(val)
|
|
return val
|
|
end,
|
|
hash = function(val)
|
|
return ("n(%s)"):format(val)
|
|
end,
|
|
mark_constant = function() end,
|
|
},
|
|
string = {
|
|
format = function(val)
|
|
return tostring(val)
|
|
end,
|
|
to_lua = function(val)
|
|
return val
|
|
end,
|
|
hash = function(val)
|
|
return ("s(%s)"):format(val)
|
|
end,
|
|
mark_constant = function() end,
|
|
},
|
|
list = {
|
|
mutable = true,
|
|
format = function(val)
|
|
local l = {}
|
|
for _, v in ipairs(val) do
|
|
local s, e = format(v)
|
|
if not s then return s, e end
|
|
table.insert(l, s)
|
|
end
|
|
return ("[%s]"):format(table.concat(l, ", "))
|
|
end,
|
|
to_lua = function(val)
|
|
local l = {}
|
|
for _, v in ipairs(val) do
|
|
local s, e = to_lua(v)
|
|
if not s and e then return s, e end
|
|
table.insert(l, s)
|
|
end
|
|
return l
|
|
end,
|
|
hash = function(val)
|
|
local l = {}
|
|
for _, v in ipairs(val) do
|
|
local s, e = hash(v)
|
|
if not s then return s, e end
|
|
table.insert(l, s)
|
|
end
|
|
return ("l(%s)"):format(table.concat(l, ","))
|
|
end,
|
|
mark_constant = function(v)
|
|
v.constant = true
|
|
for _, item in ipairs(v.value) do
|
|
mark_constant(item)
|
|
end
|
|
end
|
|
},
|
|
map = {
|
|
mutable = true,
|
|
format = function(val)
|
|
local l = {}
|
|
for _, v in pairs(val) do
|
|
local ks, ke = format(v[1])
|
|
if not ks then return ks, ke end
|
|
local vs, ve = format(v[2])
|
|
if not vs then return vs, ve end
|
|
table.insert(l, ("%s=%s"):format(ks, vs))
|
|
end
|
|
table.sort(l)
|
|
return ("{%s}"):format(table.concat(l, ", "))
|
|
end,
|
|
to_lua = function(val)
|
|
local l = {}
|
|
for _, v in pairs(val) do
|
|
local kl, ke = to_lua(v[1])
|
|
if not kl and ke then return kl, ke end
|
|
local xl, xe = to_lua(v[2])
|
|
if not xl and xe then return xl, xe end
|
|
l[kl] = xl
|
|
end
|
|
return l
|
|
end,
|
|
hash = function(val)
|
|
local l = {}
|
|
for _, v in pairs(val) do
|
|
local ks, ke = hash(v[1])
|
|
if not ks then return ks, ke end
|
|
local vs, ve = hash(v[2])
|
|
if not vs then return vs, ve end
|
|
table.insert(l, ("%s=%s"):format(ks, vs))
|
|
end
|
|
table.sort(l)
|
|
return ("m(%s)"):format(table.concat(l, ","))
|
|
end,
|
|
mark_constant = function(v)
|
|
v.constant = true
|
|
for _, val in pairs(v.value) do
|
|
mark_constant(val[1])
|
|
mark_constant(val[2])
|
|
end
|
|
update_hashes(v)
|
|
end,
|
|
},
|
|
pair = {
|
|
format = function(val)
|
|
local k, ke = format(val[1])
|
|
if not k then return k, ke end
|
|
local v, ve = format(val[2])
|
|
if not v then return v, ve end
|
|
return ("%s=%s"):format(k, v)
|
|
end,
|
|
to_lua = function(val)
|
|
local k, ke = to_lua(val[1])
|
|
if not k and ke then return k, ke end
|
|
local v, ve = to_lua(val[2])
|
|
if not v and ve then return v, ve end
|
|
return { [k] = v }
|
|
end,
|
|
hash = function(val)
|
|
local k, ke = hash(val[1])
|
|
if not k then return k, ke end
|
|
local v, ve = hash(val[2])
|
|
if not v then return v, ve end
|
|
return ("p(%s=%s)"):format(k, v)
|
|
end,
|
|
mark_constant = function(v)
|
|
mark_constant(v.value[1])
|
|
mark_constant(v.value[2])
|
|
end,
|
|
},
|
|
annotated = {
|
|
format = function(val)
|
|
local k, ke = format(val[1])
|
|
if not k then return k, ke end
|
|
local v, ve = format(val[2])
|
|
if not v then return v, ve end
|
|
return ("%s::%s"):format(k, v)
|
|
end,
|
|
to_lua = function(val)
|
|
local k, ke = to_lua(val[1])
|
|
if not k and ke then return k, ke end
|
|
return k
|
|
end,
|
|
hash = function(val)
|
|
local k, ke = hash(val[1])
|
|
if not k then return k, ke end
|
|
local v, ve = hash(val[2])
|
|
if not v then return v, ve end
|
|
return ("a(%s::%s)"):format(k, v)
|
|
end,
|
|
mark_constant = function(v)
|
|
mark_constant(v.value[1])
|
|
mark_constant(v.value[2])
|
|
end,
|
|
},
|
|
["function reference"] = {
|
|
format = function(val)
|
|
if #val > 1 then
|
|
return ("&(%s)"):format(table.concat(val, ", "))
|
|
else
|
|
return ("&%s"):format(table.concat(val, ", "))
|
|
end
|
|
end,
|
|
to_lua = nil,
|
|
hash = function(val)
|
|
return ("&f(%s)"):format(table.concat(val, ", "))
|
|
end,
|
|
mark_constant = function() end,
|
|
|
|
},
|
|
["variable reference"] = {
|
|
format = function(val)
|
|
return ("&%s"):format(val)
|
|
end,
|
|
to_lua = nil,
|
|
hash = function(val)
|
|
return ("&v(%s)"):format(val)
|
|
end,
|
|
mark_constant = function() end,
|
|
},
|
|
object = {
|
|
mutable = true,
|
|
format = function(val)
|
|
local attributes = {}
|
|
for name, v in pairs(val.attributes) do
|
|
table.insert(attributes, ("%s=%s"):format(name:gsub("^"..escape(val.class)..".", ""), format(v)))
|
|
end
|
|
if #attributes > 0 then
|
|
table.sort(attributes)
|
|
return ("%%%s(%s)"):format(val.class, table.concat(attributes, ", "))
|
|
else
|
|
return ("%%%s"):format(val.class)
|
|
end
|
|
end,
|
|
to_lua = nil,
|
|
hash = function(val)
|
|
local attributes = {}
|
|
for name, v in pairs(val.attributes) do
|
|
table.insert(attributes, ("%s=%s"):format(name:gsub("^"..escape(val.class)..".", ""), format(v)))
|
|
end
|
|
table.sort(attributes)
|
|
return ("%%(%s;%s)"):format(val.class, table.concat(attributes, ","))
|
|
end,
|
|
mark_constant = function(v)
|
|
v.constant = true
|
|
end,
|
|
},
|
|
-- internal types
|
|
["event buffer"] = {
|
|
format = function(val) -- triggered from subtexts
|
|
local v, e = events:write_buffer(anselme.running.state, val)
|
|
if not v then return v, e end
|
|
return ""
|
|
end
|
|
},
|
|
}
|
|
|
|
package.loaded[...] = types
|
|
local common = require((...):gsub("stdlib%.types$", "interpreter.common"))
|
|
format, to_lua, from_lua, events, hash, mark_constant, update_hashes = common.format, common.to_lua, common.from_lua, common.events, common.hash, common.mark_constant, common.update_hashes
|
|
anselme = require((...):gsub("stdlib%.types$", "anselme"))
|
|
escape = require((...):gsub("stdlib%.types$", "parser.common")).escape
|
|
|
|
return types
|