<commit_before>// Copyright (c) 2004 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef OPERATOR_040729_HPP
#define OPERATOR_040729_HPP

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/type_traits/is_same.hpp>
#include <luabind/detail/other.hpp>
#include <luabind/raw_policy.hpp>

#if defined(__GNUC__) && __GNUC__ < 3
# define LUABIND_NO_STRINGSTREAM
#else
# if defined(BOOST_NO_STRINGSTREAM)
#  define LUABIND_NO_STRINGSTREAM
# endif
#endif

#ifdef LUABIND_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif

namespace luabind { namespace detail {

    template<class W, class T> struct unwrap_parameter_type;
    template<class Derived> struct operator_ {};

    struct operator_void_return {};

#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    template<class T>
    inline T const& operator,(T const& x, operator_void_return)
    {
        return x;
    }
#endif

}} // namespace luabind

#include <boost/preprocessor/iteration/iterate.hpp>

namespace luabind { namespace operators {

   #define BOOST_PP_ITERATION_PARAMS_1 (3, \
       (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
   #include BOOST_PP_ITERATE()

}} // namespace luabind::operators

#include <boost/preprocessor/iteration/local.hpp>

namespace luabind {

    template<class Derived>
    struct self_base
    {
        operators::call_operator0<Derived> operator()() const
        {
            return 0;
        }

#define BOOST_PP_LOCAL_MACRO(n) \
        template<BOOST_PP_ENUM_PARAMS(n, class A)> \
        BOOST_PP_CAT(operators::call_operator, n)< \
            Derived \
            BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \
        >\
        operator()( \
            BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \
        ) const \
        { \
            return 0; \
        }

#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
#include BOOST_PP_LOCAL_ITERATE()

    };

    struct self_type : self_base<self_type>
    {
    };

    struct const_self_type : self_base<const_self_type>
    {
    };

namespace detail {

    template<class W, class T>
    struct unwrap_parameter_type
    {
        typedef typename boost::mpl::eval_if<
            boost::is_same<T, self_type>
          , boost::mpl::identity<W&>
          , boost::mpl::eval_if<
                boost::is_same<T, const_self_type>
              , boost::mpl::identity<W const&>
              , unwrap_other<T>
            >
        >::type type;
    };

    template<class Derived, class A, class B>
    struct binary_operator
        : operator_<binary_operator<Derived, A, B> >
    {
        binary_operator(int) {}

        template<class T, class Policies>
        struct apply
        {
            typedef typename unwrap_parameter_type<T, A>::type arg0;
            typedef typename unwrap_parameter_type<T, B>::type arg1;

            static void execute(lua_State* L, arg0 _0, arg1 _1)
            {
                Derived::template apply<arg0, arg1, Policies>::execute(
                    L, _0, _1);
            }
        };

        static char const* name()
        {
            return Derived::name();
        }
    };

    template<class Derived, class A>
    struct unary_operator
        : operator_<unary_operator<Derived, A> >
    {
        unary_operator(int) {}

        template<class T, class Policies>
        struct apply
        {
            typedef typename unwrap_parameter_type<T, A>::type arg0;

            static void execute(lua_State* L, arg0 _0)
            {
                Derived::template apply<arg0, Policies>::execute(L, _0);
            }
        };

        static char const* name()
        {
            return Derived::name();
        }
    };

    template<class Policies>
    inline void operator_result(lua_State* L, operator_void_return, Policies*)
    {
    }

    namespace mpl = boost::mpl;

