mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-28 00:59:31 +00:00
Add maps; remove map emulation functionality from list; function and tags now internally use maps instead of lists
This commit is contained in:
parent
bac5cdde01
commit
95462391e3
20 changed files with 699 additions and 139 deletions
187
stdlib/types.lua
187
stdlib/types.lua
|
|
@ -1,4 +1,4 @@
|
|||
local format, to_lua, from_lua, events, anselme, escape
|
||||
local format, to_lua, from_lua, events, anselme, escape, hash, mark_constant, update_hashes
|
||||
|
||||
local types = {}
|
||||
types.lua = {
|
||||
|
|
@ -36,7 +36,9 @@ types.lua = {
|
|||
},
|
||||
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
|
||||
|
|
@ -44,20 +46,33 @@ types.lua = {
|
|||
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
|
||||
table.insert(l, {
|
||||
type = "pair",
|
||||
value = { kv, vv }
|
||||
})
|
||||
local h, err = hash(kv)
|
||||
if not h then return nil, err end
|
||||
m[h] = { kv, vv }
|
||||
end
|
||||
end
|
||||
return {
|
||||
type = "list",
|
||||
value = l
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +84,11 @@ types.anselme = {
|
|||
end,
|
||||
to_lua = function()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
hash = function()
|
||||
return "nil()"
|
||||
end,
|
||||
mark_constant = function() end,
|
||||
},
|
||||
number = {
|
||||
format = function(val)
|
||||
|
|
@ -77,7 +96,11 @@ types.anselme = {
|
|||
end,
|
||||
to_lua = function(val)
|
||||
return val
|
||||
end
|
||||
end,
|
||||
hash = function(val)
|
||||
return ("n(%s)"):format(val)
|
||||
end,
|
||||
mark_constant = function() end,
|
||||
},
|
||||
string = {
|
||||
format = function(val)
|
||||
|
|
@ -85,9 +108,14 @@ types.anselme = {
|
|||
end,
|
||||
to_lua = function(val)
|
||||
return val
|
||||
end
|
||||
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
|
||||
|
|
@ -99,25 +127,74 @@ types.anselme = {
|
|||
end,
|
||||
to_lua = function(val)
|
||||
local l = {}
|
||||
-- handle non-pair before pairs as LuaJIT's table.insert will always insert after the last element even if there are some nil before unlike PUC
|
||||
for _, v in ipairs(val) do
|
||||
if v.type ~= "pair" then
|
||||
local s, e = to_lua(v)
|
||||
if not s and e then return s, e end
|
||||
table.insert(l, s)
|
||||
end
|
||||
end
|
||||
for _, v in ipairs(val) do
|
||||
if v.type == "pair" then
|
||||
local k, ke = to_lua(v.value[1])
|
||||
if not k and ke then return k, ke end
|
||||
local x, xe = to_lua(v.value[2])
|
||||
if not x and xe then return x, xe end
|
||||
l[k] = x
|
||||
end
|
||||
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)
|
||||
|
|
@ -133,7 +210,18 @@ types.anselme = {
|
|||
local v, ve = to_lua(val[2])
|
||||
if not v and ve then return v, ve end
|
||||
return { [k] = v }
|
||||
end
|
||||
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)
|
||||
|
|
@ -147,7 +235,18 @@ types.anselme = {
|
|||
local k, ke = to_lua(val[1])
|
||||
if not k and ke then return k, ke end
|
||||
return k
|
||||
end
|
||||
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)
|
||||
|
|
@ -157,27 +256,49 @@ types.anselme = {
|
|||
return ("&%s"):format(table.concat(val, ", "))
|
||||
end
|
||||
end,
|
||||
to_lua = nil
|
||||
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
|
||||
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
|
||||
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"] = {
|
||||
|
|
@ -191,7 +312,7 @@ types.anselme = {
|
|||
|
||||
package.loaded[...] = types
|
||||
local common = require((...):gsub("stdlib%.types$", "interpreter.common"))
|
||||
format, to_lua, from_lua, events = common.format, common.to_lua, common.from_lua, common.events
|
||||
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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue