Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://anggtwu.net/LUA/Code2.lua.html
--   http://anggtwu.net/LUA/Code2.lua
--          (find-angg "LUA/Code2.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2024jan08
-- Public domain.
--
-- Also here:  (find-angg "LUA/lua50init.lua" "Code")
-- Supersedes: (find-angg "LUA/Code.lua")
--
-- (defun e () (interactive) (find-angg "LUA/Code2.lua"))
-- (defun o () (interactive) (find-angg "LUA/Code.lua"))

-- «.Code»		(to "Code")
-- «.Code-tests»	(to "Code-tests")


--   ____          _      
--  / ___|___   __| | ___ 
-- | |   / _ \ / _` |/ _ \
-- | |__| (_) | (_| |  __/
--  \____\___/ \__,_|\___|
--                        
-- «Code»  (to ".Code")
-- Also here: (find-angg "LUA/lua50init.lua" "Code")
--  Based on: (find-angg "LUA/lua50init.lua" "eval-and-L")
--            (find-angg "LUA/Code.lua")
--
-- The class Code "converts strings to executable code" in nice ways.
-- Initially there are two basic ways to do the conversion:
--
--    Code.ve [[ a,b =>                  10*a + b ]] (3, 4)
--    Code.vc [[ a,b => print(a); return 10*a + b ]] (3, 4)
--
-- roughly,
--
--    Code.ve interprets its argument as "var => expr", and
--    Code.vc interprets its argument as "var => code".
--
-- It is relatively easy to add other ways to interpret the "code".
-- An object of the class Code has two fields: .src, with the "code"
-- in the original received form, and .code, with it converted to Lua
-- code that can be run with loadstring. TA-DA: an object of the class
-- Code does NOT contain a compiled version of its .code field! 8-O

Code = Class {
  type  = "Code",
  from  = function (src) return Code{src=src}:parse() end,
  expr  = function (src) return Code{src=src}:mkbody("_expr") end,
  eval  = function (src) return Code{src=src}:mkbody("_eval") end,
  ve    = function (src) return Code.from(src):mkbody("_ve") end,
  vc    = function (src) return Code.from(src):mkbody("_vc") end,
  __tostring = function (c) return c:tostring() end,
  __call     = function (c,...) return c:f()(...) end,
  __index = {
    tostring1 = function (c,key) return format("%8s: %s", key, c[key]) end,
    tostring2 = function (c,keys)
        local lines = {}
        if type(keys) == "string" then keys = split(keys) end
        for _,key in ipairs(keys) do
          if c[key] then table.insert(lines, c:tostring1(key)) end
        end
        return table.concat(lines, "\n")
      end,
    tostring = function (c)
        return c:tostring2("src srcvars srcbody templkey template body")
      end,
    tostring_sortedkeys = function (c) return c:tostring2(sortedkeys(c)) end,
    --
    srcpat = "^%s*([%w_,]+)%s*[%-=]>%s*(.*)$",
    parse = function (c)
        local srcvars,srcbody = c.src:match(c.srcpat)
        if not srcvars then error("Code.parse can't parse: "..c.src) end
        c.srcvars,c.srcbody = srcvars,srcbody
        return c
      end,
    --
    _eval   = "<src>",
    _expr   = "return <src>",
    _vc     = "local <srcvars> = ...; <srcbody>",
    _ve     = "local <srcvars> = ...; return <srcbody>",
    mkbody  = function (c,key,template)
        local f = function (s) return c[s] end
        c.templkey = key
        c.template = template or c[key]
        c.body     = c.template:gsub("<(.-)>", f)
        return c
      end,
    f = function (c) return assert(loadstring(c.body)) end,
  },
}

-- «Code-tests»  (to ".Code-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Code2.lua"
= Code {src=[[ a,b => a+b ]]}
= Code {src=[[ a,b => a+b ]]} :parse()
= Code.from [[ a,b => a+b ]]
= Code.from [[ a,b => a+b ]] :mkbody(nil, "return <srcbody>")
= Code.from [[ a,b => a+b ]] :mkbody("_vc")
= Code.from [[ a,b => a+b ]] :mkbody("_ve")
= Code.from [[ a,b => a+b ]] :mkbody("_ve") :f()
= Code.from [[ a,b => a+b ]] :mkbody("_ve") :f() (2,3)
= Code.from [[ a,b => a+b ]] :mkbody("_ve")      (2,3)

= Code.from [[ a,b => a+b ]] :mkbody("_ve")
= Code.from [[ a,b => a+b ]] :mkbody("_ve") :tostring_sortedkeys()

= Code.expr        [[ 2+3 ]]
= Code.expr        [[ 2+3 ]] ()
= Code.eval [[ return 2+3 ]]
= Code.eval [[ return 2+3 ]] ()

L = Code.ve
= L [[ a,b => 10*a+b ]]
= L [[ a,b => 10*a+b ]] :f()
= L [[ a,b => 10*a+b ]] :f() (3,4)
= L [[ a,b => 10*a+b ]]      (3,4)

L = function (code) return Code.ve(code):f() end
= L [[ a,b => 10*a+b ]]
= L [[ a,b => 10*a+b ]]      (3,4)

--]==]




-- Local Variables:
-- coding:  utf-8-unix
-- End: