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); }
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); } }
public DuplicateFunctionOverloadException(OverloadGroup overloads, IReadOnlyList <Type> types, Fragment?fragment = null) : base($"Duplicate definition of function {overloads}({string.Join(", ", types)}).", fragment) { }
public FunctionOverloadNotFoundException(OverloadGroup overloads, IReadOnlyList <Type> types, Fragment?fragment = null) : base($"Function overload {overloads.Name}({string.Join(", ", types)}) does not exist.", fragment) { }
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(); }