示例#1
0
        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;
 }
示例#3
0
        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);
        }