private static DynValue ___eq(ScriptExecutionContext context, CallbackArguments args) { T lhs; DynValue rhs; { //Raw get and nullchecks DynValue r_lhs = args.RawGet(0, true); DynValue r_rhs = args.RawGet(1, true); if (r_lhs.IsNil() || r_rhs.IsNil()) { return(DynValue.False); } //Make sure lhs is a proper T { LuaEnumProxy <T> holder; if (r_lhs.Type == DataType.UserData && r_lhs.UserData.TryGet(out holder)) { rhs = r_rhs; } else if (r_rhs.Type == DataType.UserData && r_rhs.UserData.TryGet(out holder)) { rhs = r_lhs; } else { return(DynValue.False); } lhs = holder.value; } } //Test T against rhs if (rhs.Type == DataType.Number) { return(DynValue.NewBoolean(lhs.Equals(Enum.ToObject(typeof(T), (int)rhs.Number)))); } if (rhs.Type == DataType.String) { return(DynValue.NewBoolean(lhs.Equals(Enum.Parse(typeof(T), rhs.String)))); } if (rhs.Type == DataType.UserData) { LuaEnumProxy <T> t2; if (rhs.UserData.TryGet(out t2)) { return(DynValue.NewBoolean(lhs.Equals(t2.value))); } } return(DynValue.False); }
public static DynValue concat(ScriptExecutionContext executionContext, CallbackArguments args) { if (args.Count < 1) { throw ScriptRuntimeException.BadArgumentValueExpected(0, "concat"); } string toreturn = ""; if (args.Count == 1) { toreturn = _castToString(args.RawGet(0, true)); } else if (args.Count == 2) { toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true)); } else if (args.Count == 3) { toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true)) + _castToString(args.RawGet(2, true)); } else if (args.Count == 4) { toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true)) + _castToString(args.RawGet(2, true)) + _castToString(args.RawGet(3, true)); } else { for (int i = 0; i != args.Count; i++) { toreturn += _castToString(args.RawGet(i + 1, true)); } } return(DynValue.NewString(toreturn)); }
private static DynValue Dump(ScriptExecutionContext context, CallbackArguments args) { var val = args.RawGet(0, true); if (val == null) { throw new ScriptRuntimeException("Missing a value to dump"); } var maxDepthVal = args.RawGet(1, true); var maxDepth = maxDepthVal != null ? (int)(maxDepthVal.CastToNumber() ?? -1) : -1; Dump(context.GetScript(), val, maxDepth); Console.WriteLine(); return(DynValue.Void); }
DynValue Callback(Script script, object obj, ScriptExecutionContext context, CallbackArguments args) { if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedFunc == null && m_OptimizedAction == null) { Optimize(); } object[] pars = new object[m_Arguments.Length]; int j = args.IsMethodCall ? 1 : 0; for (int i = 0; i < pars.Length; i++) { if (m_Arguments[i] == typeof(Script)) { pars[i] = script; } else if (m_Arguments[i] == typeof(ScriptExecutionContext)) { pars[i] = context; } else if (m_Arguments[i] == typeof(CallbackArguments)) { pars[i] = args.SkipMethodCall(); } else { var arg = args.RawGet(j, false) ?? DynValue.Void; pars[i] = ConversionHelper.MoonSharpValueToObjectOfType(arg, m_Arguments[i], m_Defaults[i]); j++; } } object retv = null; if (m_OptimizedFunc != null) { retv = m_OptimizedFunc(obj, pars); } else if (m_OptimizedAction != null) { m_OptimizedAction(obj, pars); retv = DynValue.Void; } else if (m_IsAction) { MethodInfo.Invoke(obj, pars); retv = DynValue.Void; } else { retv = MethodInfo.Invoke(obj, pars); } return(ConversionHelper.ClrObjectToComplexMoonSharpValue(script, retv)); }
private DynValue lua_print_generic(ScriptExecutionContext context, CallbackArguments args) { for (var i = 0; i < args.Count; ++i) { var arg = args.RawGet(i, false); Debug.Log(arg.ToPrintString()); } return(DynValue.Nil); }
public static DynValue format(ScriptExecutionContext executionContext, CallbackArguments args) { string format = args.AsString(0, "format"); string toreturn; if (args.Count == 1) { toreturn = string.Format(format); } else if (args.Count == 2) { toreturn = string.Format(format, args.RawGet(1, true).ToString()); } else if (args.Count == 3) { toreturn = string.Format(format, args.RawGet(1, true).ToString(), args.RawGet(2, true).ToString()); } else if (args.Count == 4) { toreturn = string.Format(format, args.RawGet(1, true).ToString(), args.RawGet(2, true).ToString(), args.RawGet(3, true).ToString()); } else { string[] array = new string[args.Count - 1]; for (int i = 0; i != array.Length; i++) { array[i] = args.RawGet(i + 1, true).ToString(); } toreturn = string.Format(format, array); } return(DynValue.NewString(toreturn)); }
private DynValue Place(ScriptExecutionContext _context, CallbackArguments _args) { // get the argument DynValue argument = _args.RawGet(0, true); // cast to number int type = (int)argument.CastToNumber(); // call the place func m_builder.Place((PrimitiveType)type); return(DynValue.Void); }
/// <summary> /// Builds the argument list. /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <param name="outParams">Output: A list containing the indices of all "out" parameters, or null if no out parameters are specified.</param> /// <returns>The arguments, appropriately converted.</returns> protected virtual object[] BuildArgumentList(Script script, object obj, ScriptExecutionContext context, CallbackArguments args, out List <int> outParams) { ParameterDescriptor[] parameters = Parameters; object[] pars = new object[parameters.Length]; int j = args.IsMethodCall ? 1 : 0; outParams = null; for (int i = 0; i < pars.Length; i++) { // keep track of out and ref params if (parameters[i].Type.IsByRef) { if (outParams == null) { outParams = new List <int>(); } outParams.Add(i); } // if an ext method, we have an obj -> fill the first param if (ExtensionMethodType != null && obj != null && i == 0) { pars[i] = obj; continue; } // else, fill types with a supported type else if (parameters[i].Type == typeof(Script)) { pars[i] = script; } else if (parameters[i].Type == typeof(ScriptExecutionContext)) { pars[i] = context; } else if (parameters[i].Type == typeof(CallbackArguments)) { pars[i] = args.SkipMethodCall(); } // else, ignore out params else if (parameters[i].IsOut) { pars[i] = null; } else if (i == parameters.Length - 1 && VarArgsArrayType != null) { List <DynValue> extraArgs = new List <DynValue>(); while (true) { DynValue arg = args.RawGet(j, false); j += 1; if (arg != null) { extraArgs.Add(arg); } else { break; } } // here we have to worry we already have an array.. damn. We only support this for userdata. // remains to be analyzed what's the correct behavior here. For example, let's take a params object[].. // given a single table parameter, should it use it as an array or as an object itself ? if (extraArgs.Count == 1) { DynValue arg = extraArgs[0]; if (arg.Type == DataType.UserData && arg.UserData.Object != null) { if (Framework.Do.IsAssignableFrom(VarArgsArrayType, arg.UserData.Object.GetType())) { pars[i] = arg.UserData.Object; continue; } } } // ok let's create an array, and loop Array vararg = Array.CreateInstance(VarArgsElementType, extraArgs.Count); for (int ii = 0; ii < extraArgs.Count; ii++) { vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType, null, false), ii); } pars[i] = vararg; } // else, convert it else { var arg = args.RawGet(j, false) ?? DynValue.Void; pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, parameters[i].Type, parameters[i].DefaultValue, parameters[i].HasDefaultValue); j += 1; } } return(pars); }
/// <summary> /// Calculates the score for the overload. /// </summary> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <param name="method">The method.</param> /// <param name="isExtMethod">if set to <c>true</c>, is an extension method.</param> /// <returns></returns> private int CalcScoreForOverload(ScriptExecutionContext context, CallbackArguments args, IOverloadableMemberDescriptor method, bool isExtMethod) { int totalScore = ScriptToClrConversions.WEIGHT_EXACT_MATCH; int argsBase = args.IsMethodCall ? 1 : 0; int argsCnt = argsBase; bool varArgsUsed = false; for (int i = 0; i < method.Parameters.Length; i++) { if (isExtMethod && i == 0) { continue; } if (method.Parameters[i].IsOut) { continue; } Type parameterType = method.Parameters[i].Type; if ((parameterType == typeof(Script)) || (parameterType == typeof(ScriptExecutionContext)) || (parameterType == typeof(CallbackArguments))) { continue; } if (i == method.Parameters.Length - 1 && method.VarArgsArrayType != null) { int varargCnt = 0; DynValue firstArg = null; int scoreBeforeVargars = totalScore; // update score for varargs while (true) { var arg = args.RawGet(argsCnt, false); if (arg == null) { break; } if (firstArg == null) { firstArg = arg; } argsCnt += 1; varargCnt += 1; int score = CalcScoreForSingleArgument(method.Parameters[i], method.VarArgsElementType, arg, isOptional: false); totalScore = Math.Min(totalScore, score); } // check if exact-match if (varargCnt == 1) { if (firstArg.Type == DataType.UserData && firstArg.UserData.Object != null) { if (Framework.Do.IsAssignableFrom(method.VarArgsArrayType, firstArg.UserData.Object.GetType())) { totalScore = scoreBeforeVargars; continue; } } } // apply varargs penalty to score if (varargCnt == 0) { totalScore = Math.Min(totalScore, ScriptToClrConversions.WEIGHT_VARARGS_EMPTY); } varArgsUsed = true; } else { var arg = args.RawGet(argsCnt, false) ?? DynValue.Void; int score = CalcScoreForSingleArgument(method.Parameters[i], parameterType, arg, method.Parameters[i].HasDefaultValue); totalScore = Math.Min(totalScore, score); argsCnt += 1; } } if (totalScore > 0) { if ((args.Count - argsBase) <= method.Parameters.Length) { totalScore += ScriptToClrConversions.WEIGHT_NO_EXTRA_PARAMS_BONUS; totalScore *= 1000; } else if (varArgsUsed) { totalScore -= ScriptToClrConversions.WEIGHT_VARARGS_MALUS; totalScore *= 1000; } else { totalScore *= 1000; totalScore -= ScriptToClrConversions.WEIGHT_EXTRA_PARAMS_MALUS * ((args.Count - argsBase) - method.Parameters.Length); totalScore = Math.Max(1, totalScore); } } #if DEBUG_OVERLOAD_RESOLVER System.Diagnostics.Debug.WriteLine(string.Format("[OVERLOAD] : Score {0} for method {1}", totalScore, method.SortDiscriminant)); #endif return(totalScore); }
/// <summary> /// Builds the argument list. /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <param name="outParams">Output: A list containing the indices of all "out" parameters, or null if no out parameters are specified.</param> /// <returns>The arguments, appropriately converted.</returns> protected virtual object[] BuildArgumentList(Script script, object obj, ScriptExecutionContext context, CallbackArguments args, out List<int> outParams) { ParameterDescriptor[] parameters = Parameters; object[] pars = new object[parameters.Length]; int j = args.IsMethodCall ? 1 : 0; outParams = null; for (int i = 0; i < pars.Length; i++) { // keep track of out and ref params if (parameters[i].Type.IsByRef) { if (outParams == null) outParams = new List<int>(); outParams.Add(i); } // if an ext method, we have an obj -> fill the first param if (ExtensionMethodType != null && obj != null && i == 0) { pars[i] = obj; continue; } // else, fill types with a supported type else if (parameters[i].Type == typeof(Script)) { pars[i] = script; } else if (parameters[i].Type == typeof(ScriptExecutionContext)) { pars[i] = context; } else if (parameters[i].Type == typeof(CallbackArguments)) { pars[i] = args.SkipMethodCall(); } // else, ignore out params else if (parameters[i].IsOut) { pars[i] = null; } else if (i == parameters.Length - 1 && VarArgsArrayType != null) { List<DynValue> extraArgs = new List<DynValue>(); while (true) { DynValue arg = args.RawGet(j, false); j += 1; if (arg != null) extraArgs.Add(arg); else break; } // here we have to worry we already have an array.. damn. We only support this for userdata. // remains to be analyzed what's the correct behavior here. For example, let's take a params object[].. // given a single table parameter, should it use it as an array or as an object itself ? if (extraArgs.Count == 1) { DynValue arg = extraArgs[0]; if (arg.Type == DataType.UserData && arg.UserData.Object != null) { if (VarArgsArrayType.IsAssignableFrom(arg.UserData.Object.GetType())) { pars[i] = arg.UserData.Object; continue; } } } // ok let's create an array, and loop Array vararg = Array.CreateInstance(VarArgsElementType, extraArgs.Count); for (int ii = 0; ii < extraArgs.Count; ii++) { vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType, null, false), ii); } pars[i] = vararg; } // else, convert it else { var arg = args.RawGet(j, false) ?? DynValue.Void; pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, parameters[i].Type, parameters[i].DefaultValue, parameters[i].HasDefaultValue); j += 1; } } return pars; }
/// <summary> /// The internal callback which actually executes the method /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <returns></returns> internal DynValue Callback(Script script, object obj, ScriptExecutionContext context, CallbackArguments args) { if (ValueTypeDefaultCtor != null) { object vto = Activator.CreateInstance(ValueTypeDefaultCtor); return(ClrToScriptConversions.ObjectToDynValue(script, vto)); } if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedFunc == null && m_OptimizedAction == null) { Optimize(); } object[] pars = new object[Parameters.Length]; int j = args.IsMethodCall ? 1 : 0; List <int> outParams = null; for (int i = 0; i < pars.Length; i++) { // keep track of out and ref params if (Parameters[i].ParameterType.IsByRef) { if (outParams == null) { outParams = new List <int>(); } outParams.Add(i); } // if an ext method, we have an obj -> fill the first param if (ExtensionMethodType != null && obj != null && i == 0) { pars[i] = obj; continue; } // else, fill types with a supported type else if (Parameters[i].ParameterType == typeof(Script)) { pars[i] = script; } else if (Parameters[i].ParameterType == typeof(ScriptExecutionContext)) { pars[i] = context; } else if (Parameters[i].ParameterType == typeof(CallbackArguments)) { pars[i] = args.SkipMethodCall(); } // else, ignore out params else if (Parameters[i].IsOut) { pars[i] = null; } else if (i == Parameters.Length - 1 && VarArgsArrayType != null) { List <DynValue> extraArgs = new List <DynValue>(); while (true) { DynValue arg = args.RawGet(j, false); j += 1; if (arg != null) { extraArgs.Add(arg); } else { break; } } // here we have to worry we already have an array.. damn. We only support this for userdata. // remains to be analyzed what's the correct behavior here. For example, let's take a params object[].. // given a single table parameter, should it use it as an array or as an object itself ? if (extraArgs.Count == 1) { DynValue arg = extraArgs[0]; if (arg.Type == DataType.UserData && arg.UserData.Object != null) { if (VarArgsArrayType.IsAssignableFrom(arg.UserData.Object.GetType())) { pars[i] = arg.UserData.Object; continue; } } } // ok let's create an array, and loop Array vararg = CreateVarArgArray(extraArgs.Count); for (int ii = 0; ii < extraArgs.Count; ii++) { vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType, null, false), ii); } pars[i] = vararg; } // else, convert it else { var arg = args.RawGet(j, false) ?? DynValue.Void; pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, Parameters[i].ParameterType, Parameters[i].DefaultValue, !Parameters[i].DefaultValue.IsDbNull()); j += 1; } } object retv = null; if (m_OptimizedFunc != null) { retv = m_OptimizedFunc(obj, pars); } else if (m_OptimizedAction != null) { m_OptimizedAction(obj, pars); retv = DynValue.Void; } else if (m_IsAction) { MethodInfo.Invoke(obj, pars); retv = DynValue.Void; } else { if (IsConstructor) { retv = ((ConstructorInfo)MethodInfo).Invoke(pars); } else { retv = MethodInfo.Invoke(obj, pars); } } if (outParams == null) { return(ClrToScriptConversions.ObjectToDynValue(script, retv)); } else { DynValue[] rets = new DynValue[outParams.Count + 1]; rets[0] = ClrToScriptConversions.ObjectToDynValue(script, retv); for (int i = 0; i < outParams.Count; i++) { rets[i + 1] = ClrToScriptConversions.ObjectToDynValue(script, pars[outParams[i]]); } return(DynValue.NewTuple(rets)); } }