Jump to content
Toggle menu
  • 3.1K articles
  • 4.4K files
  • 18 users
  • 91.5K edits
Ashenzari's Archive
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Calculated table: Difference between revisions

From Ashenzari's Archive
imported>Edsrzf
Module for generating tables based on formulas
 
imported>Edsrzf
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-1)/2] = formula({x = j})
       row[(i+1)/2] = formula({x = j})
     end
     end
     i = i + 2
     i = i + 2

Revision as of 02:40, 1 July 2015

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