|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/Match1.lua.html
-- http://anggtwu.net/LUA/Match1.lua
-- (find-angg "LUA/Match1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- This will be the basis of a pattern-matcher based on Haskell, OCaml
-- and pcase... but it's incomplete.
--
-- (find-elnode "Pattern-Matching Conditional")
--
-- (defun e () (interactive) (find-angg "LUA/Match1.lua"))
-- «.basic» (to "basic")
-- «.basic-tests» (to "basic-tests")
-- «.matcherfor» (to "matcherfor")
-- «.matcherfor-tests» (to "matcherfor-tests")
-- «.MatchRep» (to "MatchRep")
-- «.MatchRep-tests» (to "MatchRep-tests")
require "Indent2" -- (find-angg "LUA/Indent2.lua")
-- «basic» (to ".basic")
Pict.__index["do+3"] = "do<i:ind(3);o=' '>"
Pict.__index["end"] = "<i:pop();o='\\n'>end"
Pict.__index.doend = function (p) return p:wrap0("do+3", "end") end
Pict.__index.testsub = function (p, field)
return Pict { format("local subj = subj[%s]", mytostring(field)), p }:doend()
end
Pict.isast2 = function (o0,n)
return Pict { "if otype(subj) ~= 'AST' then return false end",
format("if subj[0] ~= %q then return false end", o0),
format("if #subj ~= %d then return false end", n) }
end
Pict.saveinto = function (to,from)
if not from then
return Pict { format("saved[%s] = subj", mytostring(to)) }
end
return Pict { format("saved[%s] = subj[%s]", mytostring(to), mytostring(from)) }
end
Pict.testsub = function (field, ...)
return Pict({...}):testsub(field)
end
Pict.matcher = function (...)
return Pict { "local subj = ...",
"local saved = VTable {}",
Pict {...},
"return saved" }
end
-- «basic-tests» (to ".basic-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Match1.lua"
o = mkast("*", "x", mkast("+", "y", "z"))
= o
= Pict.isast2('"', 2)
= Pict.saveinto("a")
= Pict.saveinto("a", 1)
= Pict {"foo", "bar"} :testsub(1)
= Pict.testsub(1, "foo", "bar")
= Pict.testsub("field", "foo", "bar")
= Pict.testsub("field", {"foo", "bar"})
p1 = Pict { Pict.isast2('*', 2),
Pict.saveinto("a", 1),
Pict.testsub(2,
Pict.isast2('+', 2),
Pict.saveinto("b", 1),
Pict.saveinto("c", 2)
),
}
= p1
= Pict { Pict.isast2('*', 2),
Pict.testsub(1, Pict.saveinto("a")),
Pict.testsub(2, Pict.saveinto("b")),
}
= Pict.matcher(
Pict.isast2('*', 2),
Pict.testsub(1, Pict.saveinto("a")),
Pict.testsub(2, Pict.saveinto("b"))
)
--]]
-- «matcherfor» (to ".matcherfor")
matcherfor_ = function (o)
if type(o) == "string" and o:match"^_"
then return Pict.saveinto(o:sub(2))
end
end
matcherforAST = function (o)
if otype(o) == "AST" then
local p = Pict { Pict.isast2(o[0], #o) }
for i=1,#o do
table.insert(p, Pict.testsub(i, matcherfor(o[i])))
end
return p
end
end
matcherfor = function (o)
return matcherfor_(o)
or matcherforAST(o)
or error("BANG!")
end
add = function (...) return mkast("+", ...) end
mul = function (...) return mkast("*", ...) end
-- «matcherfor-tests» (to ".matcherfor-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Match1.lua"
= matcherfor "_a"
= matcherfor( add("_b", "_c"))
= matcherfor( add("_b", "_c", "_d"))
= matcherfor(mul("_a", add("_b", "_c", "_d")))
= Pict.matcher(matcherfor(mul("_a", add("_b", "_c", "_d"))))
abc = mul("_a", add("_b", "_c"))
--]]
-- __ __ _ _ ____
-- | \/ | __ _| |_ ___| |__ | _ \ ___ _ __
-- | |\/| |/ _` | __/ __| '_ \| |_) / _ \ '_ \
-- | | | | (_| | || (__| | | | _ < __/ |_) |
-- |_| |_|\__,_|\__\___|_| |_|_| \_\___| .__/
-- |_|
-- «MatchRep» (to ".MatchRep")
MatchRep = Class {
type = "MatchRep",
__index = {
code1_ = function (mr) return Pict.matcher(matcherfor(expr(mr[1]))) end,
code1 = function (mr) return Code.eval(tostring(mr:code1_())) end,
coden = function (mr,n) return Code.ve("_ => "..mr[n]) end,
match_ = function (mr,o) return mr:code1()(o) end,
match_n = function (mr,o,n) return mr:coden(n)(mr:match_(o)) end,
},
}
-- «MatchRep-tests» (to ".MatchRep-tests")
mr = MatchRep {
'mul("_a", add("_b", "_c"))',
'add(mul(_.a, _.b), mul(_.a, _.c))',
}
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Match1.lua"
= mr[1]
= expr(mr[1])
= matcherfor(expr(mr[1]))
= Pict.matcher(matcherfor(expr(mr[1])))
= mr:code1_()
= mr:code1 ()
o = mul(2, add(3, 4))
= o
= mr:match_ (o)
= mr:match_n(o, 2)
--]==]
-- Local Variables:
-- coding: utf-8-unix
-- End: