-------------------------------------------------------------------------------
-- Copyright (c) 2006-2013 Fabien Fleutot and others.
--
-- All rights reserved.
--
-- This program and the accompanying materials are made available
-- under the terms of the Eclipse Public License v1.0 which
-- accompanies this distribution, and is available at
-- http://www.eclipse.org/legal/epl-v10.html
--
-- This program and the accompanying materials are also made available
-- under the terms of the MIT public license which accompanies this
-- distribution, and is available at http://www.lua.org/license.html
--
-- Contributors:
--     Fabien Fleutot - API and implementation
--
-------------------------------------------------------------------------------
--
-- This extension implements list comprehensions, similar to Haskell and
-- Python syntax, to easily describe lists.
--
-- * x[a ... b] is the list { x[a], x[a+1], ..., x[b] }
-- * { f()..., b } contains all the elements returned by f(), then b
--   (allows to expand list fields other than the last one)
-- * list comprehensions a la python, with "for" and "if" suffixes:
--   {i+10*j for i=1,3 for j=1,3 if i~=j} is { 21, 31, 12, 32, 13, 23 }
--
-------------------------------------------------------------------------------

-{ extension ("match", ...) }

local gg  = require 'metalua.grammar.generator'
local mlp = require 'metalua.compiler.parser'
local mlp_table = require 'metalua.compiler.parser.table'

local function dots_builder (x) return `Dots{ x } end

local function for_builder (x, h)
   match x with
   | `Comp{ _, acc } -> table.insert (acc, h[1]); return x
   | `Pair{ _, _ }   -> error "No explicit key in a for list generator"
   |  _              -> return `Comp{ x, {h[1]} }
   end
end

local function if_builder (x, p)
   match x with
   | `Comp{ _, acc } -> table.insert (acc, `If{ p[1] }); return x
   | `Pair{ _, _ }   -> error "No explicit key in a list guard"
   |  _              -> return `Comp{ x, p[1] }
   end
end

local function comp_builder(core, list, no_unpack)
   -- [ti] = temp var holding table.insert
   -- [v]  = variable holding the table being built
   -- [r]  = the core of the list being built
   local ti, v, r = mlp.gensym "table_insert", mlp.gensym "table"

   -----------------------------------------------------------------------------
   -- 1 - Build the loop's core: if it has suffix "...", every elements of the
   --     multi-return must be inserted, hence the extra [for] loop.
   -----------------------------------------------------------------------------
   match core with
   | `Dots{ x } -> 
      local w = mlp.gensym()
      r = +{stat: for _, -{w} in pairs( -{x} ) do -{ `Call{ ti, v, w } } end }
   | `Pair{ k, w } ->
      r = `Set{ { `Index{ v, k } }, { w } }
   |  _ -> r = `Call{ ti, v, core }
   end

   -----------------------------------------------------------------------------
   -- 2 - Stack the if and for control structures, from outside to inside.
   --     This is done in a destructive way for the elements of [list].
   -----------------------------------------------------------------------------
   for i = #list, 1, -1 do
      table.insert (list[i], {r})
      r = list[i]
   end
   if no_unpack then
      return `Stat{ { `Local{ {ti, v}, { +{table.insert}, `Table} }, r }, v }
   else
      return +{ function() 
                   local -{ti}, -{v} = table.insert, { }
                   -{r}; return unpack(-{v}) 
                end () }
   end
end

local function table_content_builder (list)
   match list with
   | { `Comp{ y, acc } } -> return comp_builder( y, acc, "no unpack")
   | _ ->
      local tables = { `Table }
      local ctable = tables[1]
      local function flush() ctable=`Table; table.insert(tables, ctable) end
      for _, x in pairs(list) do
         match x with
         | `Comp{ y, acc } -> table.insert(ctable, comp_builder(y, acc)); flush()
         | `Dots{ y }      -> table.insert(ctable, y); flush()
         |  _              -> table.insert (ctable, x); 
         end
      end
      match tables with
      | { x } | { x, { } } -> return x
      | _ ->
         if #tables[#tables]==0 then table.remove(tables) end --suppress empty table      
         return `Call{ +{table.cat}, unpack(tables) }
      end
   end
end

mlp_table.field = gg.expr{ name="table cell",
   primary = mlp_table.field,
   suffix  = { name="table cell suffix",
      { "...",                 builder = dots_builder },
      { "for", mlp.for_header, builder = for_builder  },
      { "if",  mlp.expr,       builder = if_builder   } } }

mlp_table.content.builder = table_content_builder

--[[
mlp.stat:add{ "for", gg.expr {
      primary = for_header,
      suffix = {
         { "for", mlp.for_header, builder = for_builder  },
         { "if",  mlp.expr,       builder = if_builder   } } }, 
   "do", mlp.block, "end", builder = for_stat_builder }
--]]

--------------------------------------------------------------------------------
-- Back-end for improved index operator.
--------------------------------------------------------------------------------
local function index_builder(a, suffix)
   match suffix[1] with
   -- Single index, no range: keep the native semantics
   | { { e, false } } -> return `Index{ a, e }
   -- Either a range, or multiple indexes, or both
   | ranges ->
      local r = `Call{ +{table.isub}, a }
      local function acc (x,y) table.insert (r,x); table.insert (r,y) end
      for _, seq in ipairs (ranges) do
         match seq with
         | { e, false } -> acc(e,e)
         | { e, f }     -> acc(e,f)
         end
      end
      return r
   end
end

--------------------------------------------------------------------------------
-- Improved "[...]" index operator:
--  * support for multi-indexes ("foo[bar, gnat]")
--  * support for ranges ("foo[bar ... gnat]")
--------------------------------------------------------------------------------
mlp.expr.suffix:del '['
mlp.expr.suffix:add{ name="table index/range",
   "[", gg.list{
      gg.sequence { mlp.expr, gg.onkeyword{ "...", mlp.expr } } , 
      separators = { ",", ";" } }, 
   "]", builder = index_builder }
