|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://angg.twu.net/LUA/Parenthesize2.lua.html
-- http://angg.twu.net/LUA/Parenthesize2.lua
-- (find-angg "LUA/Parenthesize2.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun p () (interactive) (find-angg "LUA/PrecParser1.lua"))
-- (defun o () (interactive) (find-angg "LUA/Parenthesize2.lua"))
-- (defun oo () (interactive) (find-angg "LUA/Parenthesize1.lua"))
require "Show1" -- (find-angg "LUA/Show1.lua" "string.show")
require "Tree1" -- (find-angg "LUA/Tree1.lua")
require "GetInfo2" -- (find-angg "LUA/GetInfo2.lua")
OpInfo = Class {
type = "OpInfo",
new = function () return OpInfo {ops={}} end,
__tostring = function (opi) return mytostringv(opi.ops) end,
__index = {
addinfix = function (opi, lbp, rbp, names)
for _,name in ipairs(split(names)) do
opi.ops[name] = HTable {fixity="infix", name=name, lbp=lbp, rbp=rbp}
end
return opi
end,
addprefix = function (opi, rbp, names)
for _,name in ipairs(split(names)) do
opi.ops[name] = HTable {fixity="prefix", name=name, rbp=rbp}
end
return opi
end,
addpostfix = function (opi, lbp, names)
for _,name in ipairs(split(names)) do
opi.ops[name] = HTable {fixity="postfix", name=name, lbp=lbp}
end
return opi
end,
norm = function (opi, x) return x or HTable {} end,
opinfo = function (opi, op) return opi:norm(op and opi.ops[op]) end,
oinfo = function (opi, o) return opi:norm(type(o) == "table" and opi:opinfo(o[0])) end,
--
opbin = function (opi, op) return opi:opinfo(op).fixity == "infix" end,
opinfix = function (opi, op) return opi:opinfo(op).fixity == "infix" end,
opprefix = function (opi, op) return opi:opinfo(op).fixity == "prefix" end,
oppostfix = function (opi, op) return opi:opinfo(op).fixity == "postfix" end,
oplbp = function (opi, op) return opi:opinfo(op).lbp end,
oprbp = function (opi, op) return opi:opinfo(op).rbp end,
--
obin = function (opi, o) return opi:oinfo(o).fixity == "infix" end,
oinfix = function (opi, o) return opi:oinfo(o).fixity == "infix" end,
oprefix = function (opi, o) return opi:oinfo(o).fixity == "prefix" end,
opostfix = function (opi, o) return opi:oinfo(o).fixity == "postfix" end,
olbp = function (opi, o) return opi:oinfo(o).lbp end,
orbp = function (opi, o) return opi:oinfo(o).rbp end,
parenp = function (opi, o, i)
if i==1 then
if opi:obin(o) then return (opi:orbp(o[1]) or 999) < opi:olbp(o)
elseif opi:opostfix(o) then return (opi:orbp(o[1]) or 999) < opi:olbp(o)
elseif opi:oprefix(o) then return (opi:olbp(o[1]) or 999) < opi:orbp(o)
else error("Bad paren1")
end
elseif i==2 then
if opi:obin(o) then return (opi:olbp(o[2]) or 999) < opi:orbp(o)
else error("Bad paren2")
end
else error("Bad i for parenp")
end
end,
text = function (opi, o)
if type(o) ~= "table" then return mytostring(o) end
local ptext = function (i)
local fmt = opi:parenp(o, i) and "(%s)" or "%s"
return format(fmt, opi:text(o[i]))
end
if opi:obin(o)
then return format("%s %s %s", ptext(1), o[0], ptext(2))
elseif opi:opostfix(o)
then return format("%s %s", ptext(1), o[0])
elseif opi:oprefix(o)
then return format("%s %s", o[0], ptext(1))
end
return "Bad opi:text"
end,
},
}
opi = OpInfo.new()
opi:addinfix(10, 11, "+ -")
opi:addinfix(30, 31, "* /")
opi:addinfix(41, 40, "^")
opi:addpostfix(50, "!")
opi:addprefix (20, "u-")
bin = function (a, op, b) return Tree {[0]=op, a, b} end
pre = function (op, a) return Tree {[0]=op, a} end
post = function (a, op) return Tree {[0]=op, a} end
add = function (a, b) return bin(a, "+", b) end
minus = function (a, b) return bin(a, "-", b) end
mul = function (a, b) return bin(a, "*", b) end
div = function (a, b) return bin(a, "/", b) end
pow = function (a, b) return bin(a, "^", b) end
fact = function (a) return Tree {[0]="!", a} end
uminus = function (a) return Tree {[0]="u-", a} end
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Parenthesize2.lua"
= opi
= add(2, 3)
foo = add(2, 3)
= opi:opinfo(foo)
= opi:opinfo("+")
= opi:oinfo("+")
= opi:oinfo(foo)
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Parenthesize2.lua"
test = function (o) print(trees(o, opi:text(o))) end
test(mul(1, add(2, 3)), "1 * (2 + 3)")
test(mul(add(1, 2), 3), "(1 + 2) * 3")
test(mul(add(1, 2), add(3, 4)), "ok")
test(add(mul(1, 2), mul(3, 4)), "ok")
test(add(2, 3))
test(add(1, mul(2, 3)))
test(add(mul(1, 2), 3))
test(minus(minus(1, 2), minus(3, 4)))
test(pow(pow(1, 2), pow(3, 4)))
test(mul(uminus(1), fact(2)))
test(uminus(fact(42)))
test(fact(uminus(42)))
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: