#! lua
(getmetatable "").__call = string.format
local j <const> = "%s.%s"
local dir, filetype in require "riscos"
local dump in string
local open in io
local concat in table
local dirtype <const>, apptype <const>, text <const> = 0x1000, 0x2000, 0xfff
local signal <const> = "reading %s"
local push = \ (self, x) self[1+#self] = x end
code = { push = push };

local build, rect, parse, f
parse = \ (x, opt_q)
       if not opt_q then
         print (signal (x))
       end -- if
       local fun, mesg = loadfile (x)
       if (fun) then code:push (fun) end -- if
       end
build = \ (x, opt)
       for leaf, t in dir (x) do
         f = rect[t]
         if f then f (j (x, leaf), opt) end -- if
       end  -- for
      end
rect = {
   [text] = parse;
   [dirtype] = build;
   [apptype] = build;
   }

local getopts = \ (opts)
      if not opts then => false, true, false end
      opt_r = opts:match "^-r[c]$?" or opts:match "^-[c]?r$"
      opt_c = opts:match "^-c[qr]?$" or opts:match "^-[qr]?c$"
      opt_q = opts:match "^-qc?$" or opts:match "^-c?q$"
      => opt_r, opt_c, opt_q
      end

local loadsrc = \ (x, opts)
  local opt_r, opt_c, opt_q = getopts(opts)
  assert (opt_r or opt_c, "Bad option")
  opt_q = opt_q or opt_r
  if not opt_q then
    print (signal (x))
  end -- if
  local target = j (x, "!RunImage")
  local settypelua <const> = "settype %s &18C"
  local t = filetype (x)
  if  not (t == dirtype or t == apptype) then
     error "Directory or application expected" end -- if
 local main = j (x, "main")
 local prelude = j (x, "prelude")
 parse (prelude, opt_q)
 for leaf, tt in dir (x) do
   if  tt == dirtype or tt == apptype then
      local y = j (x, leaf)
      build (y, opt_q)
   end -- if
 end -- for
   parse (main, opt_q)
   local chunk = { } -- table of chunks
   local qfmt <const> = "load %q (...);"
   for i, func in ipairs (code) do
      chunk[i] = qfmt:format (dump (func, true))
   end -- for
  local all = assert (load (concat (chunk)))
  if opt_r then
     pcall (all)
  end -- if
  if opt_c then
   local out <close> = assert (open (target, "wb"))
   out:write (dump (all, true))
   os.execute (settypelua (target))
   if not opt_q then
    print "-------------- done"
   end -- if
  end -- if
  end -- function

loadsrc (arg[1], arg[2])