Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://anggtwu.net/LUA/Ast2.lua.html -- http://anggtwu.net/LUA/Ast2.lua -- (find-angg "LUA/Ast2.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- (defun a () (interactive) (find-angg "LUA/Ast1.lua")) -- (defun a1 () (interactive) (find-angg "LUA/Ast1.lua")) -- (defun a2 () (interactive) (find-angg "LUA/Ast2.lua")) -- (defun a3 () (interactive) (find-angg "LUA/Ast3.lua")) -- (defun a4 () (interactive) (find-angg "LUA/Ast4.lua")) -- (defun c3 () (interactive) (find-angg "LUA/Caepro3.lua")) -- (defun c4 () (interactive) (find-angg "LUA/Caepro4.lua")) -- (defun g2 () (interactive) (find-angg "LUA/Gram2.lua")) -- (defun g3 () (interactive) (find-angg "LUA/Gram3.lua")) -- «.AST» (to "AST") -- «.AST-tests» (to "AST-tests") -- «.E» (to "E") -- «.E-tests» (to "E-tests") -- «.ToText» (to "ToText") -- «.ToText-tests» (to "ToText-tests") require "Gram2" -- (find-angg "LUA/Gram2.lua") lpeg.ptmatch = function (pat, str) PP(pat:Ct():match(str)) end L = Code.L -- _ ____ _____ -- / \ / ___|_ _| -- / _ \ \___ \ | | -- / ___ \ ___) || | -- /_/ \_\____/ |_| -- -- «AST» (to ".AST") -- Based on: (find-angg "LUA/Gram2.lua" "AST") -- AST = Class { type = "AST", alttags = {}, -- Override this! ify = function (o) if type(o) == "table" and o[0] and AST.alttags[o[0]] then o[0] = AST.alttags[o[0]] end return AST(o) end, __tostring = function (o) return tostring(SynTree.from(o)) end, __index = { }, } calceasy_alttags = function () AST.alttags = {eq="=", plus="+", minus="-", Mul="*", div="/", Div="//", pow="^", paren="()", plic="'"} end -- «AST-tests» (to ".AST-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Ast2.lua" = AST.ify {[0]="Mul", 2, 3} calceasy_alttags() = AST.ify {[0]="Mul", 2, 3} --]] -- _____ -- | ____| -- | _| -- | |___ -- |_____| -- -- «E» (to ".E") entries = {} E = setmetatable({}, { __call = function (_,name) return entries[name] end, __index = function (_,name) return entries[name] end, __newindex = function (_,name,o) entries[name] = o end, }) calceasy_E = function () fun = function (name) return AST {[0]="fun", name} end var = function (name) return AST {[0]="var", name} end num = function (str) return AST {[0]="num", str} end bin = function (a, op, b) return AST {[0]=op, a, b} end unary = function (op, a) return AST {[0]=op, a} end paren = function (a) return unary("()", a) end plic = function (a) return unary("'", a) end ap = function (a, b) return bin(a, "ap", b) end -- eq = function (a, b) return bin(a, "=", b) end plus = function (a, b) return bin(a, "+", b) end minus = function (a, b) return bin(a, "-", b) end mul = function (a, b) return bin(a, "mul", b) end Mul = function (a, b) return bin(a, "*", b) end div = 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 -- E[ "x" ] = var"x" E[ "ln x" ] = ap(fun"ln", E"x") E["(ln x)" ] = paren(E"ln x") E[ "3" ] = num("3") E["(ln x)^3" ] = pow(E"(ln x)", E"3") E["(ln x)^3" ] = pow(E"(ln x)", E"3") E[ "5" ] = num("5") E[ "sin x"] = ap(fun"sin", E"x") E[ "5 + sin x"] = plus(E"5", E"sin x") E["(ln x)^3 // 5 + sin x"] = Div(E"(ln x)^3", E"5 + sin x") -- E[ "f" ] = fun"f" E[ "(x)" ] = paren(E"x") E[ "f(x)" ] = ap(E"f", E"(x)") E[ "g" ] = fun"g" E[ "g(x)" ] = ap(E"g", E"(x)") E[ "f(x)g(x)" ] = mul(E"f(x)", E"g(x)") E["(f(x)g(x))" ] = paren(E"f(x)g(x)") E["(f(x)g(x))'" ] = plic(E"(f(x)g(x))") E[ "f'" ] = fun"f'" E[ "f'(x)" ] = ap(E"f'", E"(x)") E[ "f'(x)g(x)" ] = mul(E"f'(x)", E"g(x)") E[ "g'" ] = fun"g'" E[ "g'(x)"] = ap(E"g'", E"(x)") E[ "f(x)g'(x)"] = mul(E"f(x)", E"g'(x)") E[ "f'(x)g(x) + f(x)g'(x)"] = plus(E"f'(x)g(x)", E"f(x)g'(x)") E["(f(x)g(x))' = f'(x)g(x) + f(x)g'(x)"] = eq(E"(f(x)g(x))'", E"f'(x)g(x) + f(x)g'(x)") end -- «E-tests» (to ".E-tests") --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Ast2.lua" calceasy_alttags() -- irrelevant here calceasy_E() = E["(f(x)g(x))' = f'(x)g(x) + f(x)g'(x)"] = E["(ln x)^3 // 5 + sin x"] --]] -- (find-angg "LUA/Gram3.lua" "expr") foldplic = function (A) local o = A[1] for i=2,#A do o = plic(o) end return o end calceasy_grammar = function () gr,V,VA,VE,PE = Gram.new() grcm = function (...) print(gr:cm(...)) end _ = S(" ")^0 -- VA.num = Cs(R"09"^1) VA.var = anyof "x" VA.fun = anyof "f' f g' g ln sin" VA.ap = V.fun *_* V.exprbasic -- VA.paren = "("*_* V.expr *_*")" V.exprbasic = V.paren + V.ap + V.num + V.fun + V.var V.exprplic = assocpost(V.exprbasic, Cs"'" ) V.exprpow = assocr(V.exprplic, Cs"^" ) V.exprmul = assocl(V.exprpow, Cc"mul" ) V.exprMul = assocl(V.exprmul, Cs"*" ) V.exprplus = assocl(V.exprMul, Cs"+" ) V.exprDiv = assocl(V.exprplus, Cs"//" ) V.expreq = assocl(V.exprDiv, Cs"=" ) V.expr = V.expreq -- V.exprplic = Ct(V.exprbasic * (_*Cs"'")^0) / foldplic end --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Ast2.lua" calceasy_grammar() calceasy_alttags() -- optional calceasy_E() -- needed for plic -- alttags = {} = grcm("num", "234") = grcm("expr", "234") = grcm("expr", "f'") = grcm("expr", "f'(x)") = grcm("expr", "f'(x)") = grcm("expr", "f'(x) + 5") = grcm("expr", "f'(x) + 5^6 // 20") = grcm("expr", "(ln x)^3 // 5 + sin x") = grcm("expr", "(f(x)g(x))' = f'(x)g(x) + f(x)g'(x)") = E["(f(x)g(x))' = f'(x)g(x) + f(x)g'(x)"] = E["(ln x)^3 // 5 + sin x"] --]] -- _____ _____ _ -- |_ _|_|_ _|____ _| |_ -- | |/ _ \| |/ _ \ \/ / __| -- | | (_) | | __/> <| |_ -- |_|\___/|_|\___/_/\_\\__| -- -- «ToText» (to ".ToText") ToText0 = Class { type = "ToText0", __index = { with = function (tt0,o) return ToText {tt0=tt0, o=o} end, }, } ToText = Class { type = "ToText", __tostring = function (tt) return tostring(tt.o) end, __index = { from = function (tt, o) return ToText {tt0=tt.tt0, o=o} end, atn = function (tt, n) return tt:from(tt.o[n+0]) end, tag = function (tt) return tt.o[0] end, fmt = function (tt) return tt.tt0.fmts[tt:tag()] end, -- eval = function (tt,fmt,a,b,c) return L("tt,tt0,o,a,b,c => "..fmt)(tt, tt.tt0, tt.o, a, b, c) end, subst = function (tt, fmt) local f = function (s) if s:match"^[0-9]+$" then return tt:atn(s):totext() end return tt:eval(s) end return (fmt:gsub("<(.-)>", f)) end, totext = function (tt) if type(tt.o) == "string" then return tt.o end if type(tt.o) == "number" then return tostring(tt.o) end if not tt:tag() then return "[No tag]" end if not tt:fmt() then return "[No fmt: "..tt:tag().."]" end return tt:asttotext(tt.o) end, asttotext = function (tt) return tt:subst(tt:fmt()) end, }, } totex00 = ToText0 {fmts={}} -- Override this! totex0 = function (o) return totex00:with(o) end totex = function (o) return totex00:with(o):totext() end AST.__index.totex0 = function (o) return totex0(o) end AST.__index.totex = function (o) return totex (o) end -- «ToText-tests» (to ".ToText-tests") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Ast2.lua" calceasy_grammar() calceasy_alttags() -- optional calceasy_E() -- needed for plic oo = E"f(x)" = oo = totex(oo) = oo:totex() = oo:atn(2):totex() = calceasy0:with(o) = calceasy0:with(nil) PPPV(calceasy0:with(o)) PPPV(calceasy0:with(nil)) PPPV(calceasy0:with(42)) PPPV(calceasy0:with(oo)) ooo = calceasy0:with(oo) = ooo = ooo:totext() ooo:totext() = E"f(x)":totex() --]==] calceasy_totex = function () calceasy00 = ToText0 { fmts = { ["()"] = "(<1>)", ["//"] = "\\frac{<1>}{<2>}", ["^"] = "{<1>}^{<2>}", ["+"] = "<1> + <2>", ["="] = "<1> = <2>", ap = "<1> <2>", mul = "<1> <2>", Mul = "<1> \\cdot <2>", ["'"] = "<1>'", -- num = "<1>", var = "<1>", fun = "<tt0.funs[o[1]] or o[1]>", }, funs = { ln = "\\ln ", sin = "\\sin ", }, } totex00 = calceasy00 end --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "Ast2.lua" calceasy_grammar() calceasy_alttags() -- optional calceasy_E() -- needed for plic totex = ToText0 { fmts = VTable { num = "<1>", var = "<1>", fun = "<tt.funs[o[1]] or o[1]>", fun = "<1>", ap = "<1> <2>", ["()"] = "(<1>)", }, funs = { }, } = totex:with(E"f(x)") = totex:with(E"f(x)").o = totex:with(E"f(x)").o.o totex:with(E"f(x)"):eval"print'hello'" totex:with(E"f(x)"):eval"print(o)" = totex:with(E"f(x)"):eval"o" = totex:with(E"f(x)"):eval"o[0]" = totex:with(E"f(x)"):eval"tt0.fmts" = totex:with(E"f(x)"):eval"tt:fmt()" = totex:with(E"f(x)"):eval"tt.o" = totex:with(E"f(x)"):eval"tt.o[0]" = totex:with(E"f(x)"):eval"tt:fmt()" = totex:with(E"f(x)"):eval"tt:atn(1)" = totex:with(E"f(x)"):totext() = totex:with(E"f(x)"):eval"tt0.fmts" = ToText { fmts = } = E"f(x)" = E"f(x)"[1] Slogans ["()"] = "(<1>)", ["//"] = "\\frac{<1>}{<2>}", ["^"] = "{<1>}^{<2>}", ["+"] = "<1> + <2>", ["="] = "<1> = <2>", ap = "<1> <2>", mul = "<1> <2>", Mul = "<1> \\cdot <2>", ["'"] = "<1>'", -- num = "<1>", var = "<1>", fun = "<tt.funs[o[1]] or o[1]>", }, -- --]==] -- «Linearize-tests» (to ".Linearize-tests") -- Local Variables: -- coding: utf-8-unix -- End: