-------------------------------------------------------------------------------
-- 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 SUPPORT_IMPROVED_LOOPS   = true
local SUPPORT_IMPROVED_INDEXES = false -- depends on deprecated table.isub
local SUPPORT_CONTINUE         = true
local SUPPORT_COMP_LISTS       = true

assert (SUPPORT_IMPROVED_LOOPS or not SUPPORT_CONTINUE,
        "Can't support 'continue' without improved loop headers")

local gg  = require 'metalua.grammar.generator'
local Q   = require 'metalua.treequery'

local function dots_list_suffix_builder (x) return `DotsSuffix{ x } end

local function for_list_suffix_builder (list_element, suffix)
    local new_header = suffix[1]
    match list_element with
    | `Comp{ _, acc } -> table.insert (acc, new_header); return list_element
    |  _ -> return `Comp{ list_element, { new_header } }
    end
end

local function if_list_suffix_builder (list_element, suffix)
    local new_header = `If{ suffix[1] }
    match list_element with
    | `Comp{ _, acc } -> table.insert (acc, new_header); return list_element
    |  _ -> return `Comp{ list_element, { new_header } }
    end
end

-- Builds a statement from a table element, which adds this element to
-- a table `t`, potentially thanks to an alias `tinsert` to
-- `table.insert`.
-- @param core the part around which the loops are built.
--   either `DotsSuffix{expr}, `Pair{ expr } or a plain expression
-- @param list comprehension suffixes, in the order in which they appear
--   either `Forin{ ... } or `Fornum{ ...} or `If{ ... }. In each case,
--   it misses a last child node as its body.
-- @param t a variable containing the table to fill
-- @param tinsert a variable containing `table.insert`.
--
-- @return fill a statement which fills empty table `t` with the denoted element
local function comp_list_builder(core, list, t, tinsert)
    local filler
    -- 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
    | `DotsSuffix{ element } ->
        local x = gg.gensym()
        filler = +{stat: for _, -{x} in pairs{ -{element} } do (-{tinsert})(-{t}, -{x}) end }
    | `Pair{ key, value } ->
        --filler = +{ -{t}[-{key}] = -{value} }
        filler = `Set{ { `Index{ t, key } }, { value } }
    |  _ -> filler = +{ (-{tinsert})(-{t}, -{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], {filler})
        filler = list[i]
    end

    return filler
end

local function table_content_builder (list)
    local special = false -- Does the table need a special builder?
    for _, element in ipairs(list) do
        local etag = element.tag
        if etag=='Comp' or etag=='DotsSuffix' then special=true; break end
    end
    if not special then list.tag='Table'; return list end

    local t, tinsert = gg.gensym 'table', gg.gensym 'table_insert'
    local filler_block = { +{stat: local -{t}, -{tinsert} = { }, table.insert } }
    for _, element in ipairs(list) do
        local filler
        match element with
        | `Comp{ core, comp } -> filler = comp_list_builder(core, comp, t, tinsert)
        | _ -> filler = comp_list_builder(element, { }, t, tinsert)
        end
        table.insert(filler_block, filler)
    end
    return `Stat{ filler_block, t }
end


--------------------------------------------------------------------------------
-- 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

-------------------------------------------------------------------
-- Find continue statements in a loop body, change them into goto
-- end-of-body.
local function transform_continue_statements(body)
   local continue_statements = Q(body)
       :if_unknown() -- tolerate unknown 'Continue' statements
       :not_under ('Forin', 'Fornum', 'While', 'Repeat')
       :filter ('Continue')
       :list()
   if next(continue_statements) then
       local continue_label = gg.gensym 'continue' [1]
       table.insert(body, `Label{ continue_label })
       for _, statement in ipairs(continue_statements) do
           statement.tag = 'Goto'
           statement[1] = continue_label
       end
       return true
   else return false end
end

-------------------------------------------------------------------------------
-- Back-end for loops with a multi-element header
local function loop_builder(x)
   local first, elements, body = unpack(x)

   -- Change continue statements into gotos.
   if SUPPORT_CONTINUE then transform_continue_statements(body) end

   -------------------------------------------------------------------
   -- If it's a regular loop, don't bloat the code
   if not next(elements) then
      table.insert(first, body)
      return first
   end

   -------------------------------------------------------------------
   -- There's no reason to treat the first element in a special way
   table.insert(elements, 1, first)

   -------------------------------------------------------------------
   -- Change breaks into gotos that escape all loops at once.
   local exit_label = nil
   local function break_to_goto(break_node)
       if not exit_label then exit_label = gg.gensym 'break' [1] end
       break_node = break_node or { }
       break_node.tag = 'Goto'
       break_node[1] = exit_label
       return break_node
   end
   Q(body)
       :not_under('Function', 'Forin', 'Fornum', 'While', 'Repeat')
       :filter('Break')
       :foreach (break_to_goto)

   -------------------------------------------------------------------
   -- Compile all headers elements, from last to first.
   -- invariant: `body` is a block (not a statement)
   local result = body
   for i = #elements, 1, -1 do
      local e = elements[i]
      match e with
      | `If{ cond }    ->
         result = { `If{ cond, result } }
      | `Until{ cond } ->
         result = +{block: if -{cond} then -{break_to_goto()} else -{result} end }
      | `While{ cond } ->
         if i==1 then result = { `While{ cond, result } } -- top-level while
         else result = +{block: if -{cond} then -{result} else -{break_to_goto()} end } end
      | `Forin{ ... } | `Fornum{ ... } ->
         table.insert (e, result); result={e}
      | _-> require'metalua.pprint'.printf("Bad loop header element %s", e)
      end
   end


   -------------------------------------------------------------------
   -- If some breaks had to be changed into gotos, insert the label
   if exit_label then result = { result, `Label{ exit_label } } end

   return result
