mirror of
				https://github.com/Reuh/anselme.git
				synced 2025-10-27 16:49:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			78 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local class = require("class")
 | |
| 
 | |
| local ast = require("ast")
 | |
| local Table, Identifier
 | |
| 
 | |
| local translations_identifier, translations_symbol
 | |
| 
 | |
| local translation_manager = class {
 | |
| 	init = false,
 | |
| 
 | |
| 	setup = function(self, state)
 | |
| 		state.scope:define(translations_symbol, Table:new(state))
 | |
| 	end,
 | |
| 
 | |
| 	-- context is the context Struct - when translating, the translation will only be used for nodes that at least match this context
 | |
| 	-- original is the original node (non-evaluated)
 | |
| 	-- translated is the translated node (non-evaluated)
 | |
| 	set = function(self, state, context, original, translated)
 | |
| 		local translations = state.scope:get(translations_identifier)
 | |
| 		if not translations:has(state, original) then
 | |
| 			translations:set(state, original, Table:new(state))
 | |
| 		end
 | |
| 		local tr = translations:get(state, original)
 | |
| 		return tr:set(state, context, translated)
 | |
| 	end,
 | |
| 
 | |
| 	-- context is the context Struct of the calling translation
 | |
| 	-- original is the original node to translate (non-evaluated)
 | |
| 	-- returns the (evaluated) translated node, or the original node if no translation defined
 | |
| 	eval = function(self, state, context, original)
 | |
| 		local translations = state.scope:get(translations_identifier)
 | |
| 		if translations:has(state, original) then
 | |
| 			local tr = translations:get(state, original)
 | |
| 
 | |
| 			-- find most specific translation
 | |
| 			local translated, specificity = nil, -1
 | |
| 			for match_context, match_translated in tr:iter(state) do
 | |
| 				local matched, match_specificity = true, 0
 | |
| 				for key, val in match_context:iter() do
 | |
| 					if context:has(key) and val:hash() == context:get(key):hash() then
 | |
| 						match_specificity = match_specificity + 1
 | |
| 					else
 | |
| 						matched = false
 | |
| 						break
 | |
| 					end
 | |
| 				end
 | |
| 				if matched then
 | |
| 					if match_specificity > specificity then
 | |
| 						translated, specificity = match_translated, match_specificity
 | |
| 					elseif match_specificity == specificity then
 | |
| 						print("a a dà é payé")
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			-- found, evaluate translated
 | |
| 			if translated then
 | |
| 				-- eval in a scope where all active translations, as translating the translation would be stupid
 | |
| 				state.scope:push_partial(translations_identifier)
 | |
| 				state.scope:define(translations_symbol, Table:new(state))
 | |
| 				local r = translated:eval(state)
 | |
| 				state.scope:pop()
 | |
| 				return r
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		-- no matching translation
 | |
| 		return original.expression:eval(state)
 | |
| 	end,
 | |
| }
 | |
| 
 | |
| package.loaded[...] = translation_manager
 | |
| Table, Identifier = ast.Table, ast.Identifier
 | |
| 
 | |
| translations_identifier = Identifier:new("_translations") -- Table of { Translatable = Table{ Struct context = translated node, ... }, ... }
 | |
| translations_symbol = translations_identifier:to_symbol()
 | |
| 
 | |
| return translation_manager
 |