private ExpressionContext CompileDereference(Compiler compiler, Frame frame, ExpressionContext left, Parse.BinaryExpression expression, Type.BaseType typeHint)
{
var local = compiler.AddFrame(frame, expression);
var native = left.ActualNative(compiler.Emitter);
LocalBuilder valueVariable = null;
// Create symbol for each tuple member
foreach (var a in ((TupleType)left.Type).Attributes)
{
var field = native.GetField(a.Key.ToString(), BindingFlags.Public | BindingFlags.Instance);
local.Add(expression, a.Key, field);
compiler.ContextsBySymbol.Add
(
field,
new ExpressionContext
(
null,
a.Value,
Characteristic.Default,
m =>
{
m.IL.Emit(OpCodes.Ldloc, valueVariable);
m.IL.Emit(OpCodes.Ldfld, field);
}
)
);
}
var right = compiler.CompileExpression(local, expression.Right, typeHint);
return
new ExpressionContext
(
expression,
right.Type,
Compiler.MergeCharacteristics(left.Characteristics, right.Characteristics),
m =>
{
m.IL.BeginScope();
left.EmitGet(m);
valueVariable = m.DeclareLocal(expression.Right, native, "value");
m.IL.Emit(OpCodes.Stloc, valueVariable);
right.EmitGet(m);
m.IL.EndScope();
}
);
}