Skip to content

Commit

Permalink
Added the files.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisferron committed May 8, 2010
0 parents commit aed7da0
Show file tree
Hide file tree
Showing 109 changed files with 16,950 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .dep.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
197 changes: 197 additions & 0 deletions Include/LikeMagic/AbstractTypeSystem.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#pragma once

#include "LikeMagic/Utility/BetterTypeInfo.hpp"
#include "LikeMagic/TypeConv/AbstractTypeConverter.hpp"
#include "LikeMagic/TypeConv/ImplicitConv.hpp"
#include "LikeMagic/SFMO/NullExpr.hpp"
#include "LikeMagic/Utility/FuncPtrTraits.hpp"
#include "LikeMagic/Utility/IsIterator.hpp"
#include "LikeMagic/Utility/StripConst.hpp"
#include "LikeMagic/SFMO/Trampoline.hpp"

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

#include <map>
#include <stdexcept>
#include <string>

namespace LikeMagic {

namespace SFMO {
class AbstractCppObjProxy;
}

namespace Marshaling {
class AbstractMethodset;
class AbstractClass;
}

using LikeMagic::Marshaling::AbstractMethodset;
using LikeMagic::Marshaling::AbstractClass;
using LikeMagic::Utility::BetterTypeInfo;
using namespace LikeMagic::TypeConv;
using namespace LikeMagic::SFMO;
using namespace LikeMagic::Utility;


template <typename T, bool is_abstract=boost::is_abstract<T>::value>
struct DoConv
{
static ExprPtr cref_to_value(ExprPtr from)
{
return Trampoline<T const&, T, ImplicitConvImpl<T const&, T>>::create(from);
}

static ExprPtr value_to_cref(ExprPtr from)
{
return Trampoline<T, T const&, ImplicitConvImpl<T, T const&>>::create(from);
}
};

template <typename T>
struct DoConv<T, true>
{
static ExprPtr cref_to_value(ExprPtr from)
{
throw std::logic_error("Cannot convert " + BetterTypeInfo::create<T>().describe() + " from const ref to value; the type is abstract.");
}

static ExprPtr value_to_cref(ExprPtr from)
{
throw std::logic_error("Cannot convert " + BetterTypeInfo::create<T>().describe() + " from value to const ref; the type is abstract.");
}
};


// The reason why TypeSystem is split into AbstractTypeSystem and
// the concrete RuntimeTypeSystem is that things like class Class
// need to access type system methods, but type system methods in
// turn need to create Class objects, creating a circular dependency.
// One way to break the dependency is to make Class use the abstract
// interface instead of giving it direct access to RuntimeTypeSystem.
// The Factory Pattern is no help here because RuntimeTypeSystem must
// create concrete Class instantiations, not AbstractClass, so it
// would still have needed to include Class.hpp even if it used a factory.


class AbstractTypeSystem
{
private:

ExprPtr search_for_conv(ExprPtr from, BetterTypeInfo from_type, BetterTypeInfo to_type) const;

bool is_ref_to_value_conv(BetterTypeInfo from_type, BetterTypeInfo to_type) const;
bool is_value_to_ref_conv(BetterTypeInfo from_type, BetterTypeInfo to_type) const;
bool is_nullptr_conv(ExprPtr from, BetterTypeInfo to_type) const;
bool is_const_adding_conv(BetterTypeInfo from_type, BetterTypeInfo to_type) const;


template <typename To>
ExprPtr try_conv_impl(ExprPtr from) const
{
std::string error_msg_header = "try_conv from " + from->get_type().describe() + " to " + BetterTypeInfo::create<To>().describe() + ": ";

BetterTypeInfo from_type = from->get_type();
BetterTypeInfo to_type = BetterTypeInfo::create<To>();

typedef typename boost::remove_reference<typename boost::remove_const<To>::type>::type BareTo;

// Don't need to rely on the type converter if no conversion is needed.
// Or can we simply add const modifiers to from_type?
if (from_type == to_type || is_const_adding_conv(from_type, to_type))
{
return from;
}
// Can convert NULL to any pointer type.
else if (is_nullptr_conv(from, to_type))
{
return make_nullexpr<To>();
}
// Reference to value
else if (is_ref_to_value_conv(from_type, to_type))
{
return DoConv<BareTo>::cref_to_value(from);
}
// value to const ref
else if (is_value_to_ref_conv(from_type, to_type))
{
return DoConv<BareTo>::value_to_cref(from);
}
// Else need a type converter
else
{
return search_for_conv(from, from_type, to_type);
}
}


protected:

std::map<BetterTypeInfo, AbstractClass*> classes;
AbstractClass const* unknown_class;

typedef std::map<BetterTypeInfo,
std::map<BetterTypeInfo,
AbstractTypeConverter const*>> ConvMap;

ConvMap converters;

bool has_converter(BetterTypeInfo from, BetterTypeInfo to) const;
AbstractTypeConverter const* get_converter(BetterTypeInfo from, BetterTypeInfo to) const;

bool has_class(BetterTypeInfo type) const;
AbstractClass const* get_class(BetterTypeInfo type) const;

public:

std::vector<BetterTypeInfo> get_registered_types() const;
std::vector<std::string> get_base_names(BetterTypeInfo type) const;
std::string get_class_name(BetterTypeInfo type) const;
std::vector<std::string> get_method_names(BetterTypeInfo type) const;
AbstractCppObjProxy* call(BetterTypeInfo type, std::string method_name, AbstractCppObjProxy* proxy, std::vector<ExprPtr> args) const;
std::vector<BetterTypeInfo> get_arg_types(BetterTypeInfo type, std::string method_name) const;


void add_converter(BetterTypeInfo from, BetterTypeInfo to, AbstractTypeConverter const* conv);

template <typename From, typename To, template <typename From, typename To> class Converter=ImplicitConv>
void add_conv()
{
add_converter(
BetterTypeInfo::create<From>(),
BetterTypeInfo::create<To>(),
new Converter<From, To>);
}

template <typename T>
std::string get_class_name() const
{ return get_class_name(BetterTypeInfo::create<T>()); }

template <typename To>
boost::intrusive_ptr<Expression<To>> try_conv(ExprPtr from) const
{
return reinterpret_cast<Expression<To>*>(try_conv_impl<To>(from).get());
}

private:
template <typename To>
static typename boost::enable_if<boost::is_pointer<To>,
typename boost::intrusive_ptr<Expression<To>>>::type
make_nullexpr()
{
return NullExpr<To>::create();
}

template <typename To>
static typename boost::disable_if<boost::is_pointer<To>,
typename boost::intrusive_ptr<Expression<To>>>::type
make_nullexpr()
{
throw std::logic_error("Tried to convert NULL value to nonpointer type "
+ LikeMagic::Utility::TypeDescr<To>::text());
}

};

}
25 changes: 25 additions & 0 deletions Include/LikeMagic/Backends/Io/API_Io.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "LikeMagic/SFMO/AbstractCppObjProxy.hpp"
#include "LikeMagic/Utility/BetterTypeInfo.hpp"

