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: