local p={}
local function numberToAZ(num)
local body = ''
local s = tostring(math.floor(tonumber(num)))
for i = 1, mw.ustring.len(s) do
body = body .. mw.ustring.char(tonumber(mw.ustring.sub(s, i, i)) + 65)
end
return body
end
function p.fill_function(in_ftable, final_scope)
for k,v in pairs(in_ftable) do
if type(v) ~= type(function()end) then final_scope['*$'..k]=in_ftable[k]final_scope[k]=function(...)return final_scope['*$'..k]:func(...)end end
end
return final_scope
end
function p.fill_scope(final_scope, math_lib, number_Constructer, debug_flag, calc_func)
for k,v in pairs(final_scope) do if mw.ustring.sub(k,1,2)=="*$" then final_scope[k].local_scopes = final_scope end end
final_scope['^$math_lib']=math_lib
final_scope['^$number_Constructer']=number_Constructer
final_scope['^$debug_flag']=debug_flag
final_scope['^$calc_func']=calc_func
return final_scope
end
function p.function_preload(input_str_o,in_ftable, math_lib, number_Constructer, debug_flag, nocalc_func, just_fix)
local input_str = mw.ustring.gsub(input_str_o,'⇽','←')
if mw.ustring.find(input_str,"↦") then else return input_str end
local old_str = input_str
if just_fix == true or type(math_lib.toTagMath)==type(function()end) then
repeat
old_str = input_str
local repl_named, repl_unnamed = type(math_lib.toTagMath)==type(function()end)and(function(name,vars,contxs,tail)
local func_contx = mw.ustring.format("%s←((%s)⇰(%s))", name,mw.ustring.gsub(vars,',',mw.ustring.char(0x201A)),mw.ustring.gsub(contxs,'[,;]+','∷'))
if mw.text.trim(tail or '')~='' then func_contx = func_contx .. '∷' end
return func_contx
end) or "%1←((%2)⇰(%3))∷",type(math_lib.toTagMath)==type(function()end)and(function(vars,contxs)
return mw.ustring.format("((%s)⇰(%s))⇽",mw.ustring.gsub(vars,',',mw.ustring.char(0x201A)),mw.ustring.gsub(contxs,'[,;]+','∷'))
end) or "((%1)⇰(%2))⇽"
input_str = mw.ustring.gsub(input_str,"(%a+)%s*:([%a%s,]+)↦([^↦:]-);(%s*,?)", repl_named)
input_str = mw.ustring.gsub(input_str,"([%a%s,]+)↦([^↦:]-);",repl_unnamed)
until input_str == old_str
input_str = mw.ustring.gsub(input_str,"⇰","↦")
input_str = mw.ustring.gsub(input_str,"∷",";")
input_str = mw.ustring.gsub(input_str,mw.ustring.char(0x201A),',')
input_str = mw.text.trim(input_str,"\t\r\n\f ⇽")
return input_str
end
local ftable = type(in_ftable) ~= type({"table"}) and {} or in_ftable
local function make_fobj(par,inner)
local n_par = mw.text.trim(mw.ustring.gsub(par,'[%s,;:]+', ','),"\t\r\n\f ,")
local make_obj = {par=mw.text.split(n_par,','),inner=inner}
make_obj.postfix = nocalc_func(inner, math_lib, number_Constructer, debug_flag)
function make_obj:func(...)
local make_args = {...}
local back_up_scope = {}
for i=1,#self.par do if make_args[i] then
back_up_scope[self.par[i]] = self.local_scopes[self.par[i]]
self.local_scopes[self.par[i]] = make_args[i]
end end
if self.local_scopes['^$debug_flag'] == true then mw.log("call "..self.functionName) end
local result = self.local_scopes['^$calc_func'](
self.postfix,
self.local_scopes,
self.local_scopes['^$math_lib'],
self.local_scopes['^$number_Constructer'],
self.local_scopes['^$debug_flag']
)
for i=1,#self.par do if make_args[i] then
self.local_scopes[self.par[i]] = back_up_scope[self.par[i]]
end end
if mw.ustring.find(tostring(result),',') then
result = tostring(result)
local tail_data = mw.text.split(result,',')
for i=#tail_data,1,-1 do result = mw.text.trim(tail_data[i])if result ~= '' then break end end
end
if self.local_scopes['^$debug_flag'] == true then mw.log(self.functionName.." return "..tostring(result)) end
return result
end
return make_obj
end
local function func_repl(par,inner)
ftable[#ftable + 1] = make_fobj(par,inner)
ftable[#ftable].functionName = '#'..#ftable
local func_index = numberToAZ(#ftable)
ftable['function'..func_index] = ftable[#ftable]
return ' function'..func_index..' '
end
local function func_repl_n(name,par,inner)
ftable[name] = make_fobj(par,inner)
ftable[name].functionName = name
return ' '..name..' '
end
repeat
old_str = input_str
input_str = mw.ustring.gsub(input_str,"(%a+)%s*:([%a%s,]+)↦([^↦:]-);",func_repl_n)
input_str = mw.ustring.gsub(input_str,"([%a%s,]+)↦([^↦:]-);",func_repl)
until input_str == old_str
return input_str, ftable
end
p.symbol_table = {
['+'] = { propetry="op", multp = true, count = 2, priority=6, ppriority=6, calc=function(a,b,c,d)return d(a)+d(b) end},
["+ "] = { propetry="op", count = 1, priority=10, ppriority=10, calc=function(a,c,d)return d(a) end},
['-'] = { propetry="op", multp = true, count = 2, priority=6, ppriority=6, calc=function(a,b,c,d)return d(a)-d(b) end},
["- "] = { propetry="op", count = 1, priority=10, ppriority=10, calc=function(a,c,d)return -d(a) end},
['*'] = { propetry="op", multp = true, count = 2, priority=7, ppriority=7, calc=function(a,b,c,d)return d(a)*d(b) end},
["* "] = { propetry="op", count = 1, priority=10, ppriority=10, calc=function(a,c,d) if type(c.conjugate)==type(function()end) then return c.conjugate(d(a))else return d(a)end end},
--隱藏符號的乘法
['⋅'] = { propetry="op", count = 2, priority=7, ppriority=7, calc=function(a,b,c,d)if type(c.mathtimes)==type(function()end) then return c.mathtimes(d(a),d(b)) end return d(a)*d(b)end},
--處理單位的內部符號
['˙'] = { propetry="op", multp = true, count = 2, priority=7, ppriority=7, calc=function(a,b,c,d)if type(c.mathtimes)==type(function()end) then return c.mathtimes(d(a),d(b)) end return d(a)*d(b)end},["˙ "] = { propetry="op", count = 1, priority=10, ppriority=10, calc=function(a,c,d) return d(a) end},
['/'] = { propetry="op", count = 2, priority=7, ppriority=7, calc=function(a,b,c,d)return d(a)/d(b) end},
['%'] = { propetry="op", count = 2, priority=7, ppriority=7, calc=function(a,b,c,d)return d(a)%d(b) end},
['^'] = { propetry="op", count = 2, priority=9, ppriority=8, calc=function(a,b,c,d)return c.pow(d(a),d(b)) end},
[','] = { propetry="op", count = 2, priority=1, ppriority=1, calc=function(c,...) if type(c.mathcomma)==type(function()end) then return c.mathcomma(...) end error("此處不支援此種運算")end },
['='] = { propetry="op", count = 2, priority=3, ppriority=3, calc=function(a,b,c,d)return type(c.matheq)==type(function()end)and c.matheq(d(a),d(b))or d(d(a)==d(b)and 1 or 0)end},
['≠'] = { propetry="op", count = 2, priority=3, priority=3, calc=function(a,b,c,d)return type(c.mathneq)==type(function()end)and c.mathneq(d(a),d(b))or d(d(a)~=d(b)and 1 or 0)end},
['←'] = { propetry="op", count = 2, priority=5, ppriority=5, calc=function(a,b,c,d)return type(c.mathdef)==type(function()end)and c.mathdef(d(a),d(b))or b end},
['⇽'] = { propetry="op", count = 2, priority=9, ppriority=9, calc=function(a,b,c,d)return type(c.mathset)==type(function()end)and c.mathset(d(a),d(b))or b end},
['↦'] = { propetry="op", count = 2, priority=9, ppriority=9, calc=function(a,b,c,d)if type(c.mathmapsto)==type(function()end) then return c.mathmapsto(d(a),d(b)) end error("此處不支援此種運算子")end},
[';'] = { propetry="op", count = 2, priority=1, ppriority=1, calc=function(a,b,c,d)return type(c.mathsemicolon)==type(function()end)and c.mathsemicolon(d(a),d(b))or b end},
['>'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathgt)==type(function()end) then return c.mathgt(d(a),d(b)) end
if c.abs(c.nonRealPart(d(a))) > 1e-14 or c.abs(c.nonRealPart(d(b))) > 1e-14 then return 0 end
return d(c.re(d(a))>c.re(d(b))and 1 or 0)
end},
['<'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathlt)==type(function()end) then return c.mathlt(d(a),d(b)) end
if c.abs(c.nonRealPart(d(a))) > 1e-14 or c.abs(c.nonRealPart(d(b))) > 1e-14 then return 0 end
return d(c.re(d(a))<c.re(d(b))and 1 or 0)
end},
['≥'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathgteq)==type(function()end) then return c.mathgteq(d(a),d(b)) end
if c.abs(c.nonRealPart(d(a))) > 1e-14 or c.abs(c.nonRealPart(d(b))) > 1e-14 then return 0 end
return d(c.re(d(a))>=c.re(d(b))and 1 or 0)
end},
['≤'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathlteq)==type(function()end) then return c.mathlteq(d(a),d(b)) end
if c.abs(c.nonRealPart(d(a))) > 1e-14 or c.abs(c.nonRealPart(d(b))) > 1e-14 then return 0 end
return d(c.re(d(a))<=c.re(d(b))and 1 or 0)
end},
['&'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathand)==type(function()end) then return c.mathand(d(a),d(b)) end
return d(((c.abs(d(a)) > 1e-14) and (c.abs(d(b)) > 1e-14))and 1 or 0)
end},
['|'] = { propetry="op", count = 2, priority=4, ppriority=4, calc=function(a,b,c,d)
if type(c.mathor)==type(function()end) then return c.mathor(d(a),d(b)) end
return d(((c.abs(d(a)) > 1e-14) or (c.abs(d(b)) > 1e-14))and 1 or 0)
end},
['~'] = { propetry="op", count = 1, priority=10, ppriority=10, calc=function(a,c,d)
if type(c.mathnot)==type(function()end) then return c.mathnot(d(a)) end
return d((not(c.abs(d(a)) > 1e-14))and 1 or 0)
end},
}
return p