// Pseudocode:
//string input =>
//{
// R result = 0;
// for (int i = input.Length - 1; i >= 0; i--)
// {
// result <<= 6;
// var m = _invMap[input[i]];
// if (m == 0xff)
// return default(ConversionResult<R>);
// result += m;
// }
// return new ConversionResult<R>(result);
//}
private LambdaExpression fromLambda(Type to)
{
var stringthis = typeof(string).GetTypeInfo().DeclaredProperties.First(p => p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof(int));
var input = Ex.Parameter(typeof(string), "input");
var result = Ex.Parameter(to, "result");
var i = Ex.Parameter(typeof(int), "i");
var m = Ex.Parameter(typeof(byte), "m");
var loopstart = Ex.Label("loopstart");
var end = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
var loop = Ex.Block(
Ex.Label(loopstart),
Ex.IfThen(Ex.MakeBinary(ExpressionType.LessThan, i, Ex.Constant(0)),
Ex.Goto(end, Result(to, result))),
Ex.LeftShiftAssign(result, Ex.Constant(6)),
Ex.Assign(m, Ex.ArrayIndex(Ex.Constant(_invMap), Ex.Convert(Ex.MakeIndex(input, stringthis, new[] { i }), typeof(int)))),
Ex.IfThen(Ex.MakeBinary(ExpressionType.Equal, m, Ex.Constant((byte)0xff)),
Ex.Goto(end, NoResult(to))),
Ex.AddAssign(result, Ex.Convert(m, result.Type)),
Ex.PostDecrementAssign(i),
Ex.Goto(loopstart));
var block = Ex.Block(new[] { result, i, m },
Ex.Assign(result, Ex.Convert(Ex.Constant(0), to)),
Ex.Assign(i, Ex.MakeBinary(ExpressionType.Subtract, Ex.Property(input, nameof(string.Length)), Ex.Constant(1))),
loop,
Ex.Label(end, NoResult(to)));
return(Ex.Lambda(block, input));
}