public PseudoScope(Scope parent, GenericPrototype genProto) : this(parent) { for(int i = 0; i < genProto.GetPlaceHolderCount(); ++i) { PlaceHolderType placeHolder = genProto.GetPlaceHolder(i); AddAlias(placeHolder.GetName(), placeHolder); } }
protected Function(ChelaModule module) : base(module) { this.name = string.Empty; this.flags = MemberFlags.Default; this.parentScope = null; this.basicBlocks = new List<BasicBlock> (); this.lexicalScopes = new List<LexicalScope>(); this.locals = new List<LocalVariable> (); this.position = null; this.exceptionContext = null; this.returnBlock = null; this.returningVar = null; this.returnValueVar = null; this.genericPrototype = GenericPrototype.Empty; this.arguments = null; }
private void CreateDefaultConstructor(StructDefinition node) { // Get the structure. Structure building = node.GetStructure(); // Check for an user defined constructor. if (building.GetConstructor() != null) { return; } // Instance the building. GenericPrototype contGenProto = building.GetGenericPrototype(); int templateArgs = contGenProto.GetPlaceHolderCount(); Structure buildingInstance = building; if (templateArgs != 0) { IChelaType[] thisArgs = new IChelaType[templateArgs]; for (int i = 0; i < templateArgs; ++i) { thisArgs[i] = contGenProto.GetPlaceHolder(i); } buildingInstance = (Structure)building.InstanceGeneric( new GenericInstance(contGenProto, thisArgs), currentModule); } // Create the default constructor function type. List <IChelaType> arguments = new List <IChelaType> (); arguments.Add(ReferenceType.Create(buildingInstance)); FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), arguments); // Create the constructor method. MemberFlags flags = MemberFlags.Public | MemberFlags.Constructor; Method constructor = new Method(building.GetName(), flags, building); constructor.SetFunctionType(ctorType); // Store it. building.AddFunction("<ctor>", constructor); node.SetDefaultConstructor(constructor); }
public virtual Structure FindType(string name, GenericPrototype prototype) { // Find the member. ScopeMember member = FindMember(name); if(member == null) return null; // Use the matching type in the type group. if(member.IsTypeGroup()) { TypeGroup group = (TypeGroup)member; return group.Find(prototype); } else if(!member.IsClass() && !member.IsInterface() && !member.IsStructure()) throw new ModuleException("found no structural type " + member.GetFullName()); // Cast the member. return (Structure) member; }
private IChelaType GenericCoercion(AstNode where, IChelaType argType, IChelaType argExpType, GenericPrototype genProto, IChelaType[] genericArgumentsSoFar, out int argCoercions) { argCoercions = 0; return null; }
public void SetPrototype(GenericPrototype prototype) { this.prototype = prototype; }
protected bool CheckGenericArguments(AstNode where, GenericPrototype prototype, IChelaType[] arguments) { // The argument count must match. if(prototype.GetPlaceHolderCount() != arguments.Length) return TryError(where, "not matching generic argument count."); // Check each argument. for(int i = 0; i < arguments.Length; ++i) { // Get the placeholder and the type. PlaceHolderType placeHolder = prototype.GetPlaceHolder(i); IChelaType argument = arguments[i]; // Check for value types. if(placeHolder.IsValueType() && !argument.IsFirstClass() && !argument.IsStructure() && !argument.IsPlaceHolderType()) return TryError(where, "the generic argument number {0} must be a value type.", i+1); // Get the argument structure. Structure argumentBuilding = null; if(argument.IsClass() || argument.IsStructure() || argument.IsInterface()) argumentBuilding = (Structure)argument; else if(argument.IsFirstClass()) argumentBuilding = currentModule.GetAssociatedClass(argument); else if(argument.IsPointer()) { // TODO: Support pointers. argumentBuilding = currentModule.GetAssociatedClass(ChelaType.GetSizeType()); } else if(argument.IsPlaceHolderType()) { // Check the place holder. if(CheckGenericPlaceArgument(where, placeHolder, (PlaceHolderType)argument)) continue; else return false; } else return TryError(where, "cannot get class for type {0}", argument.GetDisplayName()); // Check for constraints. for(int j = 0; j < placeHolder.GetBaseCount(); ++j) { // Get the base building. Structure baseBuilding = placeHolder.GetBase(j); // If the argument is the base pass. if(argumentBuilding == baseBuilding) continue; // If the base is a class, check for inheritance. if(baseBuilding.IsClass() && argumentBuilding.IsDerivedFrom(baseBuilding)) continue; // If the base is a interface, check for implementation. if(baseBuilding.IsInterface() && argumentBuilding.Implements(baseBuilding)) continue; // The constraint couldn't be satisfied. return TryError(where, "generic argument {0} of type {1} doesn't support constraint {2}", i+1, argumentBuilding.GetDisplayName(), baseBuilding.GetDisplayName()); } } return true; }
public override AstNode Visit(GenericSignature node) { // Visit the constraints first. AstNode child = node.GetConstraints(); while(child != null) { GenericConstraint constraint = (GenericConstraint)child; constraint.SetSignature(node); constraint.Accept(this); // Visit the next constraint. child = child.GetNext(); } // Visit the generic parameters. child = node.GetParameters(); List<PlaceHolderType> placeholders = new List<PlaceHolderType> (); while(child != null) { // Visit the child. child.Accept(this); // Store the child type. placeholders.Add((PlaceHolderType)child.GetNodeType()); // Visit the next parameter. child = child.GetNext(); } // Create the generic prototype. GenericPrototype prototype = new GenericPrototype(placeholders); node.SetPrototype(prototype); return node; }
internal override void Read(ModuleReader reader, MemberHeader header) { // Read the function header. FunctionHeader fheader = new FunctionHeader(); fheader.Read(reader); // Read the function type. type = (FunctionType)GetModule().GetType(fheader.functionType); // Read the generic prototype. genericPrototype = GenericPrototype.Read(reader, GetModule()); // Read the vslot. if(IsMethod()) { Method method = (Method)this; method.vslot = fheader.vslot; } // Skip the elements. reader.Skip(header.memberSize - FunctionHeader.HeaderSize - genericPrototype.GetSize()); }
public void SetGenericPrototype(GenericPrototype genericPrototype) { this.genericPrototype = genericPrototype; }
public Structure Find(GenericPrototype prototype) { TypeGroupName gname = new TypeGroupName(null, prototype); TypeGroupName res = types.Find(gname); if(res != null) return res.GetBuilding(); return null; }
public GenericPrototype GetFullGenericPrototype() { // Return the cached generic prototype. if(fullGenericPrototype != null) return fullGenericPrototype; // Get the parent full generic prototype. GenericPrototype parentFull = null; Scope parent = GetParentScope(); if(parent != null) parentFull = parent.GetFullGenericPrototype(); // Get my generic prototype. GenericPrototype myPrototype = GetGenericPrototype(); if(myPrototype == null || myPrototype.GetPlaceHolderCount() == 0) { fullGenericPrototype = parentFull; } else if(parentFull == null || parentFull.GetPlaceHolderCount() == 0) { fullGenericPrototype = myPrototype; } else { // Merge both prototypes int parentSize = parentFull.GetPlaceHolderCount(); int mySize = myPrototype.GetPlaceHolderCount(); PlaceHolderType[] newProto = new PlaceHolderType[parentSize + mySize]; // Add the parent prototype components. for(int i = 0; i < parentSize; ++i) newProto[i] = parentFull.GetPlaceHolder(i); // Add my prototype components. for(int i = 0; i < mySize; ++i) newProto[i + parentSize] = myPrototype.GetPlaceHolder(i); // Store the new complete generic prototype. fullGenericPrototype = new GenericPrototype(newProto); } return fullGenericPrototype; }
public override AstNode Visit(DelegateDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if (genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), GenericPrototype.Empty); if (old != null) { Error(node, "trying to redefine a delegate."); } // Create the structure MemberFlags flags = node.GetFlags(); // TODO: Check the flags. Class building = new Class(node.GetName(), flags, currentContainer); building.SetGenericPrototype(genProto); building.Position = node.GetPosition(); node.SetStructure(building); // Add into the current scope. if (currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(building); } else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(building); } else { Error(node, "unexpected place for a delegate."); } // Register the compute binding delegate. if (building.GetFullName() == "Chela.Compute.ComputeBinding") { currentModule.RegisterComputeBindingDelegate(building); } return(node); }
public override AstNode Visit(InterfaceDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if (genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if (old != null) { Error(node, "trying to redefine a class."); } // Create the structure Interface iface = new Interface(node.GetName(), node.GetFlags(), currentContainer); iface.SetGenericPrototype(genProto); node.SetStructure(iface); iface.Position = node.GetPosition(); // Register type maps. string fullName = iface.GetFullName(); IChelaType alias; if (typeMaps.TryGetValue(fullName, out alias)) { currentModule.RegisterTypeMap(alias, ReferenceType.Create(iface)); } // Register some important interfaces. if (fullName == "Chela.Lang.NumberConstraint") { currentModule.RegisterNumberConstraint(iface); } else if (fullName == "Chela.Lang.IntegerConstraint") { currentModule.RegisterIntegerConstraint(iface); } else if (fullName == "Chela.Lang.FloatingPointConstraint") { currentModule.RegisterFloatingPointConstraint(iface); } else if (fullName == "Chela.Collections.IEnumerable") { currentModule.RegisterEnumerableIface(iface); } else if (fullName == "Chela.Collections.IEnumerator") { currentModule.RegisterEnumeratorIface(iface); } else if (fullName.StartsWith("Chela.Collections.Generic.IEnumerable<")) { currentModule.RegisterEnumerableGIface(iface); } else if (fullName.StartsWith("Chela.Collections.Generic.IEnumerator<")) { currentModule.RegisterEnumeratorGIface(iface); } // Use the prototype scope. if (protoScope != null) { PushScope(protoScope); } // Add into the current scope. if (currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(iface); } else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(iface); } else { Error(node, "unexpected place for a class."); } // Push the interface unsafe. if (iface.IsUnsafe()) { PushUnsafe(); } // Update the scope. PushScope(iface); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Restore the generic scope. if (protoScope != null) { PopScope(); } // Pop the interface unsafe. if (iface.IsUnsafe()) { PopUnsafe(); } return(node); }
public override AstNode Visit(ClassDefinition node) { // Check the partial flag. bool isPartial = (node.GetFlags() & MemberFlags.ImplFlagMask) == MemberFlags.Partial; // Add the parent static flag. if (currentContainer.IsStatic()) { MemberFlags oldInstance = node.GetFlags() & MemberFlags.InstanceMask; if (oldInstance == MemberFlags.Static || oldInstance == MemberFlags.Instanced) { MemberFlags flags = node.GetFlags() & ~MemberFlags.InstanceMask; node.SetFlags(flags | MemberFlags.Static); } else { Error(node, "static class member cannot be {0}.", oldInstance.ToString().ToLower()); } } // Static classes are automatically sealed. if ((node.GetFlags() & MemberFlags.InstanceMask) == MemberFlags.Static) { MemberFlags flags = node.GetFlags() & ~MemberFlags.InheritanceMask; node.SetFlags(flags | MemberFlags.Sealed); } // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if (genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if (old != null && (!isPartial || !old.IsClass())) { Error(node, "trying to redefine a class."); } // Create the structure Class clazz = (Class)old; if (clazz != null) { if (!clazz.IsPartial()) { Error(node, "incompatible partial class definitions."); } } else { clazz = new Class(node.GetName(), node.GetFlags(), currentContainer); clazz.Position = node.GetPosition(); clazz.SetGenericPrototype(genProto); } node.SetStructure(clazz); // Use the prototype scope. if (protoScope != null) { PushScope(protoScope); } // Register type maps. string fullName = clazz.GetFullName(); IChelaType alias; if (typeMaps.TryGetValue(fullName, out alias)) { currentModule.RegisterTypeMap(alias, clazz); } // Register type association. IChelaType assoc; if (assocClasses.TryGetValue(fullName, out assoc)) { currentModule.RegisterAssociatedClass(assoc, clazz); } // Array base class is special. if (fullName == "Chela.Lang.Array") { currentModule.RegisterArrayClass(clazz); } else if (fullName == "Chela.Lang.Attribute") { currentModule.RegisterAttributeClass(clazz); } else if (fullName == "Chela.Lang.ValueType") { currentModule.RegisterValueTypeClass(clazz); } else if (fullName == "Chela.Lang.Enum") { currentModule.RegisterEnumClass(clazz); } else if (fullName == "Chela.Lang.Type") { currentModule.RegisterTypeClass(clazz); } else if (fullName == "Chela.Lang.Delegate") { currentModule.RegisterDelegateClass(clazz); } else if (fullName == "Chela.Compute.StreamHolder") { currentModule.RegisterStreamHolderClass(clazz); } else if (fullName == "Chela.Compute.StreamHolder1D") { currentModule.RegisterStreamHolder1DClass(clazz); } else if (fullName == "Chela.Compute.StreamHolder2D") { currentModule.RegisterStreamHolder2DClass(clazz); } else if (fullName == "Chela.Compute.StreamHolder3D") { currentModule.RegisterStreamHolder3DClass(clazz); } else if (fullName == "Chela.Compute.UniformHolder") { currentModule.RegisterUniformHolderClass(clazz); } // Add into the current scope. if (currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; if (old == null) { space.AddType(clazz); } } else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; if (old == null) { parent.AddType(clazz); } } else { Error(node, "unexpected place for a class."); } // Push the class unsafe. if (clazz.IsUnsafe()) { PushUnsafe(); } // Update the scope. PushScope(clazz); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Restore the scope. if (protoScope != null) { PopScope(); } // Pop the class unsafe. if (clazz.IsUnsafe()) { PopUnsafe(); } return(node); }
public override AstNode Visit(StructDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if (genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), genProto); if (old != null) { Error(node, "trying to redefine a struct."); } // Create the structure Structure building = new Structure(node.GetName(), node.GetFlags(), currentContainer); building.SetGenericPrototype(genProto); node.SetStructure(building); building.Position = node.GetPosition(); // Use the prototype scope. if (protoScope != null) { PushScope(protoScope); } // Register type association. string fullName = building.GetFullName(); IChelaType assoc; if (assocClasses.TryGetValue(fullName, out assoc)) { currentModule.RegisterAssociatedClass(assoc, building); } // Add into the current scope. if (currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(building); } else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(building); } else { Error(node, "unexpected place for a structure."); } // Push the building unsafe. if (building.IsUnsafe()) { PushUnsafe(); } // Update the scope. PushScope(building); // Visit the building children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Pop the building unsafe. if (building.IsUnsafe()) { PopUnsafe(); } // Restore the prototype scope. if (protoScope != null) { PopScope(); } return(node); }