Beispiel #1
0
        internal override IEnumerable <Instruction> Compile()
        {
            List <InternalLambdaDescription> constructorOverloads = new List <InternalLambdaDescription>();

            if (ParameterFields != null)
            {
                constructorOverloads.Add(new InternalLambdaDescription
                {
                    argTypes     = ParameterFields.Select(param => param.Type.GetIndicatedType()).ToArray(),
                    returnType   = Type,
                    closureSize  = Type.numSlots,
                    stackSize    = ConstructorStackSize,
                    instructions = CompileConstructor(null).ToArray()
                });
            }

            foreach (FunctionDefinition constructor in Constructors)
            {
                constructorOverloads.Add(new InternalLambdaDescription
                {
                    argTypes     = constructor.Parameters.Select(param => param.Type.GetIndicatedType()).ToArray(),
                    returnType   = Type,
                    closureSize  = Type.numSlots,
                    stackSize    = ConstructorStackSize,
                    instructions = CompileConstructor(constructor).ToArray()
                });
            }

            List <Instruction> instructions = new List <Instruction>();

            instructions.AddRange(
                new Instruction[]
            {
                new BuildInternalLambdasInstruction(constructorOverloads.ToArray()),
                new AssignConstructorLambdaInstruction(Type),
                new LoadConstantInstruction(Type),
                Compiler.CompileVariableAssign(DeclaredVariable)
            }
                );

            for (int i = 0; i < StaticOverloads.Count; i++)
            {
                OverloadGroup overload = StaticOverloads[i];
                instructions.AddRange(overload.Compile());
                instructions.Add(Compiler.CompileVariableLookup(overload.variable));
                instructions.Add(new SetStaticOverloadInstruction(Type, i));
            }
            return(instructions);
        }
Beispiel #2
0
        private void DefineFunction(LeafParser.Def_funcContext def, LeafParser.Attribute_addContext[]?attribs)
        {
            var decl = def.function_decl();
            var impl = def.function_impl();
            var name = def.Id().GetText();

            try
            {
                var func = DefineFunction(name, decl, impl, def.generic_def_list(), attribs);

                if (!Namespace.Functions.TryGetValue(name, out var group))
                {
                    group = new OverloadGroup(name, Namespace);
                    Namespace.Functions.Add(name, group);
                }

                group.AddImplementation(func);
            }
            catch (CompilationException e)
            { throw new CompilationException($"Could not compile function '{name}'.", this, def.Start.Line, e); }
        }
Beispiel #3
0
 public DuplicateFunctionOverloadException(OverloadGroup overloads, IReadOnlyList <Type> types, Fragment?fragment = null)
     : base($"Duplicate definition of function {overloads}({string.Join(", ", types)}).", fragment)
 {
 }
Beispiel #4
0
 public FunctionOverloadNotFoundException(OverloadGroup overloads, IReadOnlyList <Type> types, Fragment?fragment = null)
     : base($"Function overload {overloads.Name}({string.Join(", ", types)}) does not exist.", fragment)
 {
 }
Beispiel #5
0
        internal override void Bind(Binder binder)
        {
            // TODO: Base type binding?
            base.Bind(binder);

            // Bind using local variables when building the global context
            // so that the lambdas can be available immediately when the
            // module is initialized.
            Type.staticLambdas   = new Lambda[StaticOverloads.Count];
            Type.staticSlotTypes = new RedwoodType[StaticOverloads.Count];
            Type.staticSlotMap   = new Dictionary <string, int>();

            // TODO: Is it okay to make these temporary?
            binder.Bookmark();

            foreach (FunctionDefinition method in StaticMethods)
            {
                method.Bind(binder);
            }

            for (int i = 0; i < StaticOverloads.Count; i++)
            {
                OverloadGroup overload = StaticOverloads[i];
                overload.DoBind(binder);

                Type.staticSlotTypes[i]           = overload.variable.KnownType;
                Type.staticSlotMap[overload.name] = i;
            }
            binder.Checkout();

            binder.EnterFullScope();

            binder.Bookmark();
            if (ParameterFields != null)
            {
                foreach (ParameterDefinition parameterField in ParameterFields)
                {
                    parameterField.Bind(binder);
                }
            }
            binder.Checkout();

            // We need to support a variable number of arguments
            // because all constructors are compiled to the same
            // thing
            foreach (Variable argVariable in TempArgumentVariables)
            {
                binder.BindVariable(argVariable);
            }

            foreach (FunctionDefinition constructor in Constructors)
            {
                constructor.Bind(binder);
            }

            binder.BindVariable(This);

            foreach (LetDefinition field in InstanceFields)
            {
                field.Bind(binder);
            }

            foreach (FunctionDefinition method in Methods)
            {
                method.Bind(binder);
            }

            foreach (Variable implicitConversionVariable in InterfaceImplicitConversionVars)
            {
                binder.BindVariable(implicitConversionVariable);
            }

            foreach (OverloadGroup overload in Overloads)
            {
                overload.DoBind(binder);

                RedwoodType[][] signatures = overload
                                             .definitions
                                             .Select(def =>
                                                     def.Parameters.Select(param => param.Type.GetIndicatedType()).ToArray()
                                                     )
                                             .ToArray();

                int[] slots = overload
                              .definitions
                              .Select(def => def.DeclaredVariable.Location)
                              .ToArray();

                Type.overloadsMap[overload.variable.Location] =
                    new Tuple <RedwoodType[][], int[]>(signatures, slots);
            }


            // Since our class is just a closure
            Type.numSlots = binder.GetClosureSize();

            Type.slotMap   = new Dictionary <string, int>();
            Type.slotTypes = new RedwoodType[Type.numSlots];

            Type.implicitConversionMap = new Dictionary <RedwoodType, int>();
            // Ensure that even though the overloads are hidden, they
            // are still represented in the slot map
            foreach (FunctionDefinition method in Methods)
            {
                Type.slotTypes[method.DeclaredVariable.Location] = method.DeclaredVariable.KnownType;
                if (method.Name == "op_Implicit")
                {
                    Type.implicitConversionMap[method.ReturnType.GetIndicatedType()] = method.DeclaredVariable.Location;
                }
            }

            for (int i = 0; i < MemberVariables.Count; i++)
            {
                Variable var  = MemberVariables[i];
                int      slot = var.Location;
                Type.slotTypes[slot]   = var.KnownType;
                Type.slotMap[var.Name] = slot;
            }

            Type.Interfaces = Interfaces
                              .Select(typeSyntax => typeSyntax.GetIndicatedType())
                              .ToArray();
            for (int i = 0; i < Interfaces.Length; i++)
            {
                RedwoodType interfaceType = Interfaces[i].GetIndicatedType();
                // If the user wrote a custom op_Implicit to an interface, respect
                // that instead of this conversion
                if (!Type.implicitConversionMap.ContainsKey(interfaceType))
                {
                    Type.implicitConversionMap[interfaceType] = InterfaceImplicitConversionVars[i].Location;
                }
            }

            ConstructorStackSize = binder.LeaveFullScope();
        }