public static DynValue tostring(ScriptExecutionContext executionContext, CallbackArguments args) { if (args.Count < 1) { throw ScriptRuntimeException.BadArgumentValueExpected(0, "tostring"); } DynValue v = args[0]; DynValue tail = executionContext.GetMetamethodTailCall(v, "__tostring", v); if (tail == null || tail.IsNil()) { return(DynValue.NewString(v.ToPrintString())); } tail.TailCallData.Continuation = new CallbackFunction(__tostring_continuation, "__tostring"); return(tail); }
/// <summary> /// Sets the value of the property /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="v">The value to set.</param> public void SetValue(Script script, object obj, DynValue v) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); if (m_Setter == null) { throw new ScriptRuntimeException("userdata property '{0}.{1}' cannot be written to.", this.PropertyInfo.DeclaringType.Name, this.Name); } object value = ScriptToClrConversions.DynValueToObjectOfType(v, this.PropertyInfo.PropertyType, null, false); try { if (value is double) { value = NumericConversions.DoubleToType(PropertyInfo.PropertyType, (double)value); } if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedSetter == null) { OptimizeSetter(); } if (m_OptimizedSetter != null) { m_OptimizedSetter(obj, value); } else { m_Setter.Invoke(IsStatic ? null : obj, new object[] { value }); // convoluted workaround for --full-aot Mono execution } } catch (ArgumentException) { // non-optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, PropertyInfo.PropertyType); } catch (InvalidCastException) { // optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, PropertyInfo.PropertyType); } }
public static DynValue insert(ScriptExecutionContext executionContext, CallbackArguments args) { DynValue vlist = args.AsType(0, "table.insert", DataType.Table, false); DynValue vpos = args[1]; DynValue vvalue = args[2]; if (args.Count > 3) { throw new ScriptRuntimeException("wrong number of arguments to 'insert'"); } int len = GetTableLength(executionContext, vlist); Table list = vlist.Table; if (vvalue.IsNil()) { vvalue = vpos; vpos = DynValue.NewNumber(len + (executionContext.OwnerScript.Options.ZeroIndexTables ? 0 : 1)); // + 1 } if (vpos.Type != DataType.Number) { throw ScriptRuntimeException.BadArgument(1, "table.insert", DataType.Number, vpos.Type, false); } int pos = (int)vpos.Number; if (pos > len + 1 || pos < (executionContext.OwnerScript.Options.ZeroIndexTables ? 0 : 1)) { throw new ScriptRuntimeException("bad argument #2 to 'insert' (position out of bounds)"); } for (int i = len; i >= pos; i--) { list.Set(i + 1, list.Get(i)); } list.Set(pos, vvalue); return(vlist); }
public DynValue GetSensorValue(string label) { if (allowedLabels.Find(x => x.Match(label).Success) == null) { throw ScriptRuntimeException.BadArgument(0, "GetSensorValue", "label is not valid"); } using (var searcher = new ManagementObjectSearcher(@"root\wmi", string.Format("SELECT Value FROM AIDA64_SensorValues WHERE ID='{0}'", label))) { try { var value = searcher.Get().Cast <ManagementBaseObject>().First(); try { return(DynValue.NewNumber(Convert.ToDouble(value["Value"]))); } catch (FormatException) { // Some values are not supported in trial versions return(DynValue.NewBoolean(false)); } } catch (InvalidOperationException) { // Valid label, but may not apply with this hardware (e.g. specific cpu core data) return(DynValue.NewBoolean(false)); } catch (ManagementException e) { if (e.ErrorCode == ManagementStatus.InvalidClass) { throw new ScriptRuntimeException("GetSensorValue called but AIDA64 is not running"); } else { throw e; } } } }
/// <summary> /// Raises an appropriate ScriptRuntimeException if the specified access is not supported. /// Checks are made for the MemberDescriptorAccess permissions AND for the access of instance /// members through static userdatas. /// </summary> /// <param name="desc">The desc.</param> /// <param name="access">The access.</param> /// <param name="obj">The object to be checked for access.</param> public static void CheckAccess(this IMemberDescriptor desc, MemberDescriptorAccess access, object obj) { if (!desc.IsStatic && obj == null) { throw ScriptRuntimeException.AccessInstanceMemberOnStatics(desc); } if (access.HasAllFlags(MemberDescriptorAccess.CanExecute) && !desc.CanExecute()) { throw new ScriptRuntimeException("userdata member {0} cannot be called.", desc.Name); } if (access.HasAllFlags(MemberDescriptorAccess.CanWrite) && !desc.CanWrite()) { throw new ScriptRuntimeException("userdata member {0} cannot be assigned to.", desc.Name); } if (access.HasAllFlags(MemberDescriptorAccess.CanRead) && !desc.CanRead()) { throw new ScriptRuntimeException("userdata member {0} cannot be read from.", desc.Name); } }
/// <summary> /// Evaluates the specified script node. /// </summary> /// <param name="scriptNode">The script node.</param> /// <param name="aliasReturnedFunction">if set to <c>true</c> and a function would be evaluated as part of this node, return the object function without evaluating it.</param> /// <returns>The result of the evaluation.</returns> public virtual object Evaluate(ScriptNode scriptNode, bool aliasReturnedFunction) { if (scriptNode == null) { return(null); } var previousFunctionCallState = _isFunctionCallDisabled; var previousLevel = _getOrSetValueLevel; var previousNode = CurrentNode; try { CurrentNode = scriptNode; _getOrSetValueLevel = 0; _isFunctionCallDisabled = aliasReturnedFunction; return(scriptNode.Evaluate(this)); } catch (ScriptRuntimeException ex) when(this.RenderRuntimeException != null) { return(this.RenderRuntimeException(ex)); } catch (Exception ex) when(!(ex is ScriptRuntimeException)) { var toThrow = new ScriptRuntimeException(scriptNode.Span, ex.Message, ex); if (RenderRuntimeException != null) { return(RenderRuntimeException(toThrow)); } throw toThrow; } finally { CurrentNode = previousNode; _getOrSetValueLevel = previousLevel; _isFunctionCallDisabled = previousFunctionCallState; } }
private int ExecLessEq(Instruction i, int instructionPtr) { DynValue r = m_ValueStack.Pop().ToScalar(); DynValue l = m_ValueStack.Pop().ToScalar(); if (l.Type == DataType.Number && r.Type == DataType.Number) { m_ValueStack.Push(DynValue.False); m_ValueStack.Push(DynValue.NewBoolean(l.Number <= r.Number)); } else if (l.Type == DataType.String && r.Type == DataType.String) { m_ValueStack.Push(DynValue.False); m_ValueStack.Push(DynValue.NewBoolean(l.String.CompareTo(r.String) <= 0)); } else { int ip = Internal_InvokeBinaryMetaMethod(l, r, "__le", instructionPtr, DynValue.False); if (ip < 0) { ip = Internal_InvokeBinaryMetaMethod(r, l, "__lt", instructionPtr, DynValue.True); if (ip < 0) { throw ScriptRuntimeException.CompareInvalidType(l, r); } else { return(ip); } } else { return(ip); } } return(instructionPtr); }
/// <summary> /// Sets the value of the property /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="v">The value to set.</param> public void SetValue(Script script, object obj, DynValue v) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); if (this.IsReadonly || this.IsConst) { throw new ScriptRuntimeException("userdata field '{0}.{1}' cannot be written to.", this.FieldInfo.DeclaringType.Name, this.Name); } var value = ScriptToClrConversions.DynValueToObjectOfType(v, this.FieldInfo.FieldType, null, false); try { if (value is double d) { value = NumericConversions.DoubleToType(this.FieldInfo.FieldType, d); } this.FieldInfo.SetValue(this.IsStatic ? null : obj, value); } catch (ArgumentException) { // non-optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, this.FieldInfo.FieldType); } catch (InvalidCastException) { // optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, this.FieldInfo.FieldType); } #if !(ENABLE_DOTNET || NETFX_CORE) catch (FieldAccessException ex) { throw new ScriptRuntimeException(ex); } #endif }
private int ExecNeg(Instruction i, int instructionPtr) { DynValue r = m_ValueStack.Pop().ToScalar(); double? rn = r.CastToNumber(); if (rn.HasValue) { m_ValueStack.Push(DynValue.NewNumber(-rn.Value)); return(instructionPtr); } else { int ip = Internal_InvokeUnaryMetaMethod(r, "__unm", instructionPtr); if (ip >= 0) { return(ip); } else { throw ScriptRuntimeException.ArithmeticOnNonNumber(r); } } }
/// <summary> /// Performs an "index" "set" operation. This tries to resolve minor variations of member names. /// </summary> /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="index">The index.</param> /// <param name="value">The value to be set</param> /// <param name="isDirectIndexing">If set to true, it's indexed with a name, if false it's indexed through brackets.</param> /// <returns></returns> public virtual bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool isDirectIndexing) { if (!isDirectIndexing) { StandardUserDataOverloadedMethodDescriptor mdesc = m_Methods.GetOrDefault(SPECIAL_SETITEM); if (mdesc != null) { ExecuteIndexer(mdesc, script, obj, index, value); return(true); } } index = index.ToScalar(); if (index.Type != DataType.String) { throw ScriptRuntimeException.BadArgument(1, string.Format("userdata<{0}>.__setindex", this.Name), "string", index.Type.ToLuaTypeString(), false); } bool v = TrySetIndex(script, obj, index.String, value); if (!v) { v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value); } if (!v) { v = TrySetIndex(script, obj, Camelify(index.String), value); } if (!v) { v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value); } return(v); }
public DynValue Index(Script script, object obj, DynValue index) { if (index.Type != DataType.String) { throw ScriptRuntimeException.BadArgument(1, string.Format("userdata<{0}>.__index", this.Name), "string", index.Type.ToLuaTypeString(), false); } DynValue v = TryIndex(script, obj, index.String); if (v == null) { v = TryIndex(script, obj, UpperFirstLetter(index.String)); } if (v == null) { v = TryIndex(script, obj, Camelify(index.String)); } if (v == null) { v = TryIndex(script, obj, UpperFirstLetter(Camelify(index.String))); } return(v); }
public bool SetIndex(Script script, object obj, DynValue index, DynValue value) { if (index.Type != DataType.String) { throw ScriptRuntimeException.BadArgument(1, string.Format("userdata<{0}>.__setindex", this.Name), "string", index.Type.ToLuaTypeString(), false); } bool v = TrySetIndex(script, obj, index.String, value); if (!v) { v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value); } if (!v) { v = TrySetIndex(script, obj, Camelify(index.String), value); } if (!v) { v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value); } return(v); }
internal static object ConvertString(StringSubtype stringSubType, string str, Type desiredType, DataType dataType) { switch (stringSubType) { case StringSubtype.String: return(str); case StringSubtype.StringBuilder: return(new StringBuilder(str)); case StringSubtype.Char: if (!string.IsNullOrEmpty(str)) { return(str[0]); } break; case StringSubtype.None: default: break; } throw ScriptRuntimeException.ConvertObjectFailed(dataType, desiredType); }
public static DynValue upvaluejoin(ScriptExecutionContext executionContext, CallbackArguments args) { var f1 = args.AsType(0, "upvaluejoin", DataType.Function); var f2 = args.AsType(2, "upvaluejoin", DataType.Function); int n1 = args.AsInt(1, "upvaluejoin") - 1; int n2 = args.AsInt(3, "upvaluejoin") - 1; var c1 = f1.Function; var c2 = f2.Function; if (n1 < 0 || n1 >= c1.ClosureContext.Count) { throw ScriptRuntimeException.BadArgument(1, "upvaluejoin", "invalid upvalue index"); } if (n2 < 0 || n2 >= c2.ClosureContext.Count) { throw ScriptRuntimeException.BadArgument(3, "upvaluejoin", "invalid upvalue index"); } c2.ClosureContext[n2] = c1.ClosureContext[n1]; return(DynValue.Void); }
/// <summary> /// Tries to convert a CLR object to a MoonSharp value, using more in-depth analysis /// </summary> internal static R_VAL ObjectToValue(RubyState state, object obj) { R_VAL v = TryObjectToSimpleValue(script, obj); if (v != null) { return(v); } v = UserData.Create(obj); if (v != null) { return(v); } if (obj is Type) { v = UserData.CreateStatic(obj as Type); } // unregistered enums go as integers if (obj is Enum) { return(R_VAL.NewNumber( NumericConversions.TypeToDouble(Enum.GetUnderlyingType(obj.GetType()), obj))); } if (v != null) { return(v); } if (obj is Delegate) { return(R_VAL.NewCallback(CallbackFunction.FromDelegate(script, ( Delegate )obj))); } if (obj is MethodInfo) { MethodInfo mi = ( MethodInfo )obj; if (mi.IsStatic) { return(R_VAL.NewCallback(CallbackFunction.FromMethodInfo(script, mi))); } } if (obj is System.Collections.IList) { Table t = TableConversions.ConvertIListToTable(script, (System.Collections.IList)obj); return(R_VAL.NewTable(t)); } if (obj is System.Collections.IDictionary) { Table t = TableConversions.ConvertIDictionaryToTable(script, (System.Collections.IDictionary)obj); return(R_VAL.NewTable(t)); } var enumerator = EnumerationToValue(script, obj); if (enumerator != null) { return(enumerator); } throw ScriptRuntimeException.ConvertObjectFailed(obj); }
internal static object MoonSharpValueToObjectOfType(DynValue value, Type desiredType, object defaultValue) { if (desiredType == typeof(DynValue)) { return(value); } if (desiredType == typeof(object)) { return(value.ToObject()); } bool isString = false; bool isStringBuilder = false; bool isChar = false; if (desiredType == typeof(string)) { isString = true; } else if (desiredType == typeof(StringBuilder)) { isStringBuilder = true; } else if (desiredType == typeof(char) && value.String.Length > 0) { isChar = true; } bool isAnyString = isString || isStringBuilder || isChar; string str = null; Type nt = Nullable.GetUnderlyingType(desiredType); Type nullableType = null; if (nt != null) { nullableType = desiredType; desiredType = nt; } switch (value.Type) { case DataType.Void: if (desiredType.IsValueType) { if (defaultValue != null) { return(defaultValue); } if (nullableType != null) { return(null); } } else { return(defaultValue); } break; case DataType.Nil: if (desiredType.IsValueType) { if (nullableType != null) { return(null); } if (defaultValue != null) { return(defaultValue); } } else { return(null); } break; case DataType.Boolean: if (desiredType == typeof(bool)) { return(value.Boolean); } if (isAnyString) { str = value.Boolean.ToString(); } break; case DataType.Number: if (NumericTypes.Contains(desiredType)) { return(DoubleToType(desiredType, value.Number)); } if (isAnyString) { str = value.Number.ToString(); } break; case DataType.String: if (isAnyString) { str = value.String; } break; case DataType.Function: if (desiredType == typeof(Closure)) { return(value.Function); } break; case DataType.ClrFunction: if (desiredType == typeof(CallbackFunction)) { return(value.Callback); } break; case DataType.UserData: if (value.UserData.Object != null) { if (desiredType.IsInstanceOfType(value.UserData.Object)) { return(value.UserData.Object); } if (isAnyString) { str = value.UserData.Object.ToString(); } } break; case DataType.Table: if (desiredType == typeof(Table) || desiredType.IsAssignableFrom(typeof(Table))) { return(value.Table); } else { object o = ConvertTableToType(value.Table, desiredType); if (o != null) { return(o); } } break; case DataType.Tuple: break; } if (str != null) { if (isString) { return(str); } if (isStringBuilder) { return(new StringBuilder(str)); } if (isChar && str.Length > 0) { return(str[0]); } } throw ScriptRuntimeException.ConvertObjectFailed(value.Type, desiredType); }
/// <summary> /// Converts a DynValue to a CLR object of a specific type /// </summary> internal static object DynValueToObjectOfType(DynValue value, Type desiredType, object defaultValue, bool isOptional) { if (desiredType.IsByRef) { desiredType = desiredType.GetElementType(); } var converter = Script.GlobalOptions.CustomConverters.GetScriptToClrCustomConversion(value.Type, desiredType); if (converter != null) { var v = converter(value); if (v != null) { return(v); } } if (desiredType == typeof(DynValue)) { return(value); } if (desiredType == typeof(object)) { return(DynValueToObject(value)); } StringConversions.StringSubtype stringSubType = StringConversions.GetStringSubtype(desiredType); string str = null; Type nt = Nullable.GetUnderlyingType(desiredType); Type nullableType = null; if (nt != null) { nullableType = desiredType; desiredType = nt; } switch (value.Type) { case DataType.Void: if (isOptional) { return(defaultValue); } else if ((!Framework.Do.IsValueType(desiredType)) || (nullableType != null)) { return(null); } break; case DataType.Nil: if (Framework.Do.IsValueType(desiredType)) { if (nullableType != null) { return(null); } if (isOptional) { return(defaultValue); } } else { return(null); } break; case DataType.Boolean: if (desiredType == typeof(bool)) { return(value.Boolean); } if (stringSubType != StringConversions.StringSubtype.None) { str = value.Boolean.ToString(); } break; case DataType.Number: if (Framework.Do.IsEnum(desiredType)) { // number to enum conv Type underType = Enum.GetUnderlyingType(desiredType); return(NumericConversions.FixToType(underType, value.Number)); } if (NumericConversions.NumericTypes.Contains(desiredType)) { return(NumericConversions.FixToType(desiredType, value.Number)); } if (stringSubType != StringConversions.StringSubtype.None) { str = value.Number.ToString(); } break; case DataType.String: if (stringSubType != StringConversions.StringSubtype.None) { str = value.String; } break; case DataType.Function: if (desiredType == typeof(Closure)) { return(value.Function); } else if (desiredType == typeof(ScriptFunctionDelegate)) { return(value.Function.GetDelegate()); } break; case DataType.ClrFunction: if (desiredType == typeof(CallbackFunction)) { return(value.Callback); } else if (desiredType == typeof(Func <ScriptExecutionContext, CallbackArguments, DynValue>)) { return(value.Callback.ClrCallback); } break; case DataType.UserData: if (value.UserData.Object != null) { var udObj = value.UserData.Object; var udDesc = value.UserData.Descriptor; if (udDesc.IsTypeCompatible(desiredType, udObj)) { return(udObj); } if (stringSubType != StringConversions.StringSubtype.None) { str = udDesc.AsString(udObj); } } break; case DataType.Table: if (desiredType == typeof(Table) || Framework.Do.IsAssignableFrom(desiredType, typeof(Table))) { return(value.Table); } else { object o = TableConversions.ConvertTableToType(value.Table, desiredType); if (o != null) { return(o); } } break; case DataType.Tuple: break; } if (stringSubType != StringConversions.StringSubtype.None && str != null) { return(StringConversions.ConvertString(stringSubType, str, desiredType, value.Type)); } throw ScriptRuntimeException.ConvertObjectFailed(value.Type, desiredType); }
protected static void LuaLArgError(LuaState L, lua_Integer arg, string p) { throw ScriptRuntimeException.BadArgument(arg - 1, L.FunctionName, p); }
internal static DynValue ClrObjectToComplexMoonSharpValue(Script script, object obj) { DynValue v = TryClrObjectToSimpleMoonSharpValue(script, obj); if (v != null) { return(v); } v = UserData.Create(obj); if (v != null) { return(v); } if (obj is Type) { v = UserData.CreateStatic(obj as Type); } if (v != null) { return(v); } if (obj is Delegate) { return(DynValue.NewCallback(CallbackFunction.FromDelegate(script, (Delegate)obj))); } if (obj is MethodInfo) { MethodInfo mi = (MethodInfo)obj; if (mi.IsStatic) { return(DynValue.NewCallback(CallbackFunction.FromMethodInfo(script, mi))); } } if (obj is System.Collections.IList) { Table t = ConvertIListToTable(script, (System.Collections.IList)obj); return(DynValue.NewTable(t)); } if (obj is System.Collections.IDictionary) { Table t = ConvertIDictionaryToTable(script, (System.Collections.IDictionary)obj); return(DynValue.NewTable(t)); } if (obj is System.Collections.IEnumerable) { var enumer = (System.Collections.IEnumerable)obj; return(EnumerableWrapper.ConvertIterator(script, enumer.GetEnumerator())); } if (obj is System.Collections.IEnumerator) { var enumer = (System.Collections.IEnumerator)obj; return(EnumerableWrapper.ConvertIterator(script, enumer)); } throw ScriptRuntimeException.ConvertObjectFailed(obj); }
public DynValue read(ScriptExecutionContext executionContext, CallbackArguments args) { if (args.Count == 0) { string str = ReadLine(); if (str == null) { return(DynValue.Nil); } str = str.TrimEnd('\n', '\r'); return(DynValue.NewString(str)); } else { List <DynValue> rets = new List <DynValue>(); for (int i = 0; i < args.Count; i++) { DynValue v; if (args[i].Type == DataType.Number) { if (Eof()) { return(DynValue.Nil); } int howmany = (int)args[i].Number; string str = ReadBuffer(howmany); v = DynValue.NewString(str); } else { string opt = args.AsType(i, "read", DataType.String, false).String; if (Eof()) { v = opt.StartsWith("*a") ? DynValue.NewString("") : DynValue.Nil; } else if (opt.StartsWith("*n")) { double?d = ReadNumber(); if (d.HasValue) { v = DynValue.NewNumber(d.Value); } else { v = DynValue.Nil; } } else if (opt.StartsWith("*a")) { string str = ReadToEnd(); v = DynValue.NewString(str); } else if (opt.StartsWith("*l")) { string str = ReadLine(); str = str.TrimEnd('\n', '\r'); v = DynValue.NewString(str); } else if (opt.StartsWith("*L")) { string str = ReadLine(); str = str.TrimEnd('\n', '\r'); str += "\n"; v = DynValue.NewString(str); } else { throw ScriptRuntimeException.BadArgument(i, "read", "invalid option"); } } rets.Add(v); } return(DynValue.NewTuple(rets.ToArray())); } }
public bool SignalRuntimeException(ScriptRuntimeException ex) { return(false); }
public bool SignalRuntimeException(ScriptRuntimeException ex) { Console_WriteLine("Error: {0}", ex.DecoratedMessage); return(true); }
public bool SignalRuntimeException(ScriptRuntimeException ex) { MessageBoxEx.Show(MainForm.TheMainForm, ex.ToString()); throw ex; }
/// <summary> /// Tries to convert a CLR object to a MoonSharp value, using more in-depth analysis /// </summary> internal static DynValue ObjectToDynValue(Script script, object obj) { var v = TryObjectToSimpleDynValue(script, obj); if (v != null) { return(v); } v = UserData.Create(obj); if (v != null) { return(v); } if (obj is Type type) { v = UserData.CreateStatic(type); } // unregistered enums go as integers if (obj is Enum) { return(DynValue.NewNumber(NumericConversions.TypeToDouble(Enum.GetUnderlyingType(obj.GetType()), obj))); } if (v != null) { return(v); } if (obj is Delegate d) { return(DynValue.NewCallback(CallbackFunction.FromDelegate(script, d))); } if (obj is MethodInfo mi) { if (mi.IsStatic) { return(DynValue.NewCallback(CallbackFunction.FromMethodInfo(script, mi))); } } if (obj is IList list) { var t = TableConversions.ConvertIListToTable(script, list); return(DynValue.NewTable(t)); } if (obj is IDictionary dict) { var t = TableConversions.ConvertIDictionaryToTable(script, dict); return(DynValue.NewTable(t)); } var enumerator = EnumerationToDynValue(script, obj); if (enumerator != null) { return(enumerator); } throw ScriptRuntimeException.ConvertObjectFailed(obj); }
//TODO use compiled lamda expresssion, which would GREATLY optimize this tree //the process of converting /// <summary> /// Converts a DynValue to a CLR object of a specific type /// </summary> internal static T DynValueToTypedValue <T>(DynValue value, T defaultValue, bool isOptional) { var desiredType = typeof(T); if (desiredType.IsByRef) { desiredType = desiredType.GetElementType(); } var converter = Script.GlobalOptions.CustomConverters.GetScriptToClrCustomConversion(value.Type, typeof(T)); if (converter != null) { var v = converter(value, desiredType); if (v != null) { return((T)v); } } if (desiredType == typeof(DynValue)) { return(ValueConverter <DynValue, T> .Instance.Convert(value)); } if (desiredType == typeof(object)) { return((T)DynValueToObject(value)); } StringConversions.StringSubtype stringSubType = StringConversions.GetStringSubtype(desiredType); string str = null; Type nt = Nullable.GetUnderlyingType(desiredType); Type nullableType = null; if (nt != null) { nullableType = desiredType; desiredType = nt; } switch (value.Type) { case DataType.Void: if (isOptional) { return(defaultValue); } else if ((!desiredType.IsValueType) || (nullableType != null)) { return(default(T)); } break; case DataType.Nil: if (desiredType.IsValueType) { if (nullableType != null) { return(default(T)); } if (isOptional) { return(defaultValue); } } else { return(default(T)); } break; case DataType.Boolean: if (desiredType == typeof(bool)) { return(ValueConverter <bool, T> .Instance.Convert(value.Boolean)); } if (stringSubType != StringConversions.StringSubtype.None) { str = value.Boolean.ToString(); } break; case DataType.Number: if (desiredType.IsEnum || NumericConversions.NumericTypes.Contains(desiredType)) { return(ValueConverter <double, T> .Instance.Convert(value.Number)); } if (stringSubType != StringConversions.StringSubtype.None) { str = value.Number.ToString(); } break; case DataType.String: if (stringSubType != StringConversions.StringSubtype.None) { str = value.String; } break; case DataType.Function: if (desiredType == typeof(Closure)) { return(ValueConverter <Closure, T> .Instance.Convert(value.Function)); } else if (desiredType == typeof(ScriptFunctionDelegate <T>)) { return(ValueConverter <ScriptFunctionDelegate <T>, T> .Instance.Convert(value.Function.GetDelegate <T>())); } break; case DataType.ClrFunction: if (desiredType == typeof(CallbackFunction)) { return(ValueConverter <CallbackFunction, T> .Instance.Convert(value.Callback)); } else if (desiredType == typeof(Func <ScriptExecutionContext, CallbackArguments, DynValue>)) { return(ValueConverter <Func <ScriptExecutionContext, CallbackArguments, DynValue>, T> .Instance.Convert(value.Callback.ClrCallback)); } break; case DataType.UserData: if (value.UserData.HasValue()) { T t; if (value.UserData.TryGet(out t)) { return(t); } if (stringSubType != StringConversions.StringSubtype.None) { str = value.UserData.AsString(); } } break; case DataType.Table: if (desiredType == typeof(Table) || Framework.Do.IsAssignableFrom(desiredType, typeof(Table))) { return(ValueConverter <Table, T> .Instance.Convert(value.Table)); } else { object o = TableConversions.ConvertTableToType(value.Table, typeof(T)); if (o != null) { return(ValueConverter <object, T> .Instance.Convert(o)); } } break; case DataType.Tuple: break; } if (stringSubType != StringConversions.StringSubtype.None && str != null) { return(ValueConverter <object, T> .Instance.Convert(StringConversions.ConvertString(stringSubType, str, desiredType, value.Type))); } throw ScriptRuntimeException.ConvertObjectFailed(value.Type, desiredType); }
internal void AddMsgFromScribanException(ScriptRuntimeException exception) { hasErrors = true; messages.Add(new MessageItem(exception)); }
public static DynValue open(ScriptExecutionContext executionContext, CallbackArguments args) { string filename = args.AsType(0, "open", DataType.String, false).String; DynValue vmode = args.AsType(1, "open", DataType.String, true); DynValue vencoding = args.AsType(2, "open", DataType.String, true); string mode = vmode.IsNil() ? "r" : vmode.String; string invalidChars = mode.Replace("+", "") .Replace("r", "") .Replace("a", "") .Replace("w", "") .Replace("b", "") .Replace("t", ""); if (invalidChars.Length > 0) { throw ScriptRuntimeException.BadArgument(1, "open", "invalid mode"); } try { string encoding = vencoding.IsNil() ? null : vencoding.String; // list of codes: http://msdn.microsoft.com/en-us/library/vstudio/system.text.encoding%28v=vs.90%29.aspx. // In addition, "binary" is available. Encoding e = null; bool isBinary = mode.Contains('b'); if (encoding == "binary") { isBinary = true; e = new BinaryEncoding(); } else if (encoding == null) { if (!isBinary) { e = GetUTF8Encoding(); } else { e = new BinaryEncoding(); } } else { if (isBinary) { throw new ScriptRuntimeException("Can't specify encodings other than nil or 'binary' for binary streams."); } e = Encoding.GetEncoding(encoding); } return(UserData.Create(Open(executionContext, filename, e, mode))); } catch (Exception ex) { return(DynValue.NewTuple(DynValue.Nil, DynValue.NewString(IoExceptionToLuaMessage(ex, filename)))); } }
public static DynValue tonumber(ScriptExecutionContext executionContext, CallbackArguments args) { if (args.Count < 1) { throw ScriptRuntimeException.BadArgumentValueExpected(0, "tonumber"); } DynValue e = args[0]; DynValue b = args.AsType(1, "tonumber", DataType.Number, true); if (b.IsNil()) { if (e.Type == DataType.Number) { return(e); } if (e.Type != DataType.String) { return(DynValue.Nil); } double d; if (double.TryParse(e.String, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { return(DynValue.NewNumber(d)); } return(DynValue.Nil); } else { //!COMPAT: tonumber supports only 2,8,10 or 16 as base //UPDATE: added support for 3-9 base numbers DynValue ee; if (args[0].Type != DataType.Number) { ee = args.AsType(0, "tonumber", DataType.String, false); } else { ee = DynValue.NewString(args[0].Number.ToString(CultureInfo.InvariantCulture)); }; int bb = (int)b.Number; uint uiv = 0; if (bb == 2 || bb == 8 || bb == 10 || bb == 16) { uiv = Convert.ToUInt32(ee.String.Trim(), bb); } else if (bb < 10 && bb > 2) // Support for 3, 4, 5, 6, 7 and 9 based numbers { foreach (char digit in ee.String.Trim()) { int value = digit - 48; if (value < 0 || value >= bb) { throw new ScriptRuntimeException("bad argument #1 to 'tonumber' (invalid character)"); } uiv = (uint)(uiv * bb) + (uint)value; } } else { throw new ScriptRuntimeException("bad argument #2 to 'tonumber' (base out of range)"); } return(DynValue.NewNumber(uiv)); } }
public DynValue Coroutine_Resume(DynValue[] args) { EnterProcessor(); try { int entrypoint = 0; if (m_State != CoroutineState.NotStarted && m_State != CoroutineState.Suspended && m_State != CoroutineState.ForceSuspended) { throw ScriptRuntimeException.CannotResumeNotSuspended(m_State); } if (m_State == CoroutineState.NotStarted) { entrypoint = PushClrToScriptStackFrame(CallStackItemFlags.ResumeEntryPoint, null, args); } else if (m_State == CoroutineState.Suspended) { m_ValueStack.Push(DynValue.NewTuple(args)); entrypoint = m_SavedInstructionPtr; } else if (m_State == CoroutineState.ForceSuspended) { if (args != null && args.Length > 0) { throw new ArgumentException("When resuming a force-suspended coroutine, args must be empty."); } entrypoint = m_SavedInstructionPtr; } m_State = CoroutineState.Running; DynValue retVal = Processing_Loop(entrypoint); if (retVal.Type == DataType.YieldRequest) { if (retVal.YieldRequest.Forced) { m_State = CoroutineState.ForceSuspended; return(retVal); } else { m_State = CoroutineState.Suspended; return(DynValue.NewTuple(retVal.YieldRequest.ReturnValues)); } } else { m_State = CoroutineState.Dead; return(retVal); } } catch (Exception) { // Unhandled exception - move to dead m_State = CoroutineState.Dead; throw; } finally { LeaveProcessor(); } }
public void OnException(ScriptRuntimeException ex) { SendText("runtime error : {0}", ex.DecoratedMessage); }