Difference between revisions of "Module:Calculated table"
(Module for generating tables based on formulas) |
m (Fix bug) |
||
| Line 67: | Line 67: | ||
local formula = arg[i+1] | local formula = arg[i+1] | ||
for j, row in ipairs(calculations) do | for j, row in ipairs(calculations) do | ||
| − | row[(i | + | row[(i+1)/2] = formula({x = j}) |
end | end | ||
i = i + 2 | i = i + 2 | ||
Revision as of 03:40, 1 July 2015
Documentation for this module may be created at Module:Calculated table/doc
local p = {}
-- This is a simple Reverse Polish Notation evaluator.
-- It's not infix because edsrzf is lazy and didn't want to write an infix
-- parser.
-- If you'd like to write one and replace this one, please feel free.
local function evaluate(expr, env)
local stack = {}
local i = 1
while i <= #expr do
local c = expr:sub(i, i)
if c == '*' then
local x = table.remove(stack)
local y = table.remove(stack)
table.insert(stack, x*y)
elseif c == '/' then
local x = table.remove(stack)
local y = table.remove(stack)
table.insert(stack, x/y)
elseif c == '-' then
local x = table.remove(stack)
local y = table.remove(stack)
table.insert(stack, x-y)
elseif c == '+' then
local x = table.remove(stack)
local y = table.remove(stack)
table.insert(stack, x+y)
elseif tonumber(c) then
local match = expr:match("^%d+", i)
i = i + #match - 1 -- We'll add 1 more below
table.insert(stack, tonumber(match))
elseif c:match("%a") then
local match = expr:match("^%a+", i)
i = i + #match - 1 -- We'll add 1 more below
table.insert(stack, env[match])
end
i = i + 1
end
return table.remove(stack)
end
-- eval_func returns a function that evaluates the expression with a given environment.
local function eval_func(expr)
return function(env)
return evaluate(expr, env)
end
end
function p.table(frame)
local i = 4
while i <= #frame.args do
frame.args[i] = eval_func(frame.args[i])
i = i + 2
end
return p._table(frame.args[1], frame.args[2], {style = frame.args.style}, unpack(frame.args, 3))
end
function p._table(base_heading, rows, opts, ...)
local headings = {base_heading}
local calculations = {}
for j = 1, rows do
calculations[j] = {}
end
local i = 1
while i < arg.n do
table.insert(headings, arg[i])
local formula = arg[i+1]
for j, row in ipairs(calculations) do
row[(i+1)/2] = formula({x = j})
end
i = i + 2
end
local result = {"{| "}
local style = opts.style
if style then
table.insert(result, style)
end
table.insert(result, "\n|-\n| ")
for i, heading in ipairs(headings) do
if i > 1 then
table.insert(result, " || ")
end
table.insert(result, heading)
end
for j, row in ipairs(calculations) do
table.insert(result, "\n|-\n| ")
table.insert(result, j)
for i, col in ipairs(row) do
table.insert(result, " || ")
table.insert(result, col)
end
end
table.insert(result, "\n|}")
return table.concat(result)
end
return p