end


--------------------------------------------------------------------------------
-- Improved "[...]" index operator:
--  * support for multi-indexes ("foo[bar, gnat]")
--  * support for ranges ("foo[bar ... gnat]")
--------------------------------------------------------------------------------
local function extend(M)

    local _M = gg.future(M)

    if SUPPORT_COMP_LISTS then
        -- support for "for" / "if" comprehension suffixes in literal tables
        local original_table_element = M.table.element
        M.table.element = gg.expr{ name="table cell",
                                   primary = original_table_element,
                                   suffix  = { name="table cell suffix",
                                               { "...",                builder = dots_list_suffix_builder },
                                               { "for", _M.for_header, builder = for_list_suffix_builder  },
                                               { "if",  _M.expr,       builder = if_list_suffix_builder   } } }
        M.table.content.builder = table_content_builder
    end

    if SUPPORT_IMPROVED_INDEXES then
        -- Support for ranges and multiple indices in bracket suffixes
        M.expr.suffix:del '['
        M.expr.suffix:add{ name="table index/range",
                           "[", gg.list{
                               gg.sequence { _M.expr, gg.onkeyword{ "...", _M.expr } } ,
                               separators = { ",", ";" } },
                           "]", builder = index_builder }
    end

    if SUPPORT_IMPROVED_LOOPS then
        local original_for_header = M.for_header
        M.stat :del  'for'
        M.stat :del  'while'

        M.loop_suffix = gg.multisequence{
            { 'while',  _M.expr, builder = |x| `Until{ `Op{ 'not', x[1] } } },
            { 'until',  _M.expr, builder = |x| `Until{ x[1] } },
            { 'if',     _M.expr, builder = |x| `If{ x[1] } },
            { 'for',    original_for_header, builder = |x| x[1] } }

        M.loop_suffix_list = gg.list{ _M.loop_suffix, terminators='do' }

        M.stat :add{
            'for', original_for_header, _M.loop_suffix_list, 'do', _M.block, 'end',
            builder = loop_builder }

        M.stat :add{
            'while', _M.expr, _M.loop_suffix_list, 'do', _M.block, 'end',
            builder = |x| loop_builder{ `While{x[1]}, x[2], x[3] } }
    end

    if SUPPORT_CONTINUE then
        M.lexer :add 'continue'
        M.stat :add{ 'continue', builder='Continue' }
    end
end

return extend
