-------------------------------------------------------------------------------
-- 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 library walks AST to gather information about the identifiers
-- in it. It classifies them between free variables and bound
-- variables, and keeps track of which AST node created a given bound
-- variable occurence.
--
-- walk_id (kind, ast)
--
-- Input:
-- * an AST kind: 'expr', 'stat', 'block', 'expr_list', 'binder_list', 'guess'
-- * an AST of the corresponding kind.
--
-- > string, AST
--
-- Output: a table with two fields, 'bound' and 'free';
-- * free associates the name of each free variable with the list of
--   all its occurences in the AST. That list is never empty.
-- * bound associates each stat or expr binding a new variable with
--   the occurences of that/those new variable(s).
--
-- > { free  = table (string, AST and `Id{ });
-- >   bound = table (AST, table(AST and `Id{ })) }
--
-- How it works
-- ============
-- Walk the tree to:
-- * locate open variables, and keep pointers on them so that they can
--   be alpha converted.
-- * locate variable bindings, so that we can find bound variables
-- * locate bound variables, keep them in association with their
--   binder, again in order to alpha-convert them.
--
-- Special treatments:
-- * `Function `Local `Localrec `Fornum `Forin have binders;
--   `Local takes effect from the next statement, 
--   `Localrec from the current statement,
--   `Function and other statments inside their bodies.
-- * `Repeat has a special scoping rule for its condition.
-- * blocks create temporary scopes
-- * `Splice must stop the walking, so that user code won't be
--   converted
--
-------------------------------------------------------------------------------

-{ extension ('match', ...) }
-- -{ extension ('log', ...) }

require 'metalua.walk'
require 'metalua.walk.scope'

-- variable lists auto-create empty list as values by default.
local varlist_mt = { __index = function (self, key) 
                                  local x={ }; self[key] = x; return x 
                               end }

local function _walk_id (kind, supercfg, ast, ...)

   assert(walk[kind], "Inbalid AST kind selector")
   assert(type(supercfg=='table'), "Config table expected")
   assert(type(ast)=='table', "AST expected")

   local cfg = { expr = { }; block = { }; stat = { } }
   local scope = scope:new()

   local visit_bound_var, visit_free_var
   if not supercfg.id then
      printf("Warning, you're using the id walker without id visitor. "..
             "If you know what you want do to, then you're probably doing "..
             "something else...")
      visit_bound_var = || nil
      visit_free_var  = || nil
   else
      visit_free_var  = supercfg.id.free  or || nil
      visit_bound_var = supercfg.id.bound or || nil
   end

   -----------------------------------------------------------------------------
   -- Check identifiers; add functions parameters to scope
   -----------------------------------------------------------------------------
   function cfg.expr.down(x, ...)
      -- Execute the generic expression walker; if it breaks.
      -- don't do the id walking.
      if supercfg.expr and  supercfg.expr.down then  
         local r = supercfg.expr.down(x, ...)
         if r then return r end
      end
      local parents = {...}
      match x with
      | `Id{ name } ->
         local binder, r = scope.current[name] -- binder :: ast which bound var
         if binder then 
            --$log( 'walk.id found a bound var:', x, binder)
            r = visit_bound_var(x, binder, unpack(parents))
         else 
            --$log( 'walk.id found a free var:', x, scope.current)
            r = visit_free_var(x, unpack(parents))
         end
         if r then return r end
      | `Function{ params, _ } -> scope:push (params, x)
      | `Stat{ block, expr }   -> 
         -------------------------------------------------------------
         -- 'expr' is in the scope of 'block': create the scope and
         -- walk the block 'manually', then prevent automatic walk
         -- by returning 'break'.
         -------------------------------------------------------------
         scope:push()
         for _, stat in ipairs (block) do walk.stat(cfg, stat, x, ...) end 
         walk.expr(cfg, expr, x, unpack(parents))
         scope:pop()
         return 'break'
      | _ -> -- pass
      end

   end

   -----------------------------------------------------------------------------
   -- Close the function scope opened by 'down()'
   -----------------------------------------------------------------------------
   function cfg.expr.up(x, ...)   
      match x with `Function{...} -> scope:pop() | _ -> end
      if supercfg.expr and supercfg.expr.up then supercfg.expr.up(x, ...) end
   end

   -----------------------------------------------------------------------------
   -- Create a new scope and register loop variable[s] in it
   -----------------------------------------------------------------------------
   function cfg.stat.down(x, ...)
      -- Execute the generic statement walker; if it breaks.
      -- don't do the id walking.
      if supercfg.stat and supercfg.stat.down then  
         local r = supercfg.stat.down(x, ...)
         if r then return r end
      end
      match x with
      | `Forin{ vars, ... }    -> scope:push (vars,  x)
      | `Fornum{ var, ... }    -> scope:push ({var}, x)
      | `Localrec{ vars, ... } -> scope:add  (vars,  x)
      | `Repeat{ block, expr } ->
         -------------------------------------------------------------
         -- 'expr' is in the scope of 'block': create the scope and
         -- walk the block 'manually', then prevent automatic walk
         -- by returning 'break'.
         -------------------------------------------------------------
         scope:push() 
         for _, stat in ipairs (block) do walk.stat(cfg, stat, x, ...) end 
         walk.expr(cfg, expr, x, ...)
         scope:pop()
         return 'break'
      | _ -> -- pass
      end
   end

   -----------------------------------------------------------------------------
   -- Close the scopes opened by 'up()'
   -----------------------------------------------------------------------------
   function cfg.stat.up(x, ...)
      match x with
      | `Forin{ ... } | `Fornum{ ... } -> scope:pop() 
      | `Local{ vars, ... }            -> scope:add(vars, x)
      | _                              -> -- pass
      -- `Repeat has no up(), because it 'break's.
      end
      if supercfg.stat and supercfg.stat.up then supercfg.stat.up(x, ...) end
   end

   -----------------------------------------------------------------------------
   -- Create a separate scope for each block
   -----------------------------------------------------------------------------
   function cfg.block.down(x, ...) 
      if supercfg.block and supercfg.block.down then
         local r = supercfg.block.down(x, ...) 
         if r then return r end
      end
      scope:push() 
   end
   function cfg.block.up(x, ...) 
      scope:pop() 
      if supercfg.block and supercfg.block.up then supercfg.block.up(x, ...) end
   end
   cfg.binder = supercfg.binder
   walk[kind](cfg, ast, ...)
end

local mt = { __index = |_,k| |...| _walk_id(k, ...) }
walk_id = setmetatable({ }, mt)
