mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-28 00:59:31 +00:00
Add text buffer syntax
This commit is contained in:
parent
ccaa40a99d
commit
e9606cdee0
13 changed files with 345 additions and 145 deletions
228
stdlib/types.lua
228
stdlib/types.lua
|
|
@ -1,4 +1,4 @@
|
|||
local format, to_lua, from_lua, events, anselme, escape, hash, mark_constant, update_hashes
|
||||
local format, to_lua, from_lua, events, anselme, escape, hash, mark_constant, update_hashes, get_variable, find_function_variant_from_fqm, post_process_text
|
||||
|
||||
local types = {}
|
||||
types.lua = {
|
||||
|
|
@ -114,6 +114,58 @@ types.anselme = {
|
|||
end,
|
||||
mark_constant = function() 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, state)
|
||||
local k, ke = to_lua(val[1], state)
|
||||
if ke then return nil, ke end
|
||||
local v, ve = to_lua(val[2], state)
|
||||
if ve then return nil, 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, state)
|
||||
local k, ke = to_lua(val[1], state)
|
||||
if ke then return nil, 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,
|
||||
},
|
||||
list = {
|
||||
mutable = true,
|
||||
format = function(val)
|
||||
|
|
@ -125,11 +177,11 @@ types.anselme = {
|
|||
end
|
||||
return ("[%s]"):format(table.concat(l, ", "))
|
||||
end,
|
||||
to_lua = function(val)
|
||||
to_lua = function(val, state)
|
||||
local l = {}
|
||||
for _, v in ipairs(val) do
|
||||
local s, e = to_lua(v)
|
||||
if not s and e then return s, e end
|
||||
local s, e = to_lua(v, state)
|
||||
if e then return nil, e end
|
||||
table.insert(l, s)
|
||||
end
|
||||
return l
|
||||
|
|
@ -164,13 +216,13 @@ types.anselme = {
|
|||
table.sort(l)
|
||||
return ("{%s}"):format(table.concat(l, ", "))
|
||||
end,
|
||||
to_lua = function(val)
|
||||
to_lua = function(val, state)
|
||||
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
|
||||
local kl, ke = to_lua(v[1], state)
|
||||
if ke then return nil, ke end
|
||||
local xl, xe = to_lua(v[2], state)
|
||||
if xe then return nil, xe end
|
||||
l[kl] = xl
|
||||
end
|
||||
return l
|
||||
|
|
@ -196,56 +248,56 @@ types.anselme = {
|
|||
update_hashes(v)
|
||||
end,
|
||||
},
|
||||
pair = {
|
||||
object = {
|
||||
mutable = true,
|
||||
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)
|
||||
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 = 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 }
|
||||
to_lua = function(val, state)
|
||||
local r = {}
|
||||
local namespacePattern = "^"..escape(val.class).."%."
|
||||
-- set object properties
|
||||
for name, v in pairs(val.attributes) do
|
||||
local var, err = to_lua(v, state)
|
||||
if err then return nil, err end
|
||||
r[name:gsub(namespacePattern, "")] = var
|
||||
end
|
||||
-- set class properties
|
||||
local class, err = find_function_variant_from_fqm(val.class, state, nil)
|
||||
if not class then return nil, err end
|
||||
assert(#class == 1 and class[1].subtype == "class")
|
||||
class = class[1]
|
||||
for _, prop in ipairs(class.properties) do
|
||||
if not val.attributes[prop] then
|
||||
local var
|
||||
var, err = get_variable(state, prop)
|
||||
if not var then return nil, err end
|
||||
var, err = to_lua(var, state)
|
||||
if err then return nil, err end
|
||||
r[prop:gsub(namespacePattern, "")] = var
|
||||
end
|
||||
end
|
||||
return r
|
||||
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)
|
||||
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)
|
||||
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])
|
||||
v.constant = true
|
||||
end,
|
||||
},
|
||||
["function reference"] = {
|
||||
|
|
@ -273,47 +325,55 @@ types.anselme = {
|
|||
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: can only be used outside of Anselme internal for text & flush events (through text buffers)
|
||||
["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
|
||||
end,
|
||||
to_lua = function(val, state)
|
||||
local r = {}
|
||||
for _, event in ipairs(val) do
|
||||
if event.type == "text" then
|
||||
table.insert(r, { "text", post_process_text(state, event.value) })
|
||||
elseif event.type == "flush" then
|
||||
table.insert(r, { "flush" })
|
||||
else
|
||||
return nil, ("event %q in event buffer can't be converted to a Lua value"):format(event.type)
|
||||
end
|
||||
end
|
||||
return r
|
||||
end,
|
||||
hash = function(val)
|
||||
local l = {}
|
||||
for _, event in ipairs(val) do
|
||||
if event.type == "text" then
|
||||
local text = {}
|
||||
for _, t in ipairs(event.value) do
|
||||
local str = ("s(%s)"):format(t.text)
|
||||
local tags, e = hash(t.tags)
|
||||
if not tags then return nil, e end
|
||||
table.insert(text, ("%s#%s"):format(str, tags))
|
||||
end
|
||||
table.insert(l, ("text(%s)"):format(table.concat(text, ",")))
|
||||
elseif event.type == "flush" then
|
||||
table.insert(l, "flush")
|
||||
else
|
||||
return nil, ("event %q in event buffer cannot be hashed"):format(event.type)
|
||||
end
|
||||
end
|
||||
return ("eb(%s)"):format(table.concat(l, ","))
|
||||
end,
|
||||
mark_constant = function() 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
|
||||
format, to_lua, from_lua, events, hash, mark_constant, update_hashes, get_variable, post_process_text = common.format, common.to_lua, common.from_lua, common.events, common.hash, common.mark_constant, common.update_hashes, common.get_variable, common.post_process_text
|
||||
anselme = require((...):gsub("stdlib%.types$", "anselme"))
|
||||
escape = require((...):gsub("stdlib%.types$", "parser.common")).escape
|
||||
local pcommon = require((...):gsub("stdlib%.types$", "parser.common"))
|
||||
escape, find_function_variant_from_fqm = pcommon.escape, pcommon.find_function_variant_from_fqm
|
||||
|
||||
return types
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue