-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit aed7da0
Showing
109 changed files
with
16,950 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
|
||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; | ||
|
||
|
||
}}} |
Oops, something went wrong.