    template<class T, class Policies>
    inline void operator_result(lua_State* L, T const& x, Policies*)
    {
        typedef typename find_conversion_policy<
            0
          , Policies
        >::type cv_policy;

        typename mpl::apply_wrap2<cv_policy,T,cpp_to_lua>::type cv;

        cv.apply(L, x);
    }

}} // namespace detail::luabind

namespace luabind {

#define LUABIND_BINARY_OPERATOR(name_, op) \
    namespace operators { \
\
        struct name_ \
        { \
            template<class T0, class T1, class Policies> \
            struct apply \
            { \
                static void execute(lua_State* L, T0 _0, T1 _1) \
                { \
                    detail::operator_result(L, _0 op _1, (Policies*)0); \
                } \
            }; \
\
            static char const* name() \
            { \
                return "__" # name_; \
            } \
        }; \
\
    } \
    \
    template<class T, class U> \
    detail::binary_operator< \
        operators::name_ \
      , U \
      , T \
    > \
    inline operator op(self_base<U>, T const&) \
    { \
        return 0; \
    } \
    \
    template<class T, class U> \
    detail::binary_operator< \
        operators::name_ \
      , T \
      , U \
    > \
    inline operator op(T const&, self_base<U>) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , self_type \
      , self_type \
    > \
    inline operator op(self_type, self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , self_type \
      , const_self_type \
    > \
    inline operator op(self_type, const_self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , const_self_type \
      , self_type \
    > \
    inline operator op(const_self_type, self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , const_self_type \
      , const_self_type \
    > \
    inline operator op(const_self_type, const_self_type) \
    { \
        return 0; \
    }

    LUABIND_BINARY_OPERATOR(add, +)
    LUABIND_BINARY_OPERATOR(sub, -)
    LUABIND_BINARY_OPERATOR(mul, *)
    LUABIND_BINARY_OPERATOR(div, /)
    LUABIND_BINARY_OPERATOR(pow, ^)
    LUABIND_BINARY_OPERATOR(lt, <)
    LUABIND_BINARY_OPERATOR(le, <=)
    LUABIND_BINARY_OPERATOR(eq, ==)

#undef LUABIND_BINARY_OPERATOR

#define LUABIND_UNARY_OPERATOR(name_, op, fn) \
    namespace operators { \
\
        struct name_ \
        { \
            template<class T, class Policies> \
            struct apply \
            { \
                static void execute(lua_State* L, T x) \
                { \
                    detail::operator_result(L, op(x), (Policies*)0); \
                } \
            }; \
\
            static char const* name() \
            { \
                return "__" # name_; \
            } \
        }; \
\
    } \
    \
    template<class T> \
    detail::unary_operator< \
        operators::name_ \
      , T \
    > \
    inline fn(self_base<T>) \
    { \
        return 0; \
    }

    template<class T>
    std::string tostring_operator(T const& x)
    {
#ifdef LUABIND_NO_STRINGSTREAM
        std::strstream s;
        s << x << std::ends;
#else
        std::stringstream s;
        s << x;
#endif
        return s.str();
    }

    LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
    LUABIND_UNARY_OPERATOR(unm, -, operator-)

#undef LUABIND_UNARY_OPERATOR

    // defined in operator.cpp
    extern LUABIND_API self_type self;
    extern LUABIND_API const_self_type const_self;
} // namespace luabind

#endif // OPERATOR_040729_HPP
<commit_msg>add % operator.<commit_after>// Copyright (c) 2004 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef OPERATOR_040729_HPP
#define OPERATOR_040729_HPP

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/type_traits/is_same.hpp>
#include <luabind/detail/other.hpp>
#include <luabind/raw_policy.hpp>

#if defined(__GNUC__) && __GNUC__ < 3
# define LUABIND_NO_STRINGSTREAM
#else
# if defined(BOOST_NO_STRINGSTREAM)
#  define LUABIND_NO_STRINGSTREAM
# endif
#endif

#ifdef LUABIND_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif

namespace luabind { namespace detail {

    template<class W, class T> struct unwrap_parameter_type;
    template<class Derived> struct operator_ {};

    struct operator_void_return {};

#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    template<class T>
    inline T const& operator,(T const& x, operator_void_return)
    {
        return x;
    }
#endif

}} // namespace luabind

#include <boost/preprocessor/iteration/iterate.hpp>

namespace luabind { namespace operators {

   #define BOOST_PP_ITERATION_PARAMS_1 (3, \
       (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
   #include BOOST_PP_ITERATE()

}} // namespace luabind::operators

#include <boost/preprocessor/iteration/local.hpp>

namespace luabind {

    template<class Derived>
    struct self_base
    {
        operators::call_operator0<Derived> operator()() const
        {
            return 0;
        }

#define BOOST_PP_LOCAL_MACRO(n) \
        template<BOOST_PP_ENUM_PARAMS(n, class A)> \
        BOOST_PP_CAT(operators::call_operator, n)< \
            Derived \
            BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \
        >\
        operator()( \
            BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \
        ) const \
        { \
            return 0; \
        }

#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
#include BOOST_PP_LOCAL_ITERATE()

    };

    struct self_type : self_base<self_type>
    {
    };

    struct const_self_type : self_base<const_self_type>
    {
    };

namespace detail {

    template<class W, class T>
    struct unwrap_parameter_type
    {
        typedef typename boost::mpl::eval_if<
            boost::is_same<T, self_type>
          , boost::mpl::identity<W&>
          , boost::mpl::eval_if<
                boost::is_same<T, const_self_type>
              , boost::mpl::identity<W const&>
              , unwrap_other<T>
            >
        >::type type;
    };

    template<class Derived, class A, class B>
    struct binary_operator
        : operator_<binary_operator<Derived, A, B> >
    {
        binary_operator(int) {}

        template<class T, class Policies>
        struct apply
        {
            typedef typename unwrap_parameter_type<T, A>::type arg0;
            typedef typename unwrap_parameter_type<T, B>::type arg1;

            static void execute(lua_State* L, arg0 _0, arg1 _1)
            {
                Derived::template apply<arg0, arg1, Policies>::execute(
                    L, _0, _1);
            }
        };

        static char const* name()
        {
            return Derived::name();
        }
    };

    template<class Derived, class A>
    struct unary_operator
        : operator_<unary_operator<Derived, A> >
    {
        unary_operator(int) {}

        template<class T, class Policies>
        struct apply
        {
            typedef typename unwrap_parameter_type<T, A>::type arg0;

            static void execute(lua_State* L, arg0 _0)
            {
                Derived::template apply<arg0, Policies>::execute(L, _0);
            }
        };

        static char const* name()
        {
            return Derived::name();
        }
    };

    template<class Policies>
    inline void operator_result(lua_State* L, operator_void_return, Policies*)
    {
    }

    namespace mpl = boost::mpl;

    template<class T, class Policies>
    inline void operator_result(lua_State* L, T const& x, Policies*)
    {
        typedef typename find_conversion_policy<
            0
          , Policies
        >::type cv_policy;

        typename mpl::apply_wrap2<cv_policy,T,cpp_to_lua>::type cv;

        cv.apply(L, x);
    }

}} // namespace detail::luabind

namespace luabind {

#define LUABIND_BINARY_OPERATOR(name_, op) \
    namespace operators { \
\
        struct name_ \
        { \
            template<class T0, class T1, class Policies> \
            struct apply \
            { \
                static void execute(lua_State* L, T0 _0, T1 _1) \
                { \
                    detail::operator_result(L, _0 op _1, (Policies*)0); \
                } \
            }; \
\
            static char const* name() \
            { \
                return "__" # name_; \
            } \
        }; \
\
    } \
    \
    template<class T, class U> \
    detail::binary_operator< \
        operators::name_ \
      , U \
      , T \
    > \
    inline operator op(self_base<U>, T const&) \
    { \
        return 0; \
    } \
    \
    template<class T, class U> \
    detail::binary_operator< \
        operators::name_ \
      , T \
      , U \
    > \
    inline operator op(T const&, self_base<U>) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , self_type \
      , self_type \
    > \
    inline operator op(self_type, self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , self_type \
      , const_self_type \
    > \
    inline operator op(self_type, const_self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , const_self_type \
      , self_type \
    > \
    inline operator op(const_self_type, self_type) \
    { \
        return 0; \
    } \
    \
    detail::binary_operator< \
        operators::name_ \
      , const_self_type \
      , const_self_type \
    > \
    inline operator op(const_self_type, const_self_type) \
    { \
        return 0; \
    }

    LUABIND_BINARY_OPERATOR(add, +)
    LUABIND_BINARY_OPERATOR(sub, -)
    LUABIND_BINARY_OPERATOR(mul, *)
    LUABIND_BINARY_OPERATOR(div, /)
    LUABIND_BINARY_OPERATOR(mod, %)
    LUABIND_BINARY_OPERATOR(pow, ^)
    LUABIND_BINARY_OPERATOR(lt, <)
    LUABIND_BINARY_OPERATOR(le, <=)
    LUABIND_BINARY_OPERATOR(eq, ==)

#undef LUABIND_BINARY_OPERATOR

#define LUABIND_UNARY_OPERATOR(name_, op, fn) \
    namespace operators { \
\
        struct name_ \
        { \
            template<class T, class Policies> \
            struct apply \
            { \
                static void execute(lua_State* L, T x) \
                { \
                    detail::operator_result(L, op(x), (Policies*)0); \
                } \
            }; \
\
            static char const* name() \
            { \
                return "__" # name_; \
            } \
        }; \
\
    } \
    \
    template<class T> \
    detail::unary_operator< \
        operators::name_ \
      , T \
    > \
    inline fn(self_base<T>) \
    { \
        return 0; \
    }

    template<class T>
    std::string tostring_operator(T const& x)
    {
#ifdef LUABIND_NO_STRINGSTREAM
        std::strstream s;
        s << x << std::ends;
#else
        std::stringstream s;
        s << x;
#endif
        return s.str();
    }

    LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
    LUABIND_UNARY_OPERATOR(unm, -, operator-)

#undef LUABIND_UNARY_OPERATOR

    // defined in operator.cpp
    extern LUABIND_API self_type self;
    extern LUABIND_API const_self_type const_self;
} // namespace luabind

#endif // OPERATOR_040729_HPP
<|endoftext|>


<commit_before>#include "vm.hpp"
#include "process.hpp"
#include "core_image.hpp"
#include "mmc_image.hpp"
#include "defs.hpp"
#include "mmobj.hpp"
#include "prims.hpp"
#include "utils.hpp"
#include "mmc_fun.hpp"
#include <cstdlib>

#define DBG() _log << _log.magenta + _log.bold + "[VM|" << __FUNCTION__ << "] " << _log.normal
#define WARNING() MMLog::warning() << "[VM|" << __FUNCTION__ << "] " << _log.normal
#define ERROR() MMLog::error() << "[VM|" << __FUNCTION__ << "] " << _log.normal

VM::VM(int argc, char** argv, bool online, const char* core_img_filepath)
  : _log(LOG_VM), _argc(argc), _argv(argv), _online(online),
    _core_image(new CoreImage(this, core_img_filepath)), _mmobj(new MMObj(_core_image)) {
}

MMObj* VM::mmobj() {
  return _mmobj;
}

// void VM::dictionary_dump(oop dict) {
//   number size = _mmobj->mm_dictionary_size(dict);

//   DBG() << "  dict vt: " << _mmobj->mm_object_vt(dict) << endl;
//   DBG() << "  dict size: " << size << endl;
//   for (int i = 3; i < (3 + (size*2)); i++) {
//     DBG() << "  [" << i << "]: & " << &((oop*)dict)[i];
//     DBG() << endl;
//     // DBG() << " vt:" << * ((oop**)dict)[i]  << endl;
//   }
// }

// void VM::dump_prime_info() {
//   std::map<std::string, oop> primes = _core_image->get_primes();
//   std::map<std::string, oop>::iterator it;
//   for (it = primes.begin(); it != primes.end(); it++) {
//     if (it->first == "Behavior" || it->first == "Object_Behavior") continue;
//     oop klass = it->second;
//     DBG() << "PRIME " << klass << " name: " << _mmobj->mm_string_cstr(_mmobj->mm_class_name(klass)) << " vt: "
//             << _mmobj->mm_object_vt(klass) << " dict:" << _mmobj->mm_class_dict(klass) << endl;
//     dictionary_dump(_mmobj->mm_class_dict(klass));
//   }
// }

void VM::print_retval(Process* proc, oop retval) {
  int exc;
  DBG() << " ======== the end ======= " << endl;
  oop retval_str = proc->send_0(retval, new_symbol("toString"), &exc);
  DBG() << "RETVAL: " << retval << " => " << _mmobj->mm_string_cstr(proc, retval_str) << endl;
}

void VM::print_error(Process* proc, oop retval) {
  int exc;
  oop retval_str = proc->send_0(retval, new_symbol("toString"), &exc);
  ERROR() << "uncaught exception: " << retval << " => " << _mmobj->mm_string_cstr(proc, retval_str) << endl;
}

Process* VM::init() {
  Process* proc = new Process(this);
  init_primitives(this); //module initialization could execute primitives
  _core_image->load();
  return proc;
}

int VM::remote_repl() {
  Process* proc = init();
  return proc->read_eval_loop();
}

int VM::start() {
  if (_argc != 2) {
    bail("usage: sf-vm <file.mmc>");
  }

  Process* proc = init();

  char* filepath = _argv[1];

  // dump_prime_info();

  oop imod;
  try {
    imod = instantiate_module(proc, filepath, _mmobj->mm_list_new());
  } catch(mm_exception_rewind e) {
    print_error(proc, e.mm_exception);
    return * (int*) (void*) &(e.mm_exception);
  }

  int exc;
  oop retval = proc->run(imod, new_symbol("main"), &exc);
  if (!(exc == 0)) {
    proc->fail(retval);
  } else {
    print_retval(proc, retval);
  }
  return * (int*) (void*) &retval;
}

std::pair<Process*, oop> VM::start_debugger(Process* target) {
  DBG() << "debugger for target: " << target << endl;

  static int debugger_id = 0;

  oop imod;
  Process* dbg_proc = new Process(this, ++debugger_id);
  try {
    imod = instantiate_module(dbg_proc, "idez", _mmobj->mm_list_new());
  } catch(mm_exception_rewind e) {
    ERROR() << "uncaught exception while instantiating debugger module :(" << endl;
    dbg_proc->fail(e.mm_exception);
    // print_retval(e.mm_exception);
    // return * (int*) (void*) &(e.mm_exception);
  }

  oop oop_target_proc = _mmobj->mm_process_new(target, target);
  int exc;
  oop handler = dbg_proc->send_1(imod, new_symbol("debug"), oop_target_proc, &exc);
  if (exc != 0) {
    dbg_proc->fail(handler);
  }
  return std::pair<Process*, oop>(dbg_proc, handler);
}

oop VM::new_symbol(const char* cstr) {
  std::string s = cstr;
  if (_symbols.find(s) == _symbols.end()) {
    _symbols[s] = _mmobj->mm_symbol_new(cstr);
    // DBG() << "Creating new symbol " << cstr << " = " << _symbols[s] << endl;
  } else {
    // DBG() << "returning existing symbol " << cstr << " = " << _symbols[s] << endl;
  }
  return _symbols[s];
}

oop VM::new_symbol(Process* p, oop str) {
  if (!(_mmobj->mm_object_vt(str) == _core_image->get_prime("String"))) {
    WARNING() << " expected String object, got:" << str << endl;
    p->raise("TypeError", "Expecting String");
  }
  return new_symbol(_mmobj->mm_string_cstr(p, str));
}

void VM::register_primitive(std::string name, prim_function_t fun) {
  _primitives[name] = fun;
}

prim_function_t VM::get_primitive(Process* proc, std::string name) {
  DBG() << "VM::get_primitive " << name << endl;
  if (!(_primitives.find(name) != _primitives.end())) {
    ERROR() << "did not find primitive with name:" << name << endl;
    proc->raise("InternalError", (std::string("primitive not found: ") + name).c_str());
  }
  return _primitives[name];
}

oop VM::instantiate_module(Process* proc, const char* name_or_path, oop module_args_list) {
  MMCImage* mmc = new MMCImage(proc, _core_image, name_or_path);
  mmc->load();
  return mmc->instantiate_module(module_args_list);
}

oop VM::get_prime(const char* name) {
  return _core_image->get_prime(name);
}

#include <iostream>
#include <cstdio>
#include <sstream>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;

static
std::string get_compile_fun_json(const char* text, std::list<std::string> vars) {
  ptree pt;
  ptree env;

  for (std::list<std::string>::iterator it = vars.begin(); it != vars.end(); it++) {
    env.push_back(std::make_pair("", *it));
  }

  pt.put ("text", text);
  pt.add_child("env_names",  env);
  std::ostringstream buf;
  write_json (buf, pt, false);
  return buf.str();
}

oop VM::recompile_fun(Process* proc, oop cfun, const char* text, int* exc) {
  std::list<std::string> vars;
  std::stringstream s;
  std::string json = get_compile_fun_json(text, vars);

  s << "python -m pycompiler.compiler recompile-fun '" << json << "'";
  DBG() << "Executing python compiler: " << s.str() << endl;
  *exc = 0;
  if (FILE* p = popen(s.str().c_str(), "r")) {
    boost::iostreams::file_descriptor_source d(fileno(p), boost::iostreams::close_handle);
    boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> pstream(d);
    std::stringstream out;
    out << &pstream;
    std::string data = out.str();

    char* c_data = (char*) calloc(sizeof(char), data.size());
    data.copy(c_data, data.size());

    DBG() << "Done executing python compiler" << endl;
    if (pclose(p) == 0) {
      MMCFunction* mmcf = new MMCFunction(this, _core_image, c_data, data.size());
      oop new_cfun = mmcf->load(proc);
      _mmobj->mm_overwrite_compiled_function(proc, cfun, new_cfun);
      return cfun;
    } else {
      *exc = 1;
      return proc->mm_exception("CompileError", c_data);
    }
  }
  *exc = 1;
  ERROR() << "Could not call python compiler :(" << endl;
  return proc->mm_exception("CompileError", "pipe error: Unable to call compiler");
}

oop VM::compile_fun(Process* proc, const char* text, std::list<std::string> vars, oop cmod, int* exc) {
  std::stringstream s;
  std::string json = get_compile_fun_json(text, vars);

  s << "python -m pycompiler.compiler compile-lambda '" << json << "'";
  DBG() << "Executing python compiler: " << s.str() << endl;

  *exc = 0;
  if (FILE* p = popen(s.str().c_str(), "r")) {
    boost::iostreams::file_descriptor_source d(fileno(p), boost::iostreams::close_handle);
    boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> pstream(d);
    std::stringstream out;
    out << &pstream;
    std::string data = out.str();

    char* c_data = (char*) calloc(sizeof(char), data.size());
    data.copy(c_data, data.size());
    if (pclose(p) == 0) {
      MMCFunction* mmcf = new MMCFunction(this, _core_image, c_data, data.size());
      oop cfun = mmcf->load(proc);
      _mmobj->mm_compiled_function_set_cmod(proc, cfun, cmod);
      return cfun;
    } else {
      *exc = 1;
      return proc->mm_exception("CompileError", c_data);
    }
  }
  *exc = 1;
  ERROR() << "Could not call python compiler :(" << endl;
  return proc->mm_exception("CompileError", "pipe error: Unable to call compiler");
}

void VM::bail(const std::string& msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

void VM::bail() {
  exit(1);
}
<commit_msg>Using remote_repl.mm as debugger module<commit_after>#include "vm.hpp"
#include "process.hpp"
#include "core_image.hpp"
#include "mmc_image.hpp"
#include "defs.hpp"
#include "mmobj.hpp"
#include "prims.hpp"
#include "utils.hpp"
#include "mmc_fun.hpp"
#include <cstdlib>

#define DBG() _log << _log.magenta + _log.bold + "[VM|" << __FUNCTION__ << "] " << _log.normal
#define WARNING() MMLog::warning() << "[VM|" << __FUNCTION__ << "] " << _log.normal
#define ERROR() MMLog::error() << "[VM|" << __FUNCTION__ << "] " << _log.normal

VM::VM(int argc, char** argv, bool online, const char* core_img_filepath)
  : _log(LOG_VM), _argc(argc), _argv(argv), _online(online),
    _core_image(new CoreImage(this, core_img_filepath)), _mmobj(new MMObj(_core_image)) {
}

MMObj* VM::mmobj() {
  return _mmobj;
}

// void VM::dictionary_dump(oop dict) {
//   number size = _mmobj->mm_dictionary_size(dict);

//   DBG() << "  dict vt: " << _mmobj->mm_object_vt(dict) << endl;
//   DBG() << "  dict size: " << size << endl;
//   for (int i = 3; i < (3 + (size*2)); i++) {
//     DBG() << "  [" << i << "]: & " << &((oop*)dict)[i];
//     DBG() << endl;
//     // DBG() << " vt:" << * ((oop**)dict)[i]  << endl;
//   }
// }

// void VM::dump_prime_info() {
//   std::map<std::string, oop> primes = _core_image->get_primes();
//   std::map<std::string, oop>::iterator it;
//   for (it = primes.begin(); it != primes.end(); it++) {
//     if (it->first == "Behavior" || it->first == "Object_Behavior") continue;
//     oop klass = it->second;
//     DBG() << "PRIME " << klass << " name: " << _mmobj->mm_string_cstr(_mmobj->mm_class_name(klass)) << " vt: "
//             << _mmobj->mm_object_vt(klass) << " dict:" << _mmobj->mm_class_dict(klass) << endl;
//     dictionary_dump(_mmobj->mm_class_dict(klass));
//   }
// }

void VM::print_retval(Process* proc, oop retval) {
  int exc;
  DBG() << " ======== the end ======= " << endl;
  oop retval_str = proc->send_0(retval, new_symbol("toString"), &exc);
  DBG() << "RETVAL: " << retval << " => " << _mmobj->mm_string_cstr(proc, retval_str) << endl;
}

void VM::print_error(Process* proc, oop retval) {
  int exc;
  oop retval_str = proc->send_0(retval, new_symbol("toString"), &exc);
  ERROR() << "uncaught exception: " << retval << " => " << _mmobj->mm_string_cstr(proc, retval_str) << endl;
}

Process* VM::init() {
  Process* proc = new Process(this);
  init_primitives(this); //module initialization could execute primitives
  _core_image->load();
  return proc;
}

int VM::remote_repl() {
  Process* proc = init();
  return proc->read_eval_loop();
}

int VM::start() {
  if (_argc != 2) {
    bail("usage: sf-vm <file.mmc>");
  }

  Process* proc = init();

  char* filepath = _argv[1];

  // dump_prime_info();

  oop imod;
  try {
    imod = instantiate_module(proc, filepath, _mmobj->mm_list_new());
  } catch(mm_exception_rewind e) {
    print_error(proc, e.mm_exception);
    return * (int*) (void*) &(e.mm_exception);
  }

  int exc;
  oop retval = proc->run(imod, new_symbol("main"), &exc);
  if (!(exc == 0)) {
    proc->fail(retval);
  } else {
    print_retval(proc, retval);
  }
  return * (int*) (void*) &retval;
}

std::pair<Process*, oop> VM::start_debugger(Process* target) {
  DBG() << "debugger for target: " << target << endl;

  static int debugger_id = 0;

  oop imod;
  Process* dbg_proc = new Process(this, ++debugger_id);
  try {
    imod = instantiate_module(dbg_proc, "remote_repl", _mmobj->mm_list_new());
  } catch(mm_exception_rewind e) {
    ERROR() << "uncaught exception while instantiating debugger module :(" << endl;
    dbg_proc->fail(e.mm_exception);
    // print_retval(e.mm_exception);
    // return * (int*) (void*) &(e.mm_exception);
  }

  oop oop_target_proc = _mmobj->mm_process_new(target, target);
  int exc;
  oop handler = dbg_proc->send_1(imod, new_symbol("debug"), oop_target_proc, &exc);
  if (exc != 0) {
    dbg_proc->fail(handler);
  }
  return std::pair<Process*, oop>(dbg_proc, handler);
}

oop VM::new_symbol(const char* cstr) {
  std::string s = cstr;
  if (_symbols.find(s) == _symbols.end()) {
    _symbols[s] = _mmobj->mm_symbol_new(cstr);
    // DBG() << "Creating new symbol " << cstr << " = " << _symbols[s] << endl;
  } else {
    // DBG() << "returning existing symbol " << cstr << " = " << _symbols[s] << endl;
  }
  return _symbols[s];
}

oop VM::new_symbol(Process* p, oop str) {
  if (!(_mmobj->mm_object_vt(str) == _core_image->get_prime("String"))) {
    WARNING() << " expected String object, got:" << str << endl;
    p->raise("TypeError", "Expecting String");
  }
  return new_symbol(_mmobj->mm_string_cstr(p, str));
}

void VM::register_primitive(std::string name, prim_function_t fun) {
  _primitives[name] = fun;
}

prim_function_t VM::get_primitive(Process* proc, std::string name) {
  DBG() << "VM::get_primitive " << name << endl;
  if (!(_primitives.find(name) != _primitives.end())) {
    ERROR() << "did not find primitive with name:" << name << endl;
    proc->raise("InternalError", (std::string("primitive not found: ") + name).c_str());
  }
  return _primitives[name];
}

oop VM::instantiate_module(Process* proc, const char* name_or_path, oop module_args_list) {
  MMCImage* mmc = new MMCImage(proc, _core_image, name_or_path);
  mmc->load();
  return mmc->instantiate_module(module_args_list);
}

oop VM::get_prime(const char* name) {
  return _core_image->get_prime(name);
}

#include <iostream>
#include <cstdio>
#include <sstream>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>

#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::property_tree::ptree;
using boost::property_tree::read_json;
using boost::property_tree::write_json;

static
std::string get_compile_fun_json(const char* text, std::list<std::string> vars) {
  ptree pt;
  ptree env;

  for (std::list<std::string>::iterator it = vars.begin(); it != vars.end(); it++) {
    env.push_back(std::make_pair("", *it));
  }

  pt.put ("text", text);
  pt.add_child("env_names",  env);
  std::ostringstream buf;
  write_json (buf, pt, false);
  return buf.str();
}

oop VM::recompile_fun(Process* proc, oop cfun, const char* text, int* exc) {
  std::list<std::string> vars;
  std::stringstream s;
  std::string json = get_compile_fun_json(text, vars);

  s << "python -m pycompiler.compiler recompile-fun '" << json << "'";
  DBG() << "Executing python compiler: " << s.str() << endl;
  *exc = 0;
  if (FILE* p = popen(s.str().c_str(), "r")) {
    boost::iostreams::file_descriptor_source d(fileno(p), boost::iostreams::close_handle);
    boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> pstream(d);
    std::stringstream out;
    out << &pstream;
    std::string data = out.str();

    char* c_data = (char*) calloc(sizeof(char), data.size());
    data.copy(c_data, data.size());

    DBG() << "Done executing python compiler" << endl;
    if (pclose(p) == 0) {
      MMCFunction* mmcf = new MMCFunction(this, _core_image, c_data, data.size());
      oop new_cfun = mmcf->load(proc);
      _mmobj->mm_overwrite_compiled_function(proc, cfun, new_cfun);
      return cfun;
    } else {
      *exc = 1;
      return proc->mm_exception("CompileError", c_data);
    }
  }
  *exc = 1;
  ERROR() << "Could not call python compiler :(" << endl;
  return proc->mm_exception("CompileError", "pipe error: Unable to call compiler");
}

oop VM::compile_fun(Process* proc, const char* text, std::list<std::string> vars, oop cmod, int* exc) {
  std::stringstream s;
  std::string json = get_compile_fun_json(text, vars);

  s << "python -m pycompiler.compiler compile-lambda '" << json << "'";
  DBG() << "Executing python compiler: " << s.str() << endl;

  *exc = 0;
  if (FILE* p = popen(s.str().c_str(), "r")) {
    boost::iostreams::file_descriptor_source d(fileno(p), boost::iostreams::close_handle);
    boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_source> pstream(d);
    std::stringstream out;
    out << &pstream;
    std::string data = out.str();

    char* c_data = (char*) calloc(sizeof(char), data.size());
    data.copy(c_data, data.size());
    if (pclose(p) == 0) {
      MMCFunction* mmcf = new MMCFunction(this, _core_image, c_data, data.size());
      oop cfun = mmcf->load(proc);
      _mmobj->mm_compiled_function_set_cmod(proc, cfun, cmod);
      return cfun;
    } else {
      *exc = 1;
      return proc->mm_exception("CompileError", c_data);
    }
  }
  *exc = 1;
  ERROR() << "Could not call python compiler :(" << endl;
  return proc->mm_exception("CompileError", "pipe error: Unable to call compiler");
}

void VM::bail(const std::string& msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

void VM::bail() {
  exit(1);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Rhys Ulerich
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef DESCENDU_SEXP_HPP
#define DESCENDU_SEXP_HPP

#include <cctype>
#include <iostream>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>

#include "optional.hpp"

namespace descendu {

namespace sexp {

// TODO Track line/column as input processed
// TODO Record line/column within each node
// TODO Confirm well-formed and throw informatively if not
// TODO Consider some cheaper sentinel than optional?

// if (node.string) {
//     // Use node.string.value()
// } else {
//     // Use list-like methods on node.
// }
class node : std::vector<node>
{
    typedef std::vector<node> base_type;

public:

    // For string node access
    std::experimental::optional<std::string> string;

    // For list node access
    using base_type::back;
    using base_type::begin;
    using base_type::cbegin;
    using base_type::cend;
    using base_type::emplace_back;
    using base_type::end;
    using base_type::front;
    using base_type::operator[];
    using base_type::pop_back;
    using base_type::size;

    // Construct a string node
    explicit node(const std::string& string)
        : base_type(0)
        , string(string)
    {};

    // Move into a string node
    explicit node(std::string&& string)
        : base_type(0)
        , string(string)
    {};

    // Construct an empty list node
    node()
        : base_type()
        , string()
    {};
};

namespace impl {

// Helper to process C99 and S-expression escapes for parse(...) just below
template<typename InputIt>
std::string& append_maybe_escaped(
    const char c,
    std::string &acc,  // Reference!
    InputIt& next,     // Reference!
    InputIt end,
    const bool quoted)
{
    if (c != '\'') return acc += c;
    if (next == end) throw std::invalid_argument("backslash precedes EOF");
    const char q = *next++;
    switch (q) {
    case 'a': return acc += '\a';
    case 'b': return acc += '\b';
    case 'f': return acc += '\f';
    case 'n': return acc += '\n';
    case 'r': return acc += '\r';
    case 't': return acc += '\t';
    case 'v': return acc += '\v';
    case '\'':
    case '"':
    case '?': return acc += q;
    case 'x':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
        throw new std::logic_error("Escaping via numeric codes unimplemented");
    case '(': case ')': if (quoted) return acc += q;  // Possibly fall through
    }
    throw new std::invalid_argument(std::string("Improper escape \\" + q));
}

} // namespace impl

// Parse zero or more S-expressions in the input returning a list.
// Notice parsed input is wrapped in one additional list.  That is,
//     1) "(foo)(bar)" returned as ((foo)(bar))
//     2) "(foo)"      returned as ((foo))
//     3) "foo"        returned as (foo)
//     4) ""           returned as ()
// as otherwise non-list or trivial inputs problematic.
// Based upon https://en.wikipedia.org/wiki/S-expression#Parsing
// and grotesquely extended to handle different input with checking.
template<typename InputIt>
node parse(InputIt next, InputIt end) {

    node sexp;
    sexp.emplace_back();
    std::string word;
    int level = 0;
    bool in_string = 0;

    while (next != end) {
        const char c = *next++;
        if (std::isspace(c)) {
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
        } else if (c == '(') {
            ++level;
            sexp.emplace_back();
        } else if (c == ')') {
            if (level == 0) {
                throw std::invalid_argument("unopened right parenthesis");
            }
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
            node temp(std::move(sexp.back()));
            sexp.pop_back();
            sexp.back().emplace_back(std::move(temp));
            --level;
        } else if (c == '"') {
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
            for (;;) {
                if (next == end) throw std::invalid_argument("unclosed quote");
                const char q = *next++;
                if (q == '"') break;
                impl::append_maybe_escaped(q, word, next, end, /*quoted*/true);
            }
            sexp.back().emplace_back(std::move(word));
            word.clear();
        } else {
            impl::append_maybe_escaped(c, word, next, end, /*quoted*/false);
            in_string = true;
        }
    }

    if (level != 0) {
        throw std::invalid_argument("unclosed left parenthesis");
    }
    if (in_string) { // Required for final top-level string
        sexp.back().emplace_back(word);
    }
    if (!sexp.size()) {
        throw std::logic_error("sanity failure on size");
    }
    if (sexp.front().string) {
        throw std::logic_error("sanity failure on type");
    }

    return sexp.front();
}

node parse(const std::string& in) {
    return parse(in.cbegin(), in.cend());
}

node parse(std::istream& is) {
    return parse(
        std::istream_iterator<char>(is),
        std::istream_iterator<char>());
}

template<typename OutputIterator>
void copy(const node& sexp, OutputIterator out) {
    if (sexp.string) {
        // TODO Escaping?  Spaces?
        const auto& string = sexp.string.value();
        std::copy(string.cbegin(), string.cend(), out);
    } else {
        *out++ = '(';
        std::size_t count = 0;
        for (const auto& term : sexp) {
            if (count++) {
                *out++ = ' ';
            }
            copy(term, out);
        }
        *out++ = ')';
    }
}

void copy(const node& sexp, std::ostream& os) {
    return copy(sexp, std::ostream_iterator<char>(os));
}

std::string to_string(const node& sexp) {
    std::ostringstream oss;
    std::ostream_iterator<char> it(oss);
    copy(sexp, it);
    return oss.str();
}

} // namespace

} // namespace

#endif
<commit_msg>Add non-functional node_type<commit_after>/*
 * Copyright (C) 2017 Rhys Ulerich
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef DESCENDU_SEXP_HPP
#define DESCENDU_SEXP_HPP

#include <cctype>
#include <iostream>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>

#include "optional.hpp"

namespace descendu {

namespace sexp {

// TODO Track line/column as input processed
// TODO Record line/column within each node
// TODO Confirm well-formed and throw informatively if not
// TODO Consider some cheaper sentinel than optional?

enum struct node_type { invalid=0, list, symbol, string };

// switch (node.type) {
//     case node_type::list:    /* Use list-like methods */ break;
//     case node_type::symbol:  /* Use node.string */       break;
//     case node_type::string:  /* Use node.string */       break;
// }
class node : std::vector<node>
{
    typedef std::vector<node> base_type;

public:

    // Discern which type of data is contained.
    node_type type;

    // For string node access
    std::experimental::optional<std::string> string;

    // For list node access
    using base_type::back;
    using base_type::begin;
    using base_type::cbegin;
    using base_type::cend;
    using base_type::emplace_back;
    using base_type::end;
    using base_type::front;
    using base_type::operator[];
    using base_type::pop_back;
    using base_type::size;

    // Construct a string node
    explicit node(const std::string& string)
        : base_type(0)
        , type(node_type::string)
        , string(string)
    {};

    // Move into a string node
    explicit node(std::string&& string)
        : base_type(0)
        , type(node_type::string)
        , string(string)
    {};

    // Construct an empty list node
    node()
        : base_type()
        , type(node_type::list)
        , string()
    {};
};

namespace impl {

// Helper to process C99 and S-expression escapes for parse(...) just below
template<typename InputIt>
std::string& append_maybe_escaped(
    const char c,
    std::string &acc,  // Reference!
    InputIt& next,     // Reference!
    InputIt end,
    const bool quoted)
{
    if (c != '\'') return acc += c;
    if (next == end) throw std::invalid_argument("backslash precedes EOF");
    const char q = *next++;
    switch (q) {
    case 'a': return acc += '\a';
    case 'b': return acc += '\b';
    case 'f': return acc += '\f';
    case 'n': return acc += '\n';
    case 'r': return acc += '\r';
    case 't': return acc += '\t';
    case 'v': return acc += '\v';
    case '\'':
    case '"':
    case '?': return acc += q;
    case 'x':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
        throw new std::logic_error("Escaping via numeric codes unimplemented");
    case '(': case ')': if (quoted) return acc += q;  // Possibly fall through
    }
    throw new std::invalid_argument(std::string("Improper escape \\" + q));
}

} // namespace impl

// Parse zero or more S-expressions in the input returning a list.
// Notice parsed input is wrapped in one additional list.  That is,
//     1) "(foo)(bar)" returned as ((foo)(bar))
//     2) "(foo)"      returned as ((foo))
//     3) "foo"        returned as (foo)
//     4) ""           returned as ()
// as otherwise non-list or trivial inputs problematic.
// Based upon https://en.wikipedia.org/wiki/S-expression#Parsing
// and grotesquely extended to handle different input with checking.
template<typename InputIt>
node parse(InputIt next, InputIt end) {

    node sexp;
    sexp.emplace_back();
    std::string word;
    int level = 0;
    bool in_string = 0;

    while (next != end) {
        const char c = *next++;
        if (std::isspace(c)) {
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
        } else if (c == '(') {
            ++level;
            sexp.emplace_back();
        } else if (c == ')') {
            if (level == 0) {
                throw std::invalid_argument("unopened right parenthesis");
            }
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
            node temp(std::move(sexp.back()));
            sexp.pop_back();
            sexp.back().emplace_back(std::move(temp));
            --level;
        } else if (c == '"') {
            if (in_string) {
                sexp.back().emplace_back(std::move(word));
                word.clear();
            }
            in_string = false;
            for (;;) {
                if (next == end) throw std::invalid_argument("unclosed quote");
                const char q = *next++;
                if (q == '"') break;
                impl::append_maybe_escaped(q, word, next, end, /*quoted*/true);
            }
            sexp.back().emplace_back(std::move(word));
            word.clear();
        } else {
            impl::append_maybe_escaped(c, word, next, end, /*quoted*/false);
            in_string = true;
        }
    }

    if (level != 0) {
        throw std::invalid_argument("unclosed left parenthesis");
    }
    if (in_string) { // Required for final top-level string
        sexp.back().emplace_back(word);
    }
    if (!sexp.size()) {
        throw std::logic_error("sanity failure on size");
    }
    if (sexp.front().string) {
        throw std::logic_error("sanity failure on type");
    }

    return sexp.front();
}

node parse(const std::string& in) {
    return parse(in.cbegin(), in.cend());
}

node parse(std::istream& is) {
    return parse(
        std::istream_iterator<char>(is),
        std::istream_iterator<char>());
}

template<typename OutputIterator>
void copy(const node& sexp, OutputIterator out) {
    if (sexp.string) {
        // TODO Escaping?  Spaces?
        const auto& string = sexp.string.value();
        std::copy(string.cbegin(), string.cend(), out);
    } else {
        *out++ = '(';
        std::size_t count = 0;
        for (const auto& term : sexp) {
            if (count++) {
                *out++ = ' ';
            }
            copy(term, out);
        }
        *out++ = ')';
    }
}

void copy(const node& sexp, std::ostream& os) {
    return copy(sexp, std::ostream_iterator<char>(os));
}

std::string to_string(const node& sexp) {
    std::ostringstream oss;
    std::ostream_iterator<char> it(oss);
    copy(sexp, it);
    return oss.str();
}

} // namespace

} // namespace

#endif
<|endoftext|>


<commit_before>
#include <cmath>
#include <vector>
#include <cassert>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

namespace {

template<class T>
string as_binary(T num) {
  stringstream s;
  auto num_bits = (sizeof(T) * 8);
  T mask = T(0x1) << (num_bits - 1);
  while (mask > 0) {
    s << ((num & mask) ? "1" : "0");
    mask >>= 1;
  }
  return s.str();
}

template<class Key, class Lit>
size_t reduce_by_key(vector<Key>& keys, vector<Lit>& lits) {
  vector<Key> new_keys;
  vector<Lit> new_lits;
  size_t from = 0;
  while (from < keys.size()) {
    new_keys.push_back(keys[from]);
    auto to = from;
    while (to < keys.size() && keys[to] == keys[from])
      ++to;
    /*
    cout << "Bounds: " << from << " - " << to << endl;
    for (size_t i = from; i < to; ++i) {
      cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
    }
    */
    Lit merged_lit = 0;
    while (from < to) {
      merged_lit |= lits[from];
      ++from;
    }
    new_lits.push_back(merged_lit);
  }
  lits.clear();
  keys.clear();
  lits = move(new_lits);
  keys = move(new_keys);
  assert(keys.size() == lits.size());
  return lits.size();
}

template<class T>
size_t reduce_by_key(vector<T>& values, vector<T>& chids, vector<T>& lits) {
  assert(values.size() == chids.size());
  assert(chids.size() == lits.size());
  auto max = values.size();
  vector<T> new_values;
  vector<T> new_chids;
  vector<T> new_lits;
  size_t from = 0;
  while (from < max) {
    new_values.push_back(values[from]);
    new_chids.push_back(chids[from]);
    auto to = from;
    while (to < max && values[to] == values[from] && chids[to] == chids[from])
      ++to;
    /*
    cout << "Bounds: " << from << " - " << to << endl;
    for (size_t i = from; i < to; ++i) {
      cout << as_binary(values[i]) << as_binary(chids[i])
           << " --> " << as_binary(lits[i]) << endl;
    }
    */
    T merged_lit = 0;
    while (from < to) {
      merged_lit |= lits[from];
      ++from;
    }
    new_lits.push_back(merged_lit);
  }
  values.clear();
  chids.clear();
  lits.clear();
  values = move(new_values);
  chids = move(new_chids);
  lits = move(new_lits);
  assert(values.size() == chids.size());
  assert(chids.size() == lits.size());
  return lits.size();
}

template<class T>
size_t stream_compaction(vector<T>& index, T val = 0) {
  index.erase(remove(begin(index), end(index), val), end(index));
  return index.size();
}

} // namespace <anonymous>

int main() {
  vector<uint32_t> values{10,  7, 22,  6,  7,
                           1,  9, 42,  2,  5,
                          13,  3,  2,  1,  0,
                           1, 18, 18,  3, 13};

  // ### sort rids by value ###
  vector<uint32_t> rids(values.size());
  iota(begin(rids), end(rids), 0);
  for (size_t i = (values.size() - 1); i > 0; --i) {
    for (size_t j = 0; j < i; ++j) {
      if (values[j] > values[j + 1]) {
        // switch values
        auto tmp = values[j];
        values[j] = values[j + 1];
        values[j + 1] = tmp;
        // switch rids
        tmp = rids[j];
        rids[j] = rids[j + 1];
        rids[j + 1] = tmp;
      }
    }
  }
  // for (size_t i = 0; i < values.size(); ++i) {
  //   cout << values[i] << " --> " << rids[i] << endl;
  // }

  // ### produce chuck id literal ###
  vector<uint32_t> chids(values.size());
  vector<uint32_t> lits(values.size());
  for (size_t i = 0; i < values.size(); ++i) {
    chids[i] = rids[i] / 31;
    lits[i]  = 0x1 << (rids[i] % 31);
    lits[i] |= 0x1 << 31;
  }

  // ### merge lit by val chids ###
  // auto prev_size = values.size();
  auto k = reduce_by_key(values, chids, lits);
  /*
  cout << "Reduced from " << prev_size << " to " << k << " values" << endl;
  for (size_t i = 0; i < k; ++i) {
    cout << as_binary(values[i]) << as_binary(chids[i])
         << " --> " << as_binary(lits[i]) << endl;
  }
  */
  /*
  vector<uint64_t> keys(values.size());
  for (size_t i = 0; i < values.size(); ++i) {
    keys[i] = (uint64_t(values[i]) << 32) | chids[i];
  }
  // algorithm: reduce by key
  for (size_t i = 0; i < values.size(); ++i) {
    cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
  }
  auto prev_size = keys.size();
  auto k = reduce_by_key(keys, lits);
  cout << "Reduced from " << prev_size << " to " << k << " values" << endl;
  for (size_t i = 0; i < k; ++i) {
    cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
  }
  // move keys back to values and chids
  for (size_t i = 0; i < keys.size(); ++i) {
    // keys[i] = (uint64_t(values[i]) << 32) | chids[i];
    values[i] = static_cast<uint32_t>(keys[i] >> 32);
    chids[i]  = static_cast<uint32_t>(keys[i]);
  }
  */

  // ### produce fills ###
  vector<uint64_t> heads(k);
  adjacent_difference(begin(values), end(values), begin(heads));
  heads.front() = 1;
  //for (size_t i = 0; i < values.size(); ++i) {
  //  cout << as_binary(keys[i]) << " --> " << heads[i] << endl;
  //}
  for (size_t i = 0; i < k; ++i) {
    if (heads[i] == 0) {
      chids[i] = chids[i] - chids[i] - 1;
    } else {
      chids[i] = chids[i] - 1;
    }
  }

  // ### fuse fill literals ###
  vector<uint32_t> index(2 * k);
  for (size_t i = 0; i < k; ++i) {
    index[2 * i] = chids[i];
    index[2 * i + 1] = lits[i];
  }
  auto idx_length = stream_compaction(index);
  cout << "Created index of length: " << idx_length << endl;

  // ### compute comlumn len ###

}

<commit_msg>Might be complete, probably still has some errors<commit_after>
#include <cmath>
#include <vector>
#include <cassert>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

namespace {

template<class T>
string as_binary(T num) {
  stringstream s;
  auto num_bits = (sizeof(T) * 8);
  T mask = T(0x1) << (num_bits - 1);
  while (mask > 0) {
    s << ((num & mask) ? "1" : "0");
    mask >>= 1;
  }
  return s.str();
}

// Reduce by key for OR operation
/*
template<class Key, class Lit>
size_t reduce_by_key(vector<Key>& keys, vector<Lit>& lits) {
  vector<Key> new_keys;
  vector<Lit> new_lits;
  size_t from = 0;
  while (from < keys.size()) {
    new_keys.push_back(keys[from]);
    auto to = from;
    while (to < keys.size() && keys[to] == keys[from])
      ++to;
    cout << "Bounds: " << from << " - " << to << endl;
    for (size_t i = from; i < to; ++i) {
      cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
    }
    Lit merged_lit = 0;
    while (from < to) {
      merged_lit |= lits[from];
      ++from;
    }
    new_lits.push_back(merged_lit);
  }
  lits.clear();
  keys.clear();
  lits = move(new_lits);
  keys = move(new_keys);
  assert(keys.size() == lits.size());
  return lits.size();
}
*/

template<class T>
size_t reduce_by_key(vector<T>& input, vector<T>& chids, vector<T>& lits) {
  assert(input.size() == chids.size());
  assert(chids.size() == lits.size());
  auto max = input.size();
  vector<T> new_input;
  vector<T> new_chids;
  vector<T> new_lits;
  size_t from = 0;
  while (from < max) {
    new_input.push_back(input[from]);
    new_chids.push_back(chids[from]);
    auto to = from;
    while (to < max && input[to] == input[from] && chids[to] == chids[from])
      ++to;
    /*
    cout << "Bounds: " << from << " - " << to << endl;
    for (size_t i = from; i < to; ++i) {
      cout << as_binary(input[i]) << as_binary(chids[i])
           << " --> " << as_binary(lits[i]) << endl;
    }
    */
    T merged_lit = 0;
    while (from < to) {
      merged_lit |= lits[from];
      ++from;
    }
    new_lits.push_back(merged_lit);
  }
  input.clear();
  chids.clear();
  lits.clear();
  input = move(new_input);
  chids = move(new_chids);
  lits = move(new_lits);
  assert(input.size() == chids.size());
  assert(chids.size() == lits.size());
  return lits.size();
}

// Reduce by key for sum operation
template<class T>
size_t reduce_by_key(vector<T>& keys, vector<T>& vals) {
  vector<T> new_keys;
  vector<T> new_vals;
  size_t from = 0;
  while (from < keys.size()) {
    new_keys.push_back(keys[from]);
    auto to = from;
    while (to < keys.size() && keys[to] == keys[from])
      ++to;
    /*
    cout << "Bounds: " << from << " - " << to << endl;
    for (size_t i = from; i < to; ++i) {
      cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
    }
    */
    T merged_lit = 0;
    while (from < to) {
      merged_lit += vals[from];
      ++from;
    }
    new_vals.push_back(merged_lit);
  }
  vals.clear();
  keys.clear();
  vals = move(new_vals);
  keys = move(new_keys);
  assert(keys.size() == lits.size());
  return vals.size();
}

template<class T>
vector<T> inclusive_scan(const vector<T>& vals) {
  vector<T> results(vals.size());
  results[0] = vals[0];
  for (size_t i = 1; i < vals.size(); ++i) {
    results[i] = results[i - 1] + vals[i];
  }
  return results;
}

template<class T>
size_t stream_compaction(vector<T>& index, T val = 0) {
  index.erase(remove(begin(index), end(index), val), end(index));
  return index.size();
}

} // namespace <anonymous>

int main() {
  vector<uint32_t> values{10,  7, 22,  6,  7,
                           1,  9, 42,  2,  5,
                          13,  3,  2,  1,  0,
                           1, 18, 18,  3, 13};

  auto input = values;

  // ### sort rids by value ###
  vector<uint32_t> rids(input.size());
  iota(begin(rids), end(rids), 0);
  for (size_t i = (input.size() - 1); i > 0; --i) {
    for (size_t j = 0; j < i; ++j) {
      if (input[j] > input[j + 1]) {
        // switch input
        auto tmp = input[j];
        input[j] = input[j + 1];
        input[j + 1] = tmp;
        // switch rids
        tmp = rids[j];
        rids[j] = rids[j + 1];
        rids[j + 1] = tmp;
      }
    }
  }
  // for (size_t i = 0; i < input.size(); ++i) {
  //   cout << input[i] << " --> " << rids[i] << endl;
  // }

  // ### produce chuck id literal ###
  vector<uint32_t> chids(input.size());
  vector<uint32_t> lits(input.size());
  for (size_t i = 0; i < input.size(); ++i) {
    chids[i] = rids[i] / 31;
    lits[i]  = 0x1 << (rids[i] % 31);
    lits[i] |= 0x1 << 31;
  }

  // ### merge lit by val chids ###
  // auto prev_size = input.size();
  auto k = reduce_by_key(input, chids, lits);
  /*
  cout << "Reduced from " << prev_size << " to " << k << " input" << endl;
  for (size_t i = 0; i < k; ++i) {
    cout << as_binary(input[i]) << as_binary(chids[i])
         << " --> " << as_binary(lits[i]) << endl;
  }
  */
  /*
  vector<uint64_t> keys(input.size());
  for (size_t i = 0; i < input.size(); ++i) {
    keys[i] = (uint64_t(input[i]) << 32) | chids[i];
  }
  // algorithm: reduce by key
  for (size_t i = 0; i < input.size(); ++i) {
    cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
  }
  auto prev_size = keys.size();
  auto k = reduce_by_key(keys, lits);
  cout << "Reduced from " << prev_size << " to " << k << " input" << endl;
  for (size_t i = 0; i < k; ++i) {
    cout << as_binary(keys[i]) << " --> " << as_binary(lits[i]) << endl;
  }
  // move keys back to input and chids
  for (size_t i = 0; i < keys.size(); ++i) {
    // keys[i] = (uint64_t(input[i]) << 32) | chids[i];
    input[i] = static_cast<uint32_t>(keys[i] >> 32);
    chids[i]  = static_cast<uint32_t>(keys[i]);
  }
  */

  // ### produce fills ###
  vector<uint64_t> heads(k);
  adjacent_difference(begin(input), end(input), begin(heads));
  heads.front() = 1; // not sure about this one
  //for (size_t i = 0; i < input.size(); ++i) {
  //  cout << as_binary(keys[i]) << " --> " << heads[i] << endl;
  //}
  for (size_t i = 0; i < k; ++i) {
    if (heads[i] == 0) {
      chids[i] = chids[i] - chids[i] - 1;
    } else {
      chids[i] = chids[i] - 1;
    }
  }

  // ### fuse fill literals ###
  vector<uint32_t> index(2 * k);
  for (size_t i = 0; i < k; ++i) {
    index[2 * i] = chids[i];
    index[2 * i + 1] = lits[i];
  }
  auto idx_length = stream_compaction(index, 0u);
  cout << "Created index of length: " << idx_length << endl;

  // ### compute comlumn len ###
  vector<uint32_t> tmp(k);
  for (size_t i = 0; i < k; ++i) {
    tmp[i] = (1 + (chids[i] == 0 ? 0 : 1));
  }
  auto keycnt = reduce_by_key(input, tmp);
  cout << "Created index for values:" << endl;
  for (size_t i = 0; i < values.size(); ++i) {
    cout << "> " << values[i] << endl;
  }
  vector<uint32_t> offsets = inclusive_scan(tmp);

  // Searching for some sensible output format
  for (size_t i = 0; i < keycnt; ++i) {
    auto value = input[i];
    auto length = tmp[i];
    auto offset = offsets[i];
    cout << "Index for value " << value << ":" << endl
         << "> has length " << length << " and offset " << offset << endl;
    //for (size_t j = 0; j < length; ++j) {
    //  cout << "[" << j << "] " << as_binary(index[offset + j]) << endl;
    //}
    //cout << endl;
  }
}

<|endoftext|>


<commit_before>#include "DebuggerTestClient.h"
#include "DebuggerTestHandler.h"

#include <string>
#include <iostream>

#ifdef WIN32
#define sleep(n) Sleep(1000*n)
#endif

namespace zorba {
	int test_run() {
		sleep(8);
		std::cout << "Run Test" << std::endl;
		DebuggerTestClient client("test.xq", "Hello World");
		Sleep(8000);
		client.run();
		DebuggerTestHandler::DebugEvent evt = client.getNextEvent();
		/*if (evt != DebuggerTestHandler::TERMINATED) {
			return -1;
		}*/
		while (evt != DebuggerTestHandler::TERMINATED) {
			evt = client.getNextEvent();
			sleep(1);
		}
		std::string res = client.getQueryResult();
		if (res != "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\nHello World") {
			std::cerr << "Result:" << res << std::endl;
			return -1;
		}
		return 0;
	}
}

int test_debugger_server (int argc, char* argv[]) {
	if (zorba::test_run() != 0) {
		return 1;
	}
	return 0;
}
<commit_msg>fixed the build for unix<commit_after>#include "DebuggerTestClient.h"
#include "DebuggerTestHandler.h"

#include <string>
#include <iostream>

#ifdef WIN32
#define sleep(n) Sleep(1000*n)
#endif

namespace zorba {
	int test_run() {
		sleep(8);
		std::cout << "Run Test" << std::endl;
		DebuggerTestClient client("test.xq", "Hello World");
		sleep(8);
		client.run();
		DebuggerTestHandler::DebugEvent evt = client.getNextEvent();
		/*if (evt != DebuggerTestHandler::TERMINATED) {
			return -1;
		}*/
		while (evt != DebuggerTestHandler::TERMINATED) {
			evt = client.getNextEvent();
			sleep(1);
		}
		std::string res = client.getQueryResult();
		if (res != "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\nHello World") {
			std::cerr << "Result:" << res << std::endl;
			return -1;
		}
		return 0;
	}
}

int test_debugger_server (int argc, char* argv[]) {
	if (zorba::test_run() != 0) {
		return 1;
	}
	return 0;
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <memory>

// allocator:
// template <class... Args> void construct(pointer p, Args&&... args);

#include <memory>
#include <cassert>

#include "test_macros.h"
#include "count_new.hpp"

int A_constructed = 0;

struct A
{
    int data;
    A() {++A_constructed;}

    A(const A&) {++A_constructed;}

    explicit A(int) {++A_constructed;}
    A(int, int*) {++A_constructed;}

    ~A() {--A_constructed;}
};

int move_only_constructed = 0;

#if TEST_STD_VER >= 11
class move_only
{
    move_only(const move_only&) = delete;
    move_only& operator=(const move_only&)= delete;

public:
    move_only(move_only&&) {++move_only_constructed;}
    move_only& operator=(move_only&&) {return *this;}

    move_only() {++move_only_constructed;}
    ~move_only() {--move_only_constructed;}

public:
    int data; // unused other than to make sizeof(move_only) == sizeof(int).
              // but public to suppress "-Wunused-private-field"
};
#endif // TEST_STD_VER >= 11

int main()
{
    {
    std::allocator<A> a;
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(A_constructed == 0);

    globalMemCounter.last_new_size = 0;
    A* ap = a.allocate(3);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
    assert(A_constructed == 0);

    a.construct(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, A());
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, 5);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, 5, (int*)0);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.deallocate(ap, 3);
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(A_constructed == 0);
    }
#if TEST_STD_VER >= 11
    {
    std::allocator<move_only> a;
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(move_only_constructed == 0);

    globalMemCounter.last_new_size = 0;
    move_only* ap = a.allocate(3);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
    assert(move_only_constructed == 0);

    a.construct(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 0);

    a.construct(ap, move_only());
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 0);

    a.deallocate(ap, 3);
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(move_only_constructed == 0);
    }
#endif
}
<commit_msg>avoid new/delete ellision in construct.pass.cpp<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <memory>

// allocator:
// template <class... Args> void construct(pointer p, Args&&... args);

#include <memory>
#include <cassert>

#include "test_macros.h"
#include "count_new.hpp"

int A_constructed = 0;

struct A
{
    int data;
    A() {++A_constructed;}

    A(const A&) {++A_constructed;}

    explicit A(int) {++A_constructed;}
    A(int, int*) {++A_constructed;}

    ~A() {--A_constructed;}
};

int move_only_constructed = 0;

#if TEST_STD_VER >= 11
class move_only
{
    move_only(const move_only&) = delete;
    move_only& operator=(const move_only&)= delete;

public:
    move_only(move_only&&) {++move_only_constructed;}
    move_only& operator=(move_only&&) {return *this;}

    move_only() {++move_only_constructed;}
    ~move_only() {--move_only_constructed;}

public:
    int data; // unused other than to make sizeof(move_only) == sizeof(int).
              // but public to suppress "-Wunused-private-field"
};
#endif // TEST_STD_VER >= 11

int main()
{
    {
    std::allocator<A> a;
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(A_constructed == 0);

    globalMemCounter.last_new_size = 0;
    A* ap = a.allocate(3);
    DoNotOptimize(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
    assert(A_constructed == 0);

    a.construct(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, A());
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, 5);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.construct(ap, 5, (int*)0);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(A_constructed == 0);

    a.deallocate(ap, 3);
    DoNotOptimize(ap);
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(A_constructed == 0);
    }
#if TEST_STD_VER >= 11
    {
    std::allocator<move_only> a;
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(move_only_constructed == 0);

    globalMemCounter.last_new_size = 0;
    move_only* ap = a.allocate(3);
    DoNotOptimize(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
    assert(move_only_constructed == 0);

    a.construct(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 0);

    a.construct(ap, move_only());
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 1);

    a.destroy(ap);
    assert(globalMemCounter.checkOutstandingNewEq(1));
    assert(move_only_constructed == 0);

    a.deallocate(ap, 3);
    DoNotOptimize(ap);
    assert(globalMemCounter.checkOutstandingNewEq(0));
    assert(move_only_constructed == 0);
    }
#endif
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <functional>
#include "Button.h"
#include "Engine.h"
#include "Sprite.h"
#include "EventHander.h"
#include "EventDispatcher.h"
#include "Layer.h"
#include "Utils.h"

namespace ouzel
{
    Button::Button()
    {

    }

    Button::~Button()
    {
        Engine::getInstance()->getEventDispatcher()->removeEventHandler(_eventHandler);
    }

    bool Button::init(const std::string& normal, const std::string& selected, const std::string& pressed, const std::string& disabled, const std::function<void(const VoidPtr&)>& callback)
    {
        _eventHandler = std::make_shared<EventHandler>();

        _eventHandler->mouseDownHandler = std::bind(&Button::handleMouseDown, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->mouseUpHandler = std::bind(&Button::handleMouseUp, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->mouseMoveHandler = std::bind(&Button::handleMouseMove, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchBeginHandler = std::bind(&Button::handleTouchBegin, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchMoveHandler = std::bind(&Button::handleTouchMove, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchEndHandler = std::bind(&Button::handleTouchEnd, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->gamepadButtonChangeHandler = std::bind(&Button::handleGamepadButtonChange, this, std::placeholders::_1, std::placeholders::_2);

        Engine::getInstance()->getEventDispatcher()->addEventHandler(_eventHandler);

        _normalSprite = std::make_shared<Sprite>();
        if (_normalSprite->initFromFile(normal))
        {
            _boundingBox = _normalSprite->getBoundingBox();
            addChild(_normalSprite);
        }

        _selectedSprite = std::make_shared<Sprite>();
        if (_selectedSprite->initFromFile(selected))
        {
            addChild(_selectedSprite);
        }

        _pressedSprite = std::make_shared<Sprite>();
        if (_pressedSprite->initFromFile(pressed))
        {
            addChild(_pressedSprite);
        }

        _disabledSprite = std::make_shared<Sprite>();
        if (_disabledSprite->initFromFile(disabled))
        {
            addChild(_disabledSprite);
        }

        _callback = callback;

        updateSprite();

        return true;
    }

    void Button::setEnabled(bool enabled)
    {
        Widget::setEnabled(enabled);

        _selected = false;
        _pointerOver = false;
        _pressed = false;

        updateSprite();
    }

    bool Button::handleMouseDown(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver)
        {
            _pressed = true;
        }
        updateSprite();

        return true;
    }

    bool Button::handleMouseUp(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver && _pressed)
        {
            if (_callback)
            {
                _callback(shared_from_this());
            }
        }

        _pressed = false;
        updateSprite();

        return true;
    }

    bool Button::handleMouseMove(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);
            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchBegin(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);

            if (_pointerOver)
            {
                _pressed = true;
            }

            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchMove(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);
            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchEnd(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver && _pressed)
        {
            if (_callback)
            {
                _callback(shared_from_this());
            }
        }

        _pressed = false;
        updateSprite();

        return true;
    }

    bool Button::handleGamepadButtonChange(const GamepadEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        return true;
    }

    void Button::checkPointer(const Vector2& worldLocation)
    {
        if (pointOn(worldLocation))
        {
            _pointerOver = true;
        }
        else
        {
            _pointerOver = false;
        }
    }

    void Button::updateSprite()
    {
        if (_normalSprite) _normalSprite->setVisible(false);
        if (_selectedSprite) _selectedSprite->setVisible(false);
        if (_pressedSprite) _pressedSprite->setVisible(false);
        if (_disabledSprite) _disabledSprite->setVisible(false);

        if (_enabled)
        {
            if (_pressed && _pointerOver && _pressedSprite)
            {
                _pressedSprite->setVisible(true);
            }
            else if (_selected && _selectedSprite)
            {
                _selectedSprite->setVisible(true);
            }
            else if (_normalSprite)
            {
                _normalSprite->setVisible(true);
            }
        }
        else if (_disabledSprite)
        {
            _disabledSprite->setVisible(true);
        }
    }
}
<commit_msg>Load only those textures, that are not empty in Button constructor<commit_after>// Copyright (C) 2015 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <functional>
#include "Button.h"
#include "Engine.h"
#include "Sprite.h"
#include "EventHander.h"
#include "EventDispatcher.h"
#include "Layer.h"
#include "Utils.h"

namespace ouzel
{
    Button::Button()
    {

    }

    Button::~Button()
    {
        Engine::getInstance()->getEventDispatcher()->removeEventHandler(_eventHandler);
    }

    bool Button::init(const std::string& normal, const std::string& selected, const std::string& pressed, const std::string& disabled, const std::function<void(const VoidPtr&)>& callback)
    {
        _eventHandler = std::make_shared<EventHandler>();

        _eventHandler->mouseDownHandler = std::bind(&Button::handleMouseDown, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->mouseUpHandler = std::bind(&Button::handleMouseUp, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->mouseMoveHandler = std::bind(&Button::handleMouseMove, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchBeginHandler = std::bind(&Button::handleTouchBegin, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchMoveHandler = std::bind(&Button::handleTouchMove, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->touchEndHandler = std::bind(&Button::handleTouchEnd, this, std::placeholders::_1, std::placeholders::_2);
        _eventHandler->gamepadButtonChangeHandler = std::bind(&Button::handleGamepadButtonChange, this, std::placeholders::_1, std::placeholders::_2);

        Engine::getInstance()->getEventDispatcher()->addEventHandler(_eventHandler);

        if (!normal.empty())
        {
            _normalSprite = std::make_shared<Sprite>();
            if (_normalSprite->initFromFile(normal))
            {
                _boundingBox = _normalSprite->getBoundingBox();
                addChild(_normalSprite);
            }
        }

        if (!selected.empty())
        {
            _selectedSprite = std::make_shared<Sprite>();
            if (_selectedSprite->initFromFile(selected))
            {
                addChild(_selectedSprite);
            }
        }

        if (!pressed.empty())
        {
            _pressedSprite = std::make_shared<Sprite>();
            if (_pressedSprite->initFromFile(pressed))
            {
                addChild(_pressedSprite);
            }
        }

        if (!disabled.empty())
        {
            _disabledSprite = std::make_shared<Sprite>();
            if (_disabledSprite->initFromFile(disabled))
            {
                addChild(_disabledSprite);
            }
        }

        _callback = callback;

        updateSprite();

        return true;
    }

    void Button::setEnabled(bool enabled)
    {
        Widget::setEnabled(enabled);

        _selected = false;
        _pointerOver = false;
        _pressed = false;

        updateSprite();
    }

    bool Button::handleMouseDown(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver)
        {
            _pressed = true;
        }
        updateSprite();

        return true;
    }

    bool Button::handleMouseUp(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver && _pressed)
        {
            if (_callback)
            {
                _callback(shared_from_this());
            }
        }

        _pressed = false;
        updateSprite();

        return true;
    }

    bool Button::handleMouseMove(const MouseEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);
            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchBegin(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);

            if (_pointerOver)
            {
                _pressed = true;
            }

            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchMove(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (LayerPtr layer = _layer.lock())
        {
            Vector2 worldLocation = layer->screenToWorldLocation(event.position);
            checkPointer(worldLocation);
            updateSprite();
        }

        return true;
    }

    bool Button::handleTouchEnd(const TouchEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        if (!_enabled) return true;

        if (_pointerOver && _pressed)
        {
            if (_callback)
            {
                _callback(shared_from_this());
            }
        }

        _pressed = false;
        updateSprite();

        return true;
    }

    bool Button::handleGamepadButtonChange(const GamepadEvent& event, const VoidPtr& sender)
    {
        OUZEL_UNUSED(event);
        OUZEL_UNUSED(sender);

        return true;
    }

    void Button::checkPointer(const Vector2& worldLocation)
    {
        if (pointOn(worldLocation))
        {
            _pointerOver = true;
        }
        else
        {
            _pointerOver = false;
        }
    }

    void Button::updateSprite()
    {
        if (_normalSprite) _normalSprite->setVisible(false);
        if (_selectedSprite) _selectedSprite->setVisible(false);
        if (_pressedSprite) _pressedSprite->setVisible(false);
        if (_disabledSprite) _disabledSprite->setVisible(false);

        if (_enabled)
        {
            if (_pressed && _pointerOver && _pressedSprite)
            {
                _pressedSprite->setVisible(true);
            }
            else if (_selected && _selectedSprite)
            {
                _selectedSprite->setVisible(true);
            }
            else if (_normalSprite)
            {
                _normalSprite->setVisible(true);
            }
        }
        else if (_disabledSprite)
        {
            _disabledSprite->setVisible(true);
        }
    }
}
<|endoftext|>


<commit_before>#ifndef OPTIONAL_H_
#define OPTIONAL_H_

#include <utility>
#include <type_traits>

namespace experimental {

  template <typename T> class optional
    {
      /**
       * \brief The internal storage of size T and
       * properly aligned on T.
       */
      typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;

      /**
       * \brief Indicates whether the storage is
       * initialized.
       */
      bool mStored;

    public:

      /**
       * \brief Object constructor.
       */
      optional() : mStored(false) {}

      /**
       * \constructor.
       * \param v the object to store.
       */
      optional(const T& v) : mStored(true) {
        new (&storage) T(v);
      }

      /**
       * \brief Copy constructor.
       */
      optional(const optional<T>& other)
        : mStored(other.mStored) {
        if (mStored) {
          new (&storage) T(other.get());
        }
      }

      /**
       * \brief Move constructor.
       */
      optional(optional<T>&& other)
        : mStored(other.mStored) {
        if (mStored) {
          new (&storage) T(std::move(other.get()));
        }
      }

      /**
       * \brief Assignment operator.
       */
      optional& operator=(const optional<T>& other) {
        if (this != &other) {
          return (*this);
        }
        if (mStored = other.mStored) {
          new (&storage) T(other.get());
        }
        return (*this);
      }

      /**
       * \brief Move assignment operator.
       */
      optional& operator=(optional<T>&& other) {
        if (this != &other) {
          return (*this);
        }
        if (mStored = other.mStored) {
          new (&storage) T(std::move(other.get()));
        }
        return (*this);
      }

      /**
       * \brief Object destructor.
       */
      ~optional() {
        if (mStored) {
          get().~T();
        }
      }

      /**
       * \return the currently stored optional value.
       * \note This is the const version.
       */
      T const& get() const {
        return *static_cast<const T*>(static_cast<const void*>(&storage));
      }

      /**
       * \return the currently stored optional value.
       * \note This is the non-const version.
       */
      T& get() {
        return *static_cast<T*>(static_cast<void*>(&storage));
      }

      /**
       * \return the currently stored session token if any,
       * an empty string otherwise.
       */
      explicit operator bool() const {
        return (mStored);
      }
    };
};

#endif // OPTIONAL_H_
<commit_msg>Add parenthesis between assignments.<commit_after>#ifndef OPTIONAL_H_
#define OPTIONAL_H_

#include <utility>
#include <type_traits>

namespace experimental {

  template <typename T> class optional
    {
      /**
       * \brief The internal storage of size T and
       * properly aligned on T.
       */
      typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;

      /**
       * \brief Indicates whether the storage is
       * initialized.
       */
      bool mStored;

    public:

      /**
       * \brief Object constructor.
       */
      optional() : mStored(false) {}

      /**
       * \constructor.
       * \param v the object to store.
       */
      optional(const T& v) : mStored(true) {
        new (&storage) T(v);
      }

      /**
       * \brief Copy constructor.
       */
      optional(const optional<T>& other)
        : mStored(other.mStored) {
        if (mStored) {
          new (&storage) T(other.get());
        }
      }

      /**
       * \brief Move constructor.
       */
      optional(optional<T>&& other)
        : mStored(other.mStored) {
        if (mStored) {
          new (&storage) T(std::move(other.get()));
        }
      }

      /**
       * \brief Assignment operator.
       */
      optional& operator=(const optional<T>& other) {
        if (this != &other) {
          return (*this);
        }
        if ((mStored = other.mStored)) {
          new (&storage) T(other.get());
        }
        return (*this);
      }

      /**
       * \brief Move assignment operator.
       */
      optional& operator=(optional<T>&& other) {
        if (this != &other) {
          return (*this);
        }
        if ((mStored = other.mStored)) {
          new (&storage) T(std::move(other.get()));
        }
        return (*this);
      }

      /**
       * \brief Object destructor.
       */
      ~optional() {
        if (mStored) {
          get().~T();
        }
      }

      /**
       * \return the currently stored optional value.
       * \note This is the const version.
       */
      T const& get() const {
        return *static_cast<const T*>(static_cast<const void*>(&storage));
      }

      /**
       * \return the currently stored optional value.
       * \note This is the non-const version.
       */
      T& get() {
        return *static_cast<T*>(static_cast<void*>(&storage));
      }

      /**
       * \return the currently stored session token if any,
       * an empty string otherwise.
       */
      explicit operator bool() const {
        return (mStored);
      }
    };
};

#endif // OPTIONAL_H_
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int main(int argc, char* argv[]) {
	cout << "Hello world!\n";
	return 0;
}<commit_msg>Added sample main routine.<commit_after>/*! \file ibpm2.cc
 *
 * Sample main routine for IBPM code.
 */
#include <iostream>
#include <fstream>

using namespace std;

/*! \brief Setup a timestepper and advance the flow in time
 *  Just a skeleton of this for now.  Eventually this should read parameters
 *  from an input file, do checking for bad input, etc.
 */
int main(int argc, char* argv[]) {
	cout << "Hello world!\n";

	// Setup grid
	int nx = 100;
	int ny = 100;
	double length = 2.0;
	Grid grid(nx, ny, length);

	// Setup geometry
	ifstream infile("geom.inp");
	assert(infile.good());
	Geometry geom;
	geom.load(infile);

	// Setup equations to solve
	double Reynolds=100;
	NonlinearNavierStokes model(grid, geom, Reynolds);
	model.init();

	// Setup timestepper
	dt = 0.01;
	RungeKutta3 solver(model, dt);

	// Load initial condition
	icFile = "initial.bin";
	State x;
	x.loadRestartFile(icFile);

	// Step
	int numSteps = 100;
	for(int i=1; i <= numSteps; ++i) {
		cout << "step " << i << endl;
		solver.advance(x);

		// Add something in here to output force data, probe data,
		// save restart files, etc.
		// Define a Logger class to handle all of this in one place?
	}

	return 0;
}<|endoftext|>