Sun, 29 Mar 2015 23:24:15 +0300
* Overloading for functions
- Phase 6: Function call is working
--- a/Source/Scripting/Data.h Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/Scripting/Data.h Sun Mar 29 23:24:15 2015 +0300 @@ -61,7 +61,7 @@ } else { if(isreference) - return *data.Get<typename std::remove_reference<T_>::type*>(); + return *data.Get<typename std::remove_const<typename std::remove_reference<T_>::type>::type*>(); else return data.Get<typename std::remove_reference<T_>::type>(); }
--- a/Source/Scripting/Embedding.h Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/Scripting/Embedding.h Sun Mar 29 23:24:15 2015 +0300 @@ -102,9 +102,8 @@ } } }; - - Data GetVariableValue(const std::string &varname); - extern MappedValueType<Data, String::From<Data>, GetVariableValue> Variant; + + extern Type &Variant; template<class F_> class MappedFunction : public Scripting::Function::Variant { @@ -117,12 +116,107 @@ MappedFunction(F_ fn, const Scripting::Type *returntype, Scripting::ParameterList parameters, P_ ...tags) : variant(returntype, std::move(parameters), tags...), fn(fn) { } - + virtual Data Call(bool ismethod, const std::vector<Data> ¶meters) const override { + auto ret=callfn<typename traits::ReturnType>(typename TMP::Generate<traits::Arity>::Type(), parameters); + + if(ismethod) { + if(ret.IsValid()) { + VirtualMachine::Get().GetOutput()<<ret<<std::endl<<std::endl; + + return Data::Invalid(); + } + } + + return ret; + } + + private: + + template<class T_> + struct extractvector { + enum { isvector = false }; + }; + + template<template<class, class> class V_, class T_, class A_> + struct extractvector<V_<T_, A_>> { + enum { isvector = std::is_same<V_<T_, A_>, std::vector<T_, A_>>::value }; + + using inner = T_; + }; + + template<class T_> + struct is_nonconstref { + enum { value = std::is_reference<T_>::value && !std::is_const<typename std::remove_reference<T_>::type>::value }; + }; + + template<class T_> + inline typename std::enable_if< + is_nonconstref<T_>::value, + T_ + >::type castto(const Data &d) const { + ///... do the logic to turn underlying type to T_ + return d.ReferenceValue<T_>(); + } + + template<class T_> + inline typename std::enable_if<!is_nonconstref<T_>::value, T_>::type castto(const Data &d) const { + ///... do the logic to turn underlying type to T_ + return d.GetValue<T_>(); + } + + template<int P_> + typename std::enable_if<!extractvector<param<P_>>::isvector, param<P_>>::type + accumulatevector(const std::vector<Data> ¶meters) const { + Utils::ASSERT_FALSE("Invalid accumulation"); + } + + template<int P_> + typename std::enable_if<extractvector<param<P_>>::isvector, param<P_>>::type + accumulatevector(const std::vector<Data> ¶meters) const { + param<P_> v; + for(unsigned i=P_; i<parameters.size(); i++) { + v.push_back(castto<typename extractvector<param<P_>>::inner>(parameters[i])); + } + + return v; + } + + template<int P_> + inline typename TMP::Choose< + is_nonconstref<param<P_>>::value && !extractvector<param<P_>>::isvector, + std::reference_wrapper<typename std::remove_reference<param<P_>>::type>, + param<P_> + >::Type cast(const std::vector<Data> ¶meters) const { + ASSERT(parameters.size()>P_, "Number of parameters does not match"); + + if(P_==this->parameters.size()-1 && repeatlast) { + ASSERT(extractvector<param<P_>>::isvector, "Repeating parameter should be a vector"); + + return accumulatevector<P_>(parameters); + } + + return castto<param<P_>>(parameters[P_]); + } + + template<class R_, int ...S_> + typename std::enable_if<!std::is_same<R_, void>::value, Data>::type + callfn(TMP::Sequence<S_...>, const std::vector<Data> ¶meters) const { + return Data(returntype, Any( + std::bind(fn, cast<S_>(parameters)...)() + )); + } + + template<class R_, int ...S_> + typename std::enable_if<std::is_same<R_, void>::value, Data>::type + callfn(TMP::Sequence<S_...>, const std::vector<Data> ¶meters) const { + Data ret=Data::Invalid(); + + std::bind(fn, cast<S_>(parameters)...)(); + return Data::Invalid(); } - private: - + template<int P_> void checkparam() { }
--- a/Source/Scripting/Reflection.h Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/Scripting/Reflection.h Sun Mar 29 23:24:15 2015 +0300 @@ -442,11 +442,13 @@ unpacktags(tag); unpacktags(tags...); + + init(); } template<class ...P_> Function(const std::string &name, const std::string &help, const Type *parent, - const Containers::Collection<Variant> &variants, const Containers::Collection<Variant> &methods={} + const Containers::Collection<Variant> &variants, const Containers::Collection<Variant> &methods=Containers::Collection<Variant>() ) : name(name), help(help), parent(parent), Variants(this->variants), Methods(this->methods) {
--- a/Source/Scripting/Scripting.cpp Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/Scripting/Scripting.cpp Sun Mar 29 23:24:15 2015 +0300 @@ -8,10 +8,12 @@ namespace Gorgon { namespace Scripting { - MappedValueType<Data, String::From<Data>, GetVariableValue> Variant = {"Variant", + + Data GetVariableValue(const std::string &varname); + Type &Variant = *new MappedValueType<Data, String::From<Data>, GetVariableValue>("Variant", "This type can contain any type.", Data::Invalid() - }; + ); std::set<std::string, String::CaseInsensitiveLess> KeywordNames;
--- a/Source/Scripting/VirtualMachine.cpp Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/Scripting/VirtualMachine.cpp Sun Mar 29 23:24:15 2015 +0300 @@ -1,7 +1,6 @@ #include "VirtualMachine.h" #include "Exceptions.h" #include "../Scripting.h" -#include "Embedding.h" @@ -10,7 +9,10 @@ namespace Scripting { Containers::Hashmap<std::thread::id, VirtualMachine, &VirtualMachine::getthread> VirtualMachine::activevms; - + + + extern Type &Variant; + VirtualMachine::VirtualMachine(bool automaticreset, std::ostream &out, std::istream &in) : Libraries(libraries), output(&out), input(&in), defoutput(&out), definput(&in), automaticreset(automaticreset), temporaries(256, Data::Invalid())
--- a/Source/TMP.h Sun Mar 29 15:14:31 2015 +0300 +++ b/Source/TMP.h Sun Mar 29 23:24:15 2015 +0300 @@ -68,14 +68,14 @@ /// @cond template<class C_, class R_, class ...Args_> struct FunctionTraits<R_(C_::*)(Args_...)> : - public FunctionTraits<R_(typename std::decay<C_>::type*, Args_...)> + public FunctionTraits<R_(typename std::decay<C_>::type&, Args_...)> { static const bool IsMember = true; }; template<class C_, class R_, class ...Args_> struct FunctionTraits<R_(C_::*)(Args_...) const> : - public FunctionTraits<R_(const typename std::decay<C_>::type*, Args_...)> + public FunctionTraits<R_(const typename std::decay<C_>::type&, Args_...)> { static const bool IsMember = true; }; @@ -117,12 +117,12 @@ /// @cond template<class T1_, class T2_> struct Choose<false, T1_, T2_> { - using Type = T1_; + using Type = T2_; }; template<class T1_, class T2_> struct Choose<true, T1_, T2_> { - using Type = T2_; + using Type = T1_; }; ///@endcond }