|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://angg.twu.net/LUA/Arith6.lua.html
-- http://angg.twu.net/LUA/Arith6.lua
-- (find-angg "LUA/Arith6.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun a () (interactive) (find-angg "LUA/Arith6.lua"))
-- (defun a6 () (interactive) (find-angg "LUA/Arith6.lua"))
-- (defun a5 () (interactive) (find-angg "LUA/Arith5.lua"))
-- (defun a4 () (interactive) (find-angg "LUA/Arith4.lua"))
-- (find-angg "LUA/Lazy5.lua" "Lazy")
-- (find-angg "LUA/Lazy5.lua" "Lazy" "totree =")
-- (find-books "__comp/__comp.el" "aho" "left-associative")
-- «.BinOps» (to "BinOps")
-- «.BinExpr» (to "BinExpr")
-- «.BinExpr-tests» (to "BinExpr-tests")
-- «.Parenthesize» (to "Parenthesize")
-- «.defs_0» (to "defs_0")
-- (find-es "lpeg" "lpeg-quickref")
-- (find-es "lpeg" "globals")
require "lpeg"
B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V
Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg
Cp,Cs,Ct = lpeg.Cp,lpeg.Cs,lpeg.Ct
Carg,Cmt = lpeg.Carg,lpeg.Cmt
lpeg_methods = getmetatable(P("")).__index
-- «BinOps» (to ".BinOps")
--
BinOp = Class {
type = "BinOp",
__tostring = mytostring,
__index = {
},
}
BinOps = Class {
type = "BinOps",
new = function () return BinOps({ _ = {} }) end,
__tostring = function (o) return mytostringv(o._) end,
__index = {
has = function (bops, name) return bops._[name] end,
get = function (bops, name) return bops._[name] end,
add = function (bops, ...)
local A = {...}
for i=1,#A-2,3 do
local lbp,rbp,names = A[i],A[i+1],A[i+2]
for _,name in ipairs(split(names)) do
bops._[name] = BinOp {name=name, lbp=lbp, rbp=rbp}
end
end
return bops
end,
},
}
binops = BinOps.new()
binops:add(10, 11, "+ -",
20, 21, "* /",
31, 30, "^")
-- «BinExpr» (to ".BinExpr")
--
BinExpr = Class {
type = "BinExpr",
from = function (a, op, b) return BinExpr {[0]=op, a, b} end
is = function (o) return otype(o) == "BinExpr" end,
isl = function (o) return BinExpr.is(o) and BinExpr.is(o[1]) end,
isr = function (o) return BinExpr.is(o) and BinExpr.is(o[2]) end,
isl_paren = function (o)
if not BinExpr.isl(o) then return false end
local rbp,lbp = o[1]:rbp(), o:lbp()
return rbp < lbp
end,
isr_paren = function (o)
if not BinExpr.isr(o) then return false end
local rbp,lbp = o:rbp(), o[2]:lbp()
return lbp < rbp
end,
__tostring = function (bex)
local l,r = tostring(bex[1]), tostring(bex[2])
if bex:isl_paren() then l = "("..l..")" end
if bex:isr_paren() then r = "("..r..")" end
return format("%s %s %s", l, bex[0], r)
end,
__index = {
lbp = function (bex) return binops:get(bex[0]).lbp end,
rbp = function (bex) return binops:get(bex[0]).rbp end,
isl = function (bex) return BinExpr.isl(bex) end,
isr = function (bex) return BinExpr.isr(bex) end,
isl_paren = function (bex) return BinExpr.isl_paren(bex) end,
isr_paren = function (bex) return BinExpr.isr_paren(bex) end,
},
}
-- «BinExpr-tests» (to ".BinExpr-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith6.lua"
= binops
be = function (a, op, b) return BinExpr {[0]=op, a, b} end
foo = be(22, "+", 33)
= BinExpr.is(foo)
= BinExpr.is(22)
= BinExpr.isl(foo)
= BinExpr.isr(foo)
= foo
= be(44, "*", foo)
= be(be(22, "+", 33), "*", be(44, "^", 55))
= be(be(22, "^", 33), "*", be(44, "+", 55))
= be(be(22, "-", 33), "-", be(44, "-", 55))
run_my_repl_now()
dg = dgis
= dg
= dg[7]
= dg[7]:info()
--]]
s = S(" \t\n")^0
num = C(R("09")^1)
Tree = Class {
type = "Tree",
__tostring = function (o) return tostring(SynTree.from(o)) end,
__index = {
},
}
Tok = Class {
type = "Tok",
anyof = function (str)
local plus = function (a, b) return a+b end
return C(foldl1(plus, map(P, split(str))))
end,
__index = {
},
}
Assoc = Class {
type = "Assoc",
afoldl = function (f, A)
local o = A[1]
for i=3,#A,2 do o = f(o, A[i-1], A[i]) end
return o
end,
afoldr = function (f, A)
local o = A[#A]
for i=#A-2,1,-2 do o = f(A[i], A[i+1], o) end
return o
end,
mktr = function (a, op, b) return BinExpr {[0]=op, a, b} end,
afoldltr = function (A) return Assoc.afoldl(Assoc.mktr, A) end,
afoldrtr = function (A) return Assoc.afoldr(Assoc.mktr, A) end,
list = function (e, op) return Ct(e*(op*e)^0) end,
left = function (e, op) return Assoc.list(e, op) / Assoc.afoldltr end,
right = function (e, op) return Assoc.list(e, op) / Assoc.afoldrtr end,
__index = {
},
}
istable = function (o) return type(o) == "table" end
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith6.lua"
f = function (a, b) return format("(%s,%s)", a, b) end
af = function (a,op,b) return format("(%s %s %s)", a, op, b) end
= Assoc.afoldl(af, {2, "+", 4, "*", 6, "/", 7})
= Assoc.afoldr(af, {2, "+", 4, "*", 6, "/", 7})
op_exp = Tok.anyof("^")
op_mul = Tok.anyof("* /")
op_add = Tok.anyof("+ -")
expr_exp = Assoc.right(num, op_exp)
expr_mul = Assoc.left(expr_exp, op_mul)
expr_add = Assoc.left(expr_mul, op_add)
= Tree(expr_exp:match("22^33^44^55"))
= Tree(expr_add:match("22^33^44^55-66-77"))
= expr_add:match("22^33^44^55-66-77")
expr_all = lpeg.P{
"expr_add",
expr_basic = num + "(" * V"expr_add" * ")",
expr_exp = Assoc.right(V"expr_basic", op_exp),
expr_mul = Assoc.left (V"expr_exp", op_mul),
expr_add = Assoc.left (V"expr_mul", op_add),
}
= Tree(expr_add:match("22^33+44*(55-66-77)^88^99"))
= Tree(expr_all:match("22^33+44*(55-66-77)^88^99"))
= expr_all:match("22^33+44*(55-66-77)^88^99")
--]]
-- «Parenthesize» (to ".Parenthesize")
Parenthesize = Class {
type = "Parenthesize",
new = function () return Parenthesize {binops={}} end,
__tostring = function (pth) return mytostringv(pth.binops) end,
__index = {
binops = {},
addbinops = function (pth, A)
for i=1,#A-2,3 do
local lbp,rbp,ops = A[i], A[i+1], A[i+2]
for _,op in ipairs(split(ops)) do
pth.binops[op] = {lbp=lbp, rbp=rbp}
end
end
return pth
end,
isbin = function (pth, o)
return type(o) == "table"
and #o == 2
and o[0]
and pth.binops[o[0]]
end,
isbinlbin = function (pth, o) return pth:isbin(o) and pth:isbin(o[1]) end,
isbinrbin = function (pth, o) return pth:isbin(o) and pth:isbin(o[2]) end,
lbp = function (pth, o)
return pth:isbin(o) and pth.binops[o[0]].lbp
end,
rbp = function (pth, o)
return pth:isbin(o) and pth.binops[o[0]].rbp
end,
lparen = function (pth, o)
if pth:isbin(o) then
return pth:isbin(o[1]) and pth:rbp(o[1]) < pth:lbp(o)
end
end,
rparen = function (pth, o)
if pth:isbin(o) then
return pth:isbin(o[2]) and pth:lbp(o[2]) < pth:rbp(o)
end
end,
tos = function (pth, o)
if type(o) == "number" then return tostring(o) end
if type(o) == "string" then return o end
if type(o) == "table" then
if pth:isbin(o) then
local strl,strr = pth:tos(o[1]), pth:tos(o[2])
if pth:lparen(o) then strl = "("..strl..")" end
if pth:rparen(o) then strr = "("..strr..")" end
return format("%s %s %s", strl, o[0], strr)
end
error("a")
end
error("b")
end,
},
}
-- «defs_0» (to ".defs_0")
defs_0 = function ()
op_exp = Tok.anyof("^")
op_mul = Tok.anyof("* /")
op_add = Tok.anyof("+ -")
--
pth = Parenthesize.new():addbinops({
10, 11, "+ -",
20, 21, "* /",
31, 30, "^",
})
--
expr_0 = lpeg.P{
"expr_add",
expr_basic = num + "(" * V"expr_add" * ")",
expr_exp = Assoc.right(V"expr_basic", op_exp),
expr_mul = Assoc.left (V"expr_exp", op_mul),
expr_add = Assoc.left (V"expr_mul", op_add),
}
end
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Arith6.lua"
defs_0()
= pth
foo = expr_0:match("22^33+44*(55-66-77)^88^99")
foo = expr_0:match("(22-33)-(44-55)")
= Tree(foo)
= pth:tos(foo)
foo = expr_0:match("(22^33)^(44^55)")
= Tree(foo)
= pth:tos(foo)
foo = expr_0:match("(22+33)*(44^55)")
= Tree(foo)
= pth:tos(foo)
= pth:tos(22)
= pth:tos("bla")
-- (find-anggfile "OCAML/calc0.ml")
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: