// writers public void WriteItem(object value) { if (value == null) { WriteMarker(Marker.Null); } else { var type = value.GetType(); if (Int29Types.Contains(type)) { WriteInt29(Convert.ToInt32(value)); } else if (NumberTypes.Contains(type)) { WriteDouble(Convert.ToDouble(value)); } else if (Writers.TryGetValue(type, out var writer)) { writer(this, value); } else { DispatchGenericWrite(value); } } }
internal static ReturnConverter MakeReturnConversion(Type returnType) { if (returnType == typeof(void)) { return((e, s, o) => MondValue.Undefined); } if (returnType == typeof(MondValue)) { return((e, s, o) => ReferenceEquals(o, null) ? MondValue.Null : (MondValue)o); } if (returnType == typeof(string)) { return((e, s, o) => ReferenceEquals(o, null) ? MondValue.Null : (MondValue)(string)o); } if (returnType == typeof(bool)) { return((e, s, o) => (bool)o); } if (NumberTypes.Contains(returnType)) { return((e, s, o) => Convert.ToDouble(o)); } var classAttrib = returnType.Attribute <MondClassAttribute>(); if (classAttrib != null && classAttrib.AllowReturn) { var className = classAttrib.Name ?? returnType.Name; return((e, s, o) => { var prototype = s.FindPrototype(className); if (prototype == null) { throw new MondRuntimeException(e + string.Format(BindingError.PrototypeNotFound, className)); } var obj = new MondValue(s); obj.Prototype = prototype; obj.UserData = o; return obj; }); } throw new MondBindingException(BindingError.UnsupportedReturnType, returnType); }
// MondValue -> T internal static Func <Expression, Expression> MakeParameterConversion(Type parameterType) { if (BasicTypes.Contains(parameterType)) { return(e => Expression.Convert(e, parameterType)); } if (NumberTypes.Contains(parameterType)) { return(e => Expression.Convert(Expression.Convert(e, typeof(double)), parameterType)); } return(null); }
void WriteItemInternal(object value) { var type = value.GetType(); if (NumberTypes.Contains(type)) { WriteNumber(Convert.ToDouble(value)); } else if (Writers.TryGetValue(type, out var write)) { write(this, value); } else { DispatchGenericWrite(value); } }
// T -> MondValue internal static ReturnConverter MakeReturnConversion(Type returnType) { if (returnType == typeof(void)) { return((e, s, v) => throw new MondBindingException("Expression binder should not use void return conversion")); } if (returnType == typeof(MondValue)) { return((e, s, v) => Expression.Coalesce(v, Expression.Constant(MondValue.Null))); } if (returnType == typeof(string)) { return((e, s, v) => { var tempVar = Expression.Variable(typeof(string)); var tempVarIsNull = Expression.ReferenceEqual(tempVar, Expression.Constant(null)); var tempVarAsValue = Expression.Convert(tempVar, typeof(MondValue)); var block = Expression.Block( new[] { tempVar }, Expression.Assign(tempVar, v), Expression.Condition(tempVarIsNull, Expression.Constant(MondValue.Null), tempVarAsValue) ); return block; }); } if (BasicTypes.Contains(returnType)) { return((e, s, v) => Expression.Convert(v, typeof(MondValue))); } if (NumberTypes.Contains(returnType)) { return((e, s, v) => Expression.Convert(Expression.Convert(v, typeof(double)), typeof(MondValue))); } var classAttrib = returnType.Attribute <MondClassAttribute>(); if (classAttrib != null && classAttrib.AllowReturn) { var objInitializerType = typeof(IEnumerable <KeyValuePair <MondValue, MondValue> >); var valueFactory = typeof(MondValue).GetMethod("Object", new[] { typeof(MondState), objInitializerType }); if (valueFactory == null) { throw new Exception("Could not find MondValue.Object method"); } var findPrototype = typeof(MondState).GetMethod("FindPrototype"); if (findPrototype == null) { throw new Exception("Could not find FindPrototype method"); } var className = classAttrib.Name ?? returnType.Name; return((e, s, v) => { var prototype = Expression.Variable(typeof(MondValue)); var obj = Expression.Variable(typeof(MondValue)); var throwMsg = Expression.Constant(e + string.Format(BindingError.PrototypeNotFound, className)); var throwExpr = Expression.Throw(Expression.New(RuntimeExceptionConstructor, throwMsg)); return Expression.Block( new [] { prototype, obj }, Expression.Assign(prototype, Expression.Call(s, findPrototype, Expression.Constant(className))), Expression.IfThen(Expression.ReferenceEqual(prototype, Expression.Constant(null)), throwExpr), Expression.Assign(obj, Expression.Call(valueFactory, s, Expression.Constant(null, objInitializerType))), Expression.Assign(Expression.PropertyOrField(obj, "Prototype"), prototype), Expression.Assign(Expression.PropertyOrField(obj, "UserData"), v), obj ); }); } throw new MondBindingException(BindingError.UnsupportedReturnType, returnType); }