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: