Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://anggtwu.net/LUA/MapAST2.lua.html
--   http://anggtwu.net/LUA/MapAST2.lua
--          (find-angg "LUA/MapAST2.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- This file implements several functions that look conceptually like
-- "map", but that act on ASTs and that are recursive.
--
-- (defun e () (interactive) (find-angg "LUA/MapAST2.lua"))
-- (defun o () (interactive) (find-angg "LUA/MapAST2.lua"))
--
-- Used by:
--   (find-angg "LUA/ParseTikz1.lua")
--   (find-angg "LUA/ParseTikz1.lua" "grammar-2")

-- «.MapAST-basic»		(to "MapAST-basic")
-- «.MapAST-basic-tests»	(to "MapAST-basic-tests")
-- «.MapAST_underbracify»	(to "MapAST_underbracify")
-- «.MapAST_underbracify-tests»	(to "MapAST_underbracify-tests")
-- «.AST-methods»		(to "AST-methods")
-- «.AST-methods-tests»		(to "AST-methods-tests")
-- «.totex»			(to "totex")

-- TODO: (find-angg "LUA/ParseTree2.lua" "fmts")

require "ELpeg1"        -- (find-angg "LUA/ELpeg1.lua")
                        -- (find-angg "LUA/ELpeg1.lua" "AST")
require "Tos3"          -- (find-angg "LUA/Tos3.lua")
require "Show2"         -- (find-angg "LUA/Show2.lua")
require "Co1"           -- (find-angg "LUA/Co1.lua")
require "ToTeX1"        -- (find-angg "LUA/ToTeX1.lua")

PPT = function (...)
    return MakePrint.with(...):mapn(treetor):ddot():print():ret()
  end

mkastbe = function (tag, b, e,...)
    return AST {[0]=tag, b=b, e=e, ...}
  end


-- «MapAST-basic»  (to ".MapAST-basic")

MapAST = Class {
  type    = "MapAST",
  __index = {
    tablep   = function (m,o)   return type(o) == "table"  end,
    stringp  = function (m,o)   return type(o) == "string" end,
    copy0be  = function (m,o)   return AST {[0]=o[0], b=o.b, e=o.e} end,
    add      = function (m,A,o) if o then table.insert(A,o) end end,
    map1     = function (m,o)
        if not m:tablep(o) then return m:f1(o) end
        local ast = m:copy0be(o)
        for i=1,#o do m:add(ast, m:map1(o[i])) end
        return ast
      end,
    mapt     = function (m,o)
        if not m:tablep(o) then return o end
        local newt = m:ft(o); if newt then return newt end
        local ast = m:copy0be(o)
        for i=1,#o do m:add(ast, m:mapt(o[i])) end
        return ast
      end,
    --
    delstr1  = function (m,o) if not m:stringp(o) then return o end end,
    dotstr1  = function (m,o) return m:stringp(o) and "."..o.."." or o end,
    --
    trivs    = Set.new(),
    trivp    = function (m,o) return m.trivs:has(o) end,
    triv0p   = function (m,o) return m:tablep(o) and m:trivp(o[0]) end,
    deltriv  = function (m,o) if m:triv0p(o) then return m:mapt(o[1]) end end,
    --
    delap    = function (m,o)
        if m:tablep(o) and o[0] == "ap" then
          local ast = AST {[0]=o[1], b=o.b, e=o.e}
          for i=2,#o do m:add(ast, m:mapt(o[i])) end
          return ast
        end
      end,
    --
    subj0  = function (m,b,e) return subj:sub(b,     e-1) end,
    subj   = function (m,o)   return subj:sub(o.b, o.e-1) end,
    mkco0  = function (m,b,e) return mkastbe("Co",b,e, m:subj0(b,e)) end,
    mkco   = function (m,o)   return m:mkco0(o.b, o.e) end,
    ang    = function (m,s)   return mkast("<>", s) end,
    und1   = function (m,o)   return mkastbe("Und",o.b,o.e, m:mkco(o), m:ang(o)) end,
    dotbe0 = function (m,o)   return format("%s.%d.%d", (o[0] or ""), o.b, o.e) end,
    dotbe1 = function (m,o)
        if m:tablep(o) and o.b and o.e then
          local ast = AST {[0]=m:dotbe0(o), b=o.b, e=o.e}
          for i=1,#o do m:add(ast, m:mapt(o[i])) end
          return ast
        end
      end,
  },
}

MapAST_delstrings = function (o)
    local ma = MapAST { f1=MapAST.__index.delstr1 }
    return ma:map1(o)
  end
MapAST_dotstrings = function (o)
    local ma = MapAST { f1=MapAST.__index.dotstr1 }
    return ma:map1(o)
  end
MapAST_deltrivs = function (o)
    local ma = MapAST { ft=MapAST.__index.deltriv }
    return ma:mapt(o)
  end
MapAST_delaps = function (o)
    local ma = MapAST { ft=MapAST.__index.delap }
    return ma:mapt(o)
  end
MapAST_dotbe = function (o)
    local ma = MapAST { ft=MapAST.__index.dotbe1 }
    return ma:mapt(o)
  end

-- «MapAST-basic-tests»  (to ".MapAST-basic-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "MapAST2.lua"
MapAST.__index.trivs = Set.from(split("var num"))

  o = mkast("ap", "f", mkast("ap", "g", mkast("num", 99), "x"))
= o
= MapAST_dotstrings(o)
= MapAST_delstrings(o)
= MapAST_deltrivs(o)
= MapAST_delaps(o)
=                                 MapAST_deltrivs(o)
=                   MapAST_delaps(MapAST_deltrivs(o))
= MapAST_dotstrings(MapAST_delaps(MapAST_deltrivs(o)))
= MapAST_delstrings(MapAST_delaps(MapAST_deltrivs(o)))

subj = "_Aa_Bb_"

oa = mkastbe("a",2,4)
ob = mkastbe("b",5,7)
oc = mkastbe("c",1,8, oa, ob)
= oc

ma = MapAST {}
= ma:subj(oa)
= ma:mkco(oa)
= ma:ang(oa[0])
= ma:und1(oa)
= ma:dotbe0(oa)
= ma:dotbe0(ob)
= ma:dotbe0(oc)
= MapAST_dotbe(oc)
=              ma:sandw0(oc)
= MapAST_dotbe(ma:sandw0(oc))

--]]