// Using forward declarations here so that user of IoVM class doesn't
// actually need to include Io headers to create an IoVM object.
struct IoState;
struct CollectorMarker;
typedef CollectorMarker IoObject;
typedef IoObject IoMessage;

namespace LikeMagic { namespace Backends { namespace Io {

using namespace LikeMagic::SFMO;
using namespace LikeMagic::Utility;

bool is_sfmo_obj(IoObject* io_obj);
boost::intrusive_ptr<AbstractExpression> from_script(IoObject* self, IoObject* io_obj, BetterTypeInfo expected_type, AbstractTypeSystem const& type_sys);

IoObject* to_script(IoObject *self, IoObject *locals, IoMessage *m, AbstractCppObjProxy* proxy);

IoMessage* new_message(IoObject* self, std::string name);

}}}
57 changes: 57 additions & 0 deletions Include/LikeMagic/Backends/Io/API_Io_Impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include "LikeMagic/Backends/Io/API_Io.hpp"
#include "LikeMagic/Utility/BetterTypeInfo.hpp"

// This makes it compile under windows. Apparently both "inline" and the
// attribute are required together for it to work.
#define REPLACE_IOINLINE __attribute__((always_inline)) inline

// Note: IoVM.h not the same thing as IoVM.hpp
#include "io/IoVM.h"

