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

-------------------------------------------------------------------------------
--
-- Summary: metalua parser, miscellaneous utility functions.
--
-------------------------------------------------------------------------------

--------------------------------------------------------------------------------
--
-- Exported API:
-- * [mlp.fget()]
-- * [mlp.id()]
-- * [mlp.opt_id()]
-- * [mlp.id_list()]
-- * [mlp.string()]
-- * [mlp.opt_string()]
-- * [mlp.id2string()]
--
--------------------------------------------------------------------------------

local gg       = require 'metalua.grammar.generator'

-- TODO: replace splice-aware versions with naive ones, move etensions in ./meta

return function(M)
    local _M = gg.future(M)

--[[ metaprog-free versions:
    function M.id(lx)
        if lx:peek().tag~='Id' then gg.parse_error(lx, "Identifier expected")
        else return lx:next() end
    end

    function M.opt_id(lx)
        if lx:peek().tag~='Id' then return lx:next() else return false end
    end

    function M.string(lx)
        if lx:peek().tag~='String' then gg.parse_error(lx, "String expected")
        else return lx:next() end
    end

    function M.opt_string(lx)
        if lx:peek().tag~='String' then return lx:next() else return false end
    end

    --------------------------------------------------------------------------------
    -- Converts an identifier into a string. Hopefully one day it'll handle
    -- splices gracefully, but that proves quite tricky.
    --------------------------------------------------------------------------------
    function M.id2string (id)
        if id.tag == "Id" then id.tag = "String"; return id
        else error ("Identifier expected: "..table.tostring(id, 'nohash')) end
    end
--]]

    --------------------------------------------------------------------------------
    -- Try to read an identifier (possibly as a splice), or return [false] if no
    -- id is found.
    --------------------------------------------------------------------------------
    function M.opt_id (lx)
        local a = lx:peek();
        if lx:is_keyword (a, "-{") then
            local v = M.meta.splice(lx)
            if v.tag ~= "Id" and v.tag ~= "Splice" then
                gg.parse_error(lx, "Bad id splice")
            end
            return v
        elseif a.tag == "Id" then return lx:next()
        else return false end
    end

    --------------------------------------------------------------------------------
    -- Mandatory reading of an id: causes an error if it can't read one.
    --------------------------------------------------------------------------------
    function M.id (lx)
        return M.opt_id (lx) or gg.parse_error(lx,"Identifier expected")
    end

    --------------------------------------------------------------------------------
    -- Common helper function
    --------------------------------------------------------------------------------
    M.id_list = gg.list { primary = _M.id, separators = "," }

    --------------------------------------------------------------------------------
    -- Converts an identifier into a string. Hopefully one day it'll handle
    -- splices gracefully, but that proves quite tricky.
    --------------------------------------------------------------------------------
    function M.id2string (id)
        --print("id2string:", disp.ast(id))
        if id.tag == "Id" then id.tag = "String"; return id
        elseif id.tag == "Splice" then
            error ("id2string on splice not implemented")
            -- Evaluating id[1] will produce `Id{ xxx },
            -- and we want it to produce `String{ xxx }.
            -- The following is the plain notation of:
            -- +{ `String{ `Index{ `Splice{ -{id[1]} }, `Number 1 } } }
            return { tag="String",  { tag="Index", { tag="Splice", id[1] },
                                      { tag="Number", 1 } } }
        else error ("Identifier expected: "..table.tostring(id, 'nohash')) end
    end

    --------------------------------------------------------------------------------
    -- Read a string, possibly spliced, or return an error if it can't
    --------------------------------------------------------------------------------
    function M.string (lx)
        local a = lx:peek()
        if lx:is_keyword (a, "-{") then
            local v = M.meta.splice(lx)
            if v.tag ~= "String" and v.tag ~= "Splice" then
                gg.parse_error(lx,"Bad string splice")
            end
            return v
        elseif a.tag == "String" then return lx:next()
        else error "String expected" end
    end

    --------------------------------------------------------------------------------
    -- Try to read a string, or return false if it can't. No splice allowed.
    --------------------------------------------------------------------------------
    function M.opt_string (lx)
        return lx:peek().tag == "String" and lx:next()
    end

    --------------------------------------------------------------------------------
    -- Chunk reader: block + Eof
    --------------------------------------------------------------------------------
    function M.skip_initial_sharp_comment (lx)
        -- Dirty hack: I'm happily fondling lexer's private parts
        -- FIXME: redundant with lexer:newstream()
        lx :sync()
        local i = lx.src:match ("^#.-\n()", lx.i)
        if i then
            lx.i = i
            lx.column_offset = i
            lx.line = lx.line and lx.line + 1 or 1
        end
    end

    local function chunk (lx)
        if lx:peek().tag == 'Eof' then
            return { } -- handle empty files
        else
            M.skip_initial_sharp_comment (lx)
            local chunk = M.block (lx)
            if lx:peek().tag ~= "Eof" then
                gg.parse_error(lx, "End-of-file expected")
            end
            return chunk
        end
    end

    -- chunk is wrapped in a sequence so that it has a "transformer" field.
    M.chunk = gg.sequence { chunk, builder = unpack }

    return M
end