-- «MapAST_underbracify»  (to ".MapAST_underbracify")

table.addentries(MapAST.__index, {
    sandw0 = function (m,o)
      local sandw  = AST {[0]=o[0], b=o.b, e=o.e}
      local b,e    = o.b,o.e
      local pos    = o.b
      local addco  = function (x,y) m:add(sandw, (x~=y and m:mkco0(x,y))) end
      local addw   = function (w)   m:add(sandw, w); pos = w.e end
      local addcow = function (w)   addco(pos,w.b); addw(w) end
      if #o == 0 then
        addco(b,e)
      else
        for i=1,#o do addcow(o[i]) end
        addco(pos,e)
      end
      return sandw
    end,
    sandwrec = function (m,o)   -- recursive
        if not m:tablep(o) then return o end
        if not (o.b and o.e) then return o end
        local f = function (o) return m:sandwrec(o) end
        local o2 = AST {[0]="tmp", b=o.b, e=o.e, unpack(map(f, o))}
        local o3 = AST {[0]=".",   b=o.b, e=o.e, unpack(m:sandw0(o2))}
        local o4 = AST {[0]="Und", b=o.b, e=o.e, o3, m:ang(o[0])}
        return o4
      end,
  })

MapAST_underbracify0 = function (o)
    return MapAST{}:sandwrec(o)
  end
MapAST_underbracify = function (o)
    return MapAST_underbracify0(MapAST_delstrings(o))
  end

-- «MapAST_underbracify-tests»  (to ".MapAST_underbracify-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "MapAST2.lua"
ma = MapAST {}
subj = "_DdEe_"

= ma:ang("bla")

od = mkastbe("d",2,4)
oe = mkastbe("e",4,6)
of = mkastbe("f",1,7, od, oe)
=                     of
=           ma:sandw0(of)
= MapAST_underbracify(of)

--]]
 

-- «AST-methods»  (to ".AST-methods")

table.addentries(AST.__index, {
    delstrings    = function (o) return MapAST_delstrings(o) end,
    dotstrings    = function (o) return MapAST_dotstrings(o) end,
    deltrivs      = function (o) return MapAST_deltrivs(o) end,
    delaps        = function (o) return MapAST_delaps(o) end,
    dotbe         = function (o) return MapAST_dotbe(o) end,
    underbracify0 = function (o) return MapAST_underbracify0(o) end,
    underbracify  = function (o) return MapAST_underbracify(o) end,
  })

-- «AST-methods-tests»  (to ".AST-methods-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "MapAST2.lua"

--]]



-- «totex»  (to ".totex")
-- (find-angg "LUA/ParseTree1.lua" "cot")
-- (find-angg "LUA/ParseTree1.lua" "totex")

co0 = Co.new(" %_{}", "\\^")
co0 = Co.new(" %_{}<>=", "\\^")
co0 = Co.new(" %_{}", "<>=\\^")
cot = co0:translator()

middletexbody = Dang.from [=[
\scalebox{<<scale>>}{%
  <<texbody>>
  }
]=]
defs.NT = [=[
  % (find-LATEX "2023-2-C2-intro.tex" "gramatica-fig")
  \def\ColorRed#1{{\color{red}{#1}}}
  \def\NT#1{\langle\textsf{#1}\rangle}
  \def\T#1{\ColorRed{\tt#1}}
  \def\T#1{\mathstrut \ColorRed{\tt#1}}
  \def\T#1{\mathstrut \ColorRed{\texttt{#1}}}
  \def\und#1#2{\underbrace{#1}_{\textstyle#2}}
]=]

-- fmts       = VTable {}
fmts["Co"]    = "\\T{<cot(o[1])>}"
fmts["Und"]   = "\\und{<1>}{<2>}"
fmts["."]     = "<mapconcat(totex, o)>"
fmts["<>"]    = "\\NT{<o[1]>}"




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