#include <io/IoBlock.h>

#include "io/IoState.h"
#include "io/IoNumber.h"
#include "io/IoSeq.h"
#include "io/IoState.h"
#include "io/IoObject.h"
#include "io/IoTag.h"

using namespace std;
using namespace LikeMagic::SFMO;
using namespace LikeMagic::Backends::Io;

extern "C"
{
IoObject* API_io_rawClone(IoObject* proto);
void API_io_free_proxy(IoObject* self);
void API_io_mark(IoObject* self);
IoObject* API_io_proto(IoState* state);
IoObject* API_io_userfunc(IoObject *self, IoObject *locals, IoMessage *m);
}

// Using forward declarations here so that user of IoVM class doesn't
// actually need to include Io headers to create an IoVM object.
struct IoState;
struct CollectorMarker;
typedef CollectorMarker IoObject;

namespace LikeMagic { namespace Backends { namespace Io {

using namespace LikeMagic::SFMO;
using namespace LikeMagic::Utility;

bool is_sfmo_obj(IoObject* io_obj);
boost::intrusive_ptr<AbstractExpression> from_script(IoObject* self, IoObject* io_obj, BetterTypeInfo expected_type);

IoMethodTable* make_io_method_table(std::vector<std::string> method_names);
IoObject* arg_at(IoObject *self, IoObject *locals, IoMessage *m, int pos);
boost::intrusive_ptr<LikeMagic::SFMO::AbstractExpression> arg_at(IoObject *self, IoObject *locals, IoMessage *m, int pos, std::vector<BetterTypeInfo> arg_types);

IoObject* to_script(IoObject *self, IoObject *locals, IoMessage *m, AbstractCppObjProxy* proxy);

IoState* get_io_state(IoObject* self);

}}}
86 changes: 86 additions & 0 deletions Include/LikeMagic/Backends/Io/IoBlock.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#pragma once

#include "LikeMagic/Backends/Io/IoVM.hpp"
#include "LikeMagic/Backends/Io/API_Io.hpp"

#include "LikeMagic/AbstractTypeSystem.hpp"
#include "LikeMagic/SFMO/CppObjProxy.hpp"

#include "LikeMagic/IMarkable.hpp"

#include <tuple>

namespace LikeMagic { namespace Backends { namespace Io {

using LikeMagic::AbstractTypeSystem;
using namespace LikeMagic::SFMO;

class IoBlock : public LikeMagic::IMarkable
{
private:
AbstractTypeSystem const* type_sys;

// The block to activate
IoObject* io_block;

// The target on which to activate the block.
IoObject* io_target;

template <typename T>
AbstractCppObjProxy* make_proxy(T t) const
{
return CppObjProxy<T&>::create(Term<T>::create(t), *type_sys);
}

void add_arg(IoMessage* m, AbstractCppObjProxy* proxy) const;

void add_args(IoMessage* m) const {}

template <typename Arg0, typename... Args>
void add_args(IoMessage* m, Arg0 arg0, Args... args) const
{
add_arg(m, make_proxy(arg0));
add_args(m, args...);
}

IoObject* activate(IoMessage* m) const;

public:
IoBlock();
IoBlock(AbstractTypeSystem const* type_sys_, IoObject* io_block_, IoObject* io_target_);

template <typename... Args>
void operator()(Args... args) const
{
if (type_sys && io_block && io_target)
{
IoMessage* m = new_message(io_target, "foo");
add_args(m, args...);
activate(m);
}
}

template <typename R, typename... Args>
R eval(Args... args) const
{
if (!empty())
{
IoMessage* m = new_message(io_target, "foo");
add_args(m, args...);
IoObject* result = activate(m);
ExprPtr expr = from_script(io_target, result, BetterTypeInfo::create<R>(), *type_sys);
return type_sys->try_conv<R>(expr)->eval();
}
else
{
throw std::logic_error("Tried to eval an empty block.");
}
}

bool empty() const;

virtual void mark() const;
};


}}}
Loading

0 comments on commit aed7da0

Please sign in to comment.