* Overloading for functions gscript

Sun, 29 Mar 2015 23:24:15 +0300

author
cemkalyoncu
date
Sun, 29 Mar 2015 23:24:15 +0300
branch
gscript
changeset 669
6a6aa7868741
parent 668
ae70f10f79fb
child 670
81919e7265ca

* Overloading for functions
- Phase 6: Function call is working

Source/Scripting/Data.h file | annotate | diff | comparison | revisions
Source/Scripting/Embedding.h file | annotate | diff | comparison | revisions
Source/Scripting/Reflection.h file | annotate | diff | comparison | revisions
Source/Scripting/Scripting.cpp file | annotate | diff | comparison | revisions
Source/Scripting/VirtualMachine.cpp file | annotate | diff | comparison | revisions
Source/TMP.h file | annotate | diff | comparison | revisions
--- 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> &parameters) 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> &parameters) 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> &parameters) 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> &parameters) 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> &parameters) 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> &parameters) 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
 	}

mercurial