mirror of
				https://github.com/Reuh/anselme.git
				synced 2025-10-27 16:49: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