internal override IEnumerable <Instruction> Compile() { List <Instruction> constructorInstructions = new List <Instruction>(); // For everything that isn't an overload group, we're going to // trust it as an argument and put it into our class closure. for (int i = 0; i < ArgumentVariables.Count; i++) { constructorInstructions.Add(Compiler.CompileVariableLookup(ArgumentVariables[i])); constructorInstructions.Add(Compiler.CompileVariableAssign(SuppliedVariables[i])); } foreach (OverloadGroup overload in Overloads) { if (overload.IsSingleMethod()) { continue; } int[] lambdaLocations = ArgumentVariables .Where(variable => variable.Name == overload.name) .Select(variable => variable.Location) .ToArray(); constructorInstructions.Add(new BuildLambdaGroupFromLambdasInstruction(lambdaLocations)); constructorInstructions.Add(Compiler.CompileVariableAssign(overload.variable)); } constructorInstructions.Add(new BuildRedwoodObjectFromClosureInstruction(Type)); constructorInstructions.Add(new ReturnInstruction()); InternalLambdaDescription constructorLambda = new InternalLambdaDescription { argTypes = SuppliedVariables .Select(argVar => null as RedwoodType) .ToArray(), returnType = Type, closureSize = Type.numSlots, stackSize = ArgumentVariables.Count, instructions = constructorInstructions.ToArray() }; return(new Instruction[] { new BuildInternalLambdaInstruction(constructorLambda), new AssignConstructorLambdaInstruction(Type), new LoadConstantInstruction(Type), Compiler.CompileVariableAssign(DeclaredVariable) }); }
public BuildInternalLambdaInstruction(InternalLambdaDescription description) { this.description = description; }
internal List <Instruction> CompileConstructor(FunctionDefinition constructor) { List <Instruction> instructions = new List <Instruction>(); instructions.Add(new BuildRedwoodObjectFromClosureInstruction(Type)); instructions.Add(Compiler.CompileVariableAssign(This)); if (ConstructorBase == null) { ConstructorBase = new List <Instruction>(); foreach (LetDefinition field in InstanceFields) { ConstructorBase.AddRange(field.Compile()); } foreach (FunctionDefinition method in Methods) { ConstructorBase.AddRange(method.Compile()); } for (int i = 0; i < Interfaces.Length; i++) { ConstructorBase.Add( new BuildInternalLambdaInstruction( CompileInterfaceConversion(Interfaces[i].GetIndicatedType()) ) ); ConstructorBase.Add( Compiler.CompileVariableAssign(InterfaceImplicitConversionVars[i]) ); } foreach (OverloadGroup method in Overloads) { if (!method.IsSingleMethod()) { ConstructorBase.AddRange(method.Compile()); } } } instructions.AddRange(ConstructorBase); // TODO: should these be mutually exclusive for a class? if (constructor == null) { foreach (ParameterDefinition paramField in ParameterFields) { instructions.AddRange(paramField.Compile()); } } else { InternalLambdaDescription constructorDescription = constructor.CompileInner(); int[] argLocations = new int[constructorDescription.argTypes.Length]; for (int i = 0; i < argLocations.Length; i++) { argLocations[i] = i; } instructions.Add(new BuildInternalLambdaInstruction(constructorDescription)); instructions.Add(new InternalCallInstruction(argLocations)); } instructions.Add(Compiler.CompileVariableLookup(This)); instructions.Add(new ReturnInstruction()); return(instructions); }