/*=============================================================================
    Copyright (c) 2001-2010 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_SCHEME_COMPILER)
#define BOOST_SPIRIT_SCHEME_COMPILER

#include <vector>
#include <map>
#include <exception>

#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/lexical_cast.hpp>
#include <scheme/intrinsics.hpp>
#include <scheme/interpreter.hpp>
#include <input/parse_sexpr.hpp>

namespace scheme
{
///////////////////////////////////////////////////////////////////////////////
//  Exceptions
///////////////////////////////////////////////////////////////////////////////
    struct scheme_exception : std::exception {};

    struct compilation_error : std::exception
    {
        ~compilation_error() throw() {}
        virtual const char* what() const throw()
        {
            return "scheme: Compilation error.";
        }
    };

    struct identifier_expected : scheme_exception
    {
        ~identifier_expected() throw() {}
        virtual const char* what() const throw()
        {
            return "scheme: Identifier expected.";
        }
    };

    struct identifier_not_found : scheme_exception
    {
        std::string msg;
        identifier_not_found(std::string const& id)
          : msg("scheme: Identifier (" + id + ") not found.") {}
        ~identifier_not_found() throw() {}

        virtual const char* what() const throw()
        {
            return msg.c_str();;
        }
    };

    struct duplicate_identifier : scheme_exception
    {
        std::string msg;
        duplicate_identifier(std::string const& id)
          : msg("scheme: Duplicate identifier (" + id + ").") {}
        ~duplicate_identifier() throw() {}

        virtual const char* what() const throw()
        {
            return msg.c_str();
        }
    };

    struct body_already_defined : scheme_exception
    {
        std::string msg;
        body_already_defined(std::string const& id)
          : msg("scheme: Multiple definition (" + id + ").") {}
        ~body_already_defined() throw() {}

        virtual const char* what() const throw()
        {
            return msg.c_str();
        }
    };

    struct incorrect_arity : scheme_exception
    {
        std::string msg;
        incorrect_arity(std::string const& id, int arity, bool fixed)
          : msg("scheme: Invalid number of parameters to function call ("
                + id + ").")
        {
            if (!fixed)
                msg += std::string(" Expecting at least ");
            else
                msg += std::string(" Expecting ");

            msg += boost::lexical_cast<std::string>(arity) + " arguments.";
        }
        ~incorrect_arity() throw() {}

        virtual const char* what() const throw()
        {
            return msg.c_str();
        }
    };

    struct function_application_expected : scheme_exception
    {
        std::string msg;
        function_application_expected(utree const& got)
        {
            // $$$ TODO: add got to message $$$
            msg = "scheme: Function application expected";
        }
        ~function_application_expected() throw() {}

        virtual const char* what() const throw()
        {
            return msg.c_str();
        }
    };

    struct no_body : scheme_exception
    {
        ~no_body() throw() {}
        virtual const char* what() const throw()
        {
            return "scheme: No expression in body.";
        }
    };

///////////////////////////////////////////////////////////////////////////////
//  The environment
///////////////////////////////////////////////////////////////////////////////
    typedef boost::function<function(actor_list const&)> compiled_function;

    class environment
    {
    public:

        environment(environment* parent = 0)
          : outer(parent),
            depth(parent? parent->depth + 1 : 0)
        {}

        template <typename Function>
        void define(std::string const& name, Function const& f, int arity, bool fixed)
        {
            if (definitions.find(name) != definitions.end())
                throw duplicate_identifier(name);
            definitions[name] = boost::make_tuple(compiled_function(f), arity, fixed);
        }

        boost::tuple<compiled_function*, int, bool>
        find(std::string const& name)
        {
            std::map<std::string, map_element>::iterator
                i = definitions.find(name);
            if (i != definitions.end())
                return boost::make_tuple(
                    &boost::get<0>(i->second),
                    boost::get<1>(i->second),
                    boost::get<2>(i->second)
                );
            else if (outer != 0)
                return outer->find(name);
            return boost::make_tuple((compiled_function*)0, 0, false);
        }

        void undefine(std::string const& name)
        {
            definitions.erase(name);
        }

        bool defined(std::string const& name)
        {
            return definitions.find(name) != definitions.end();
        }

        void forward_declare(std::string const& name, function* f)
        {
            forwards[name] = f;
        }

        function* find_forward(std::string const& name)
        {
            std::map<std::string, function*>::iterator
                iter = forwards.find(name);
            if (iter == forwards.end())
                return 0;
            else
                return iter->second;
        }

        environment* parent() const { return outer; }
        int level() const { return depth; }

    private:

        typedef boost::tuple<compiled_function, int, bool> map_element;

        environment* outer;
        std::map<std::string, map_element> definitions;
        std::map<std::string, function*> forwards;
        int depth;
    };

///////////////////////////////////////////////////////////////////////////////
//  The compiler
///////////////////////////////////////////////////////////////////////////////
    function compile(
        utree const& ast,
        environment& env,
        actor_list& fragments,
        int parent_line,
        std::string const& source_file = "");

    struct external_function : composite<external_function>
    {
        // we must hold f by reference because functions can be recursive
        boost::reference_wrapper<function const> f;
        int level;

        external_function(function const& f, int level)
          : f(f), level(level) {}

        using base_type::operator();
        function operator()(actor_list const& elements) const
        {
            return function(lambda_function(f, elements, level));
        }
    };

    struct compiler
    {
        typedef function result_type;
        environment& env;
        actor_list& fragments;
        int line;
        std::string source_file;

        compiler(
            environment& env,
            actor_list& fragments,
            int line,
            std::string const& source_file = "")
          : env(env), fragments(fragments),
            line(line), source_file(source_file)
        {
        }

        function operator()(nil) const
        {
            return scheme::val(utree());
        }

        template <typename T>
        function operator()(T const& val) const
        {
            return scheme::val(utree(val));
        }

        function operator()(utf8_symbol_range const& str) const
        {
            std::string name(str.begin(), str.end());
            boost::tuple<compiled_function*, int, bool> r = env.find(name);
            if (boost::get<0>(r))
            {
                actor_list flist;
                return (*boost::get<0>(r))(flist);
            }
            throw identifier_not_found(name);
            return function();
        }

        function make_lambda(
            std::vector<std::string> const& args,
            bool fixed_arity,
            utree const& body) const
        {
            environment local_env(&this->env);
            for (std::size_t i = 0; i < args.size(); ++i)
            {
                if (!fixed_arity && (args.size() - 1) == i)
                    local_env.define(args[i],
                        boost::bind(varg, i, local_env.level()), 0, false);
                else
                    local_env.define(args[i],
                        boost::bind(arg, i, local_env.level()), 0, false);
            }

            actor_list flist;
            if (body.size() == 0)
                return function();
                //~ throw no_body();

            BOOST_FOREACH(utree const& item, body)
            {
                function f = compile(item, local_env, fragments, line, source_file);
                if (!is_define(item))
                    flist.push_back(f);
            }
            if (flist.size() > 1)
                return protect(block(flist));
            else
                return protect(flist.front());
        }

        static bool is_define(utree const& item)
        {
            if (item.which() != utree_type::list_type ||
                item.begin()->which() != utree_type::symbol_type)
                return false;
            return get_symbol(*item.begin()) == "define";
        }

        function define_function(
            std::string const& name,
            std::vector<std::string>& args,
            bool fixed_arity,
            utree const& body) const
        {
            try
            {
                function* fp = 0;
                if (env.defined(name))
                {
                    fp = env.find_forward(name);
                    if (fp != 0 && !fp->empty())
                        throw body_already_defined(name);
                }

                if (fp == 0)
                {
                    fragments.push_back(function());
                    fp = &fragments.back();
                    env.define(name, external_function(*fp, env.level()), args.size(), fixed_arity);
                }

                function lambda = make_lambda(args, fixed_arity, body);
                if (!lambda.empty())
                {
                    // unprotect (eval returns a function)
                    *fp = lambda();
                }
                else
                {
                    // allow forward declaration of scheme functions
                    env.forward_declare(name, fp);
                }
                return *fp;
            }
            catch (std::exception const&)
            {
                env.undefine(name);
                throw;
            }
        }

        function operator()(utree::const_range const& range) const
        {
            typedef utree::const_range::iterator iterator;

            if (range.begin()->which() != utree_type::symbol_type)
                throw function_application_expected(*range.begin());

            std::string name(get_symbol(*range.begin()));

            if (name == "quote")
            {
                iterator i = range.begin(); ++i;
                return scheme::val(*i);
            }

            if (name == "define")
            {
                std::string fname;
                std::vector<std::string> args;
                bool fixed_arity = true;

                iterator i = range.begin(); ++i;
                if (i->which() == utree_type::list_type)
                {
                    // (define (f x) ...body...)
                    utree const& decl = *i++;
                    iterator di = decl.begin();
                    fname = get_symbol(*di++);
                    while (di != decl.end())
                    {
                        std::string sym = get_symbol(*di++);
                        if (sym == ".")
                           // check that . is one pos behind the last arg
                           fixed_arity = false;
                        else
                            args.push_back(sym);
                    }
                }
                else
                {
                    // (define f ...body...)
                    fname = get_symbol(*i++);

                    // (define f (lambda (x) ...body...))
                    if (i != range.end()
                        && i->which() == utree_type::list_type
                        && get_symbol((*i)[0]) == "lambda")
                    {
                        utree const& arg_names = (*i)[1];
                        iterator ai = arg_names.begin();
                        while (ai != arg_names.end())
                        {
                            std::string sym = get_symbol(*ai++);
                            if (sym == ".")
                                // check that . is one pos behind the last arg
                                fixed_arity = false;
                            else
                                args.push_back(sym);
                        };

                        iterator bi = i->begin(); ++bi; ++bi; // (*i)[2]
                        utree body(utree::const_range(bi, i->end()), shallow);
                        return define_function(fname, args, fixed_arity, body);
                    }
                }

                utree body(utree::const_range(i, range.end()), shallow);
                return define_function(fname, args, fixed_arity, body);
            }

            if (name == "lambda")
            {
                // (lambda (x) ...body...)
                iterator i = range.begin(); ++i;
                utree const& arg_names = *i++;
                iterator ai = arg_names.begin();
                std::vector<std::string> args;
                bool fixed_arity = true;

                while (ai != arg_names.end())
                {
                    std::string sym = get_symbol(*ai++);
                    if (sym == ".")
                        // check that . is one pos behind the last arg
                        fixed_arity = false;
                    else
                        args.push_back(sym);
                }

                utree body(utree::const_range(i, range.end()), shallow);
                return make_lambda(args, fixed_arity, body);
            }

            // (f x)
            boost::tuple<compiled_function*, int, bool> r = env.find(name);
            if (boost::get<0>(r))
            {
                compiled_function* cf = boost::get<0>(r);
                int arity = boost::get<1>(r);
                bool fixed_arity = boost::get<2>(r);

                actor_list flist;
                iterator i = range.begin(); ++i;
                int size = 0;
                for (; i != range.end(); ++i, ++size)
                {
                    flist.push_back(
                        compile(*i, env, fragments, line, source_file));
                }

                // Arity check
                if (!fixed_arity) // non-fixed arity
                {
                    if (size < arity)
                        throw incorrect_arity(name, arity, false);
                }
                else // fixed arity
                {
                    if (size != arity)
                        throw incorrect_arity(name, arity, true);
                }
                return (*cf)(flist);
            }
            else
            {
                throw identifier_not_found(name);
            }

            // Can't reach here
            throw compilation_error();
            return function();
        }

        function operator()(function_base const& pf) const
        {
            // Can't reach here. Surely, at this point, we don't have
            // utree functions yet. The utree AST should be pure data.
            throw compilation_error();
            return function();
        }

        static std::string get_symbol(utree const& s)
        {
            if (s.which() != utree_type::symbol_type)
                throw identifier_expected();
            utf8_symbol_range symbol = s.get<utf8_symbol_range>();
            return std::string(symbol.begin(), symbol.end());
        }
    };

    inline function compile(
        utree const& ast,
        environment& env,
        actor_list& fragments,
        int parent_line,
        std::string const& source_file)
    {
        int line = (ast.which() == utree_type::list_type)
            ? ast.tag() : parent_line;

        try
        {
            return utree::visit(ast,
                compiler(env, fragments, line, source_file));
        }
        catch (scheme_exception const& x)
        {
            if (source_file != "")
                std::cerr << source_file;

            if (line != -1)
                std::cerr << '(' << line << ')';

            std::cerr << " : Error! "  << x.what() << std::endl;
            throw compilation_error();
        }

        return function();
    }

    void compile_all(
        utree const& ast,
        environment& env,
        actor_list& results,
        actor_list& fragments,
        std::string const& source_file = "")
    {
        int line = (ast.which() == utree_type::list_type)
            ? ast.tag() : 1;
        BOOST_FOREACH(utree const& program, ast)
        {
            scheme::function f;
            try
            {
                if (!compiler::is_define(program))
                {
                    if (source_file != "")
                        std::cerr << source_file;

                    int progline = (program.which() == utree_type::list_type)
                        ? program.tag() : line;

                    if (progline != -1)
                        std::cerr << '(' << progline << ')';

                    std::cerr << " : Error! scheme: Function definition expected." << std::endl;
                    continue; // try the next expression
                }
                else
                {
                    f = compile(program, env, fragments, line, source_file);
                }
            }
            catch (compilation_error const&)
            {
                continue; // try the next expression
            }
            results.push_back(f);
        }
    }

    void build_basic_environment(environment& env)
    {
        env.define("if", if_, 3, true);
        env.define("begin", block, 1, false);
        env.define("list", list, 1, false);
        env.define("display", display, 1, true);
        env.define("front", front, 1, true);
        env.define("back", back, 1, true);
        env.define("rest", rest, 1, true);
        env.define("=", equal, 2, true);
        env.define("<", less_than, 2, true);
        env.define("<=", less_than_equal, 2, true);
        env.define("+", plus, 2, false);
        env.define("-", minus, 2, false);
        env.define("*", times, 2, false);
        env.define("/", divide, 2, false);
    }

    ///////////////////////////////////////////////////////////////////////////
    // interpreter
    ///////////////////////////////////////////////////////////////////////////
    struct interpreter
    {
        template <typename Source>
        interpreter(
            Source& in,
            std::string const& source_file = "",
            environment* envp = 0)
        {
            if (envp == 0)
                build_basic_environment(env);
            else
                env = *envp;

            if (input::parse_sexpr_list(in, program, source_file))
            {
                compile_all(program, env, flist, fragments, source_file);
            }
        }

        interpreter(
            utree const& program,
            environment* envp = 0)
        {
            if (envp == 0)
                build_basic_environment(env);
            else
                env = *envp;

            compile_all(program, env, flist, fragments);
        }

        function operator[](std::string const& name)
        {
            boost::tuple<compiled_function*, int, bool> r = env.find(name);
            if (boost::get<0>(r))
            {
                compiled_function* cf = boost::get<0>(r);
                int arity = boost::get<1>(r);
                bool fixed_arity = boost::get<2>(r);
                actor_list flist;

                if (arity > 0)
                {
                    for (int i = 0; i < (arity-1); ++i)
                        flist.push_back(arg(i));

                    if (fixed_arity)
                        flist.push_back(arg(arity-1));
                    else
                        flist.push_back(varg(arity-1));
                }
                return (*cf)(flist);
            }
            else
            {
                std::cerr
                    << " : Error! scheme: Function "
                    << name
                    << " not found."
                    << std::endl;
                return function();
            }
        }

        environment env;
        utree program;
        actor_list fragments;
        actor_list flist;
    };
}

#endif
