private static TypeDefinition buildTypeOfLambda(ComputationContext ctx, FunctionDefinition lambda, IEnumerable <VariableDeclaration> fields) { if (lambda.Owner != null) { throw new Exception("Internal error"); } FunctionDefinition cons = FunctionDefinition.CreateInitConstructor(EntityModifier.None, fields.Select(it => FunctionParameter.Create(it.Name.Name, it.TypeName)), Block.CreateStatement( fields.Select(it => Assignment.CreateStatement(NameReference.Create(NameFactory.ThisVariableName, it.Name.Name), NameReference.Create(it.Name.Name))) )); lambda.SetModifier(EntityModifier.Override | lambda.Modifier); TypeDefinition functor = TypeBuilder.Create(NameDefinition.Create(AutoName.Instance.CreateNew("Closure"))) .With(fields) .With(cons) .With(lambda) .Parents(lambda.CreateFunctionInterface()); return(functor); }
private static TypeDefinition buildTypeOfReference(ComputationContext ctx, NameReference funcReference, IExpression thisObject) { if (funcReference.Owner != null) { throw new Exception("Detach it first."); } const string meta_this = "mThis"; FunctionDefinition function = funcReference.Binding.Match.Instance.Target.CastFunction(); FunctionDefinition cons; NameReference func_field_ref; if (thisObject != null) { cons = FunctionDefinition.CreateInitConstructor(EntityModifier.None, new[] { FunctionParameter.Create(meta_this, thisObject.Evaluation.Components.NameOf) }, Block.CreateStatement( new[] { Assignment.CreateStatement(NameReference.Create(NameFactory.ThisVariableName, meta_this), NameReference.Create(meta_this)), })); func_field_ref = NameReference.Create(NameFactory.ThisVariableName, meta_this); } else { func_field_ref = null; cons = null; } IEnumerable <FunctionParameter> trans_parameters = function.Parameters.Select(pit => FunctionParameter.Create(pit.Name.Name, pit.TypeName.Evaluated(ctx, EvaluationCall.AdHocCrossJump) .TranslateThrough(funcReference.Binding.Match.Instance).NameOf)); FunctionDefinition invoke = FunctionBuilder.Create(NameFactory.LambdaInvoke, ExpressionReadMode.ReadRequired, function.ResultTypeName, Block.CreateStatement(new[] { Return.Create(FunctionCall.Create( NameReference.Create(func_field_ref, funcReference.Name, funcReference.TemplateArguments.Select(it => it.TypeName).ToArray()), function.Parameters.Select(it => FunctionArgument.Create(NameReference.Create(it.Name.Name))).ToArray())) })) .SetModifier(EntityModifier.Override) .Parameters(trans_parameters.ToArray()); TypeBuilder closure_builder = TypeBuilder.Create(NameDefinition.Create(AutoName.Instance.CreateNew("Closure"))) .With(invoke) .Parents(invoke.CreateFunctionInterface()); if (thisObject != null) { VariableDeclaration this_field = VariableDeclaration.CreateStatement(meta_this, thisObject.Evaluation.Components.NameOf, Undef.Create()); closure_builder .With(cons) .With(this_field); TypeMutability mutability = thisObject.Evaluation.Components.MutabilityOfType(ctx); if (mutability == TypeMutability.ForceMutable) { closure_builder.SetModifier(EntityModifier.Mutable); } else if (mutability != TypeMutability.ConstAsSource) { throw new NotImplementedException(); } } return(closure_builder); }