SHARE
TWEET

Untitled

a guest Oct 18th, 2019 77 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- vim: set noexpandtab tabstop=3 :miv --
  2.  
  3. -- Note: To make reading of this codebase more enjoyable, please consider typing
  4. -- :%s/other/otter/
  5. -- into your vim command line.
  6.  
  7. local function tokenize(tokens, values, reference, target)
  8.     for key, value in pairs(reference) do
  9.         if tokens[value] then
  10.             if target[key] then
  11.                 rawset(values, tokens[value], target[key])
  12.             else
  13.                 return nil
  14.             end
  15.         else
  16.             if type(value) == 'table' and type(target[key]) == 'table' then
  17.                 if not tokenize(tokens, values, reference[key], target[key]) then
  18.                     return nil
  19.                 end
  20.             else
  21.                 if target[key] ~= value then
  22.                     return nil
  23.                 end
  24.             end
  25.         end
  26.     end
  27.  
  28.     -- Abort if target has extra values -- Really though?
  29.     for key, value in pairs(target) do
  30.         -- I don't like how this iterates over everything again
  31.         -- Maybe there's another way of doing this, dunno
  32.         if reference[key]==nil then -- Remember to accept `false` as a value
  33.             return nil
  34.         end
  35.     end
  36.  
  37.     return values
  38. end
  39.  
  40. local function match(reference)
  41.     local tokens = {}
  42.     local _tokens = {}
  43.  
  44.     -- Make "unused" globals resolve to tokens
  45.     env = setmetatable({}, {__index=function(self, key)
  46.         local super=_G[key] do
  47.             if super then
  48.                 return super
  49.             else
  50.                 if _tokens[key] then
  51.                     return _tokens[key]
  52.                 else
  53.                     local token = {}
  54.                     tokens[token] = key
  55.                     _tokens[key] = token
  56.                     return token
  57.                 end
  58.             end
  59.         end
  60.     end})
  61.  
  62.     reference = reference(env)
  63.  
  64.     return function(target)
  65.         local values = tokenize(tokens, {}, reference, target)
  66.  
  67.         if values then
  68.             setmetatable(values, {__index=_G})
  69.             return function(code)
  70.                 return code(values)
  71.             end
  72.         else
  73.             return function()
  74.             end
  75.         end
  76.     end
  77. end
  78.  
  79. --[============================================================================[
  80.     This is where the magic ends and the showcase begins ;)
  81. --]============================================================================]
  82.  
  83. local pair = match(function(_ENV)
  84.     return {
  85.         { name = 'alice' },
  86.         { name = other }
  87.     }
  88. end)
  89.  
  90. local maybe = pair {
  91.     { name = 'alice' },
  92.     { name = 'bob' }
  93. }
  94.  
  95. maybe(function(_ENV)
  96.     print(other)
  97. end)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top