public AttributeConstant(Class attributeClass, Method attributeCtor) { this.attributeClass = attributeClass; this.attributeCtor = attributeCtor; this.ctorArguments = new List<ConstantValue> (); this.propertyValues = new List<PropertyValue> (); }
public NewExpression(Expression typeExpression, Expression arguments, TokenPosition position) : base(position) { this.typeExpression = typeExpression; this.arguments = arguments; this.constructor = null; this.objectType = null; }
public StructDefinition(MemberFlags flags, string name, GenericSignature genericSignature, AstNode bases, AstNode children, TokenPosition position) : base(children, position) { SetName(name); this.flags = flags; this.bases = bases; this.genericSignature = genericSignature; this.defaultConstructor = null; this.genericScope = null; }
private Method CreateTrivialConstructor(Structure building, Structure buildingInstance) { // Create the constructor function type. FunctionType type = FunctionType.Create(ChelaType.GetVoidType(), new IChelaType[]{ReferenceType.Create(buildingInstance)}, false); // Create the constructor. Method ctor = new Method(".ctor", MemberFlags.Public | MemberFlags.Constructor, building); ctor.SetFunctionType(type); building.AddFunction(".ctor", ctor); // Create the constructor block. BasicBlock top = new BasicBlock(ctor); top.SetName("top"); top.Append(new Instruction(OpCode.RetVoid, null)); return ctor; }
private void CreateDefaultStaticConstructor(StructDefinition node) { // Get the structure. Structure building = node.GetStructure(); // Check for an user defined constructor. if(building.GetStaticConstructor() != null) return; // Get the static initialization fields. List<FieldDeclaration> staticInitedField = new List<FieldDeclaration> (); bool isUnsafe = false; foreach(FieldDeclaration decl in building.GetFieldInitializations()) { Variable variable = decl.GetVariable(); if(variable.IsStatic()) { staticInitedField.Add(decl); if(variable.IsUnsafe()) isUnsafe = true; } } // If there aren't field to initialize, don't create the static constructor. if(staticInitedField.Count == 0) return; // Begin the node. builder.BeginNode(node); // Create the static constructor function type. FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType()); // Create the constructor method. MemberFlags flags = MemberFlags.StaticConstructor; if(isUnsafe) flags |= MemberFlags.Unsafe; Method constructor = new Method("<sctor>", flags, building); constructor.SetFunctionType(ctorType); // Store it. building.AddFunction("<sctor>", constructor); // Create the constructor scope. LexicalScope ctorScope = CreateLexicalScope(node, constructor); PushScope(ctorScope); // Create the top basic block. BasicBlock topBlock = new BasicBlock(constructor); builder.SetBlock(topBlock); // Initialize the static fields. GenerateStaticFieldInitializations(node, staticInitedField); // Restore the scope. PopScope(); // Return void. builder.CreateRetVoid(); // End the node. builder.EndNode(); }
private void CreateGenerator_Reset(FunctionDefinition node) { // Get the generator class. Class genClass = node.GeneratorClass; // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false); // Create the method. Method method = new Method("Reset", MemberFlags.Public, genClass); method.SetFunctionType(functionType); genClass.AddFunction("Reset", method); // Create the top block. BasicBlock top = new BasicBlock(method); builder.SetBlock(top); // Throw an exception. Class excpt = (Class)ExtractClass(node, currentModule.GetLangMember("InvalidOperationException")); builder.CreateLoadString("IEnumerator.Reset cannot be called in generators."); builder.CreateNewObject(excpt, GetExceptionCtor(node, excpt), 1); builder.CreateThrow(); }
private void CreateImplicitBaseConstructor(AstNode node, Method function) { Function parentConstructor = function.GetCtorParent(); if(parentConstructor != null && function.GetParentScope().IsStructure() == parentConstructor.GetParentScope().IsStructure()) { builder.CreateLoadArg(0); builder.CreateCall(parentConstructor, 1); } }
private void CreateGenerator_GetEnumerator(FunctionDefinition node, Structure enumeratorType, bool generic) { // Get the generator class. Class genClass = node.GeneratorClass; // Use the GetEnumerator name for the most specific version. string name = "GetEnumerator"; Function contract = null; if(!generic && node.IsGenericIterator) { name = GenSym(); contract = FindFirstConstract(currentModule.GetEnumerableIface(), "GetEnumerator"); } // Create the function type. FunctionType functionType = FunctionType.Create(ReferenceType.Create(enumeratorType), new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false); // Create the method. Method method = new Method(name, MemberFlags.Public, genClass); method.SetFunctionType(functionType); genClass.AddFunction(name, method); // Set the explicit contract. if(contract != null) method.SetExplicitContract(contract); // Create the method block. BasicBlock block = new BasicBlock(method); block.SetName("top"); // Return this. builder.SetBlock(block); builder.CreateLoadArg(0); builder.CreateRet(); }
private Function CreateGenerator_MoveNext(FunctionDefinition node) { // Get the generator class. Class genClass = node.GeneratorClass; // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetBoolType(), new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false); // Create the method. Method method = new Method("MoveNext", MemberFlags.Public, genClass); method.SetFunctionType(functionType); method.DefinitionNode = node; genClass.AddFunction("MoveNext", method); // Swap the exception contexts. method.SwapExceptionContexts(currentFunction); // Store the old function. Function oldFunction = currentFunction; currentFunction = method; // Create the jump table block. BasicBlock jmpBlock = CreateBasicBlock(); jmpBlock.SetName("jmp"); // Generate the main code. BasicBlock topBlock = CreateBasicBlock(); topBlock.SetName("top"); builder.SetBlock(topBlock); // Prepare returning. LexicalScope topScope = (LexicalScope) node.GetScope(); PrepareReturning(node, currentFunction, topScope); // Create the function body. VisitList(node.GetChildren()); // Finish returning. FinishReturn(node, currentFunction); // Create the state jump table. builder.SetBlock(jmpBlock); // Load the current state. builder.CreateLoadArg(0); builder.CreateLoadField(node.GeneratorState); // Build the jump table. int numstates = node.Yields.Count*2+3; int[] stateConstants = new int[numstates]; BasicBlock[] stateEntries = new BasicBlock[numstates]; // The default case is return. stateConstants[0] = -1; stateEntries[0] = currentFunction.ReturnBlock; // The first state is the top block. stateConstants[1] = 0; stateEntries[1] = topBlock; // The second state is the return block. stateConstants[2] = 1; stateEntries[2] = currentFunction.ReturnBlock; // The next states are the yield merges followed by yield disposes. for(int i = 0; i < node.Yields.Count; ++i) { ReturnStatement yieldStmnt = node.Yields[i]; // Emit the merge state. int stateId = i*2+2; int entryIndex = stateId+1; stateConstants[entryIndex] = stateId; stateEntries[entryIndex] = yieldStmnt.MergeBlock; // Emit the dispose state. stateConstants[entryIndex+1] = stateId+1; stateEntries[entryIndex+1] = yieldStmnt.DisposeBlock; } builder.CreateSwitch(stateConstants, stateEntries); // Restore the old function. currentFunction = oldFunction; return method; }
public void SetDefaultConstructor(Method constructor) { defaultConstructor = constructor; }
private void CheckDefaultConstructorInit(AstNode node, Method function) { // Get the base building. Structure building = (Structure)function.GetParentScope(); Structure baseBuilding = building.GetBase(); if(baseBuilding == null) return; // Object class. // Find a default construcotor. FunctionGroup ctorGroup = baseBuilding.GetConstructor(); Method ctor = null; foreach(FunctionGroupName ctorName in ctorGroup.GetFunctions()) { // Ignore static constructors. if(ctorName.IsStatic()) continue; // Check the constructor type. FunctionType ctorType = ctorName.GetFunctionType(); if(ctorType.GetArgumentCount() == 1) { // Found, the first argument must be "this". ctor = (Method)ctorName.GetFunction(); break; } } // If not found, raise error. if(ctor == null) Error(node, baseBuilding.GetFullName() + " doesn't have a default constructor."); // Store the default constructor. function.SetCtorParent(ctor); }
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 void SetConstructor(Method method) { this.constructor = method; }
public override AstNode Visit(EventAccessorDefinition node) { EventVariable eventVariable = node.GetEvent(); // Build the event flags. MemberFlags flags = node.GetFlags(); if(flags == MemberFlags.ImplicitVis) { flags = eventVariable.GetFlags(); } else { // TODO: Check compatibility. flags |= eventVariable.GetFlags() & ~MemberFlags.VisibilityMask; } // Get the instance type. MemberFlags instanceFlags = MemberFlags.InstanceMask & flags; // Abstract properties cannot have a body. if((instanceFlags == MemberFlags.Abstract || instanceFlags == MemberFlags.Contract) && node.GetChildren() != null) Error(node, "abstract events cannot have a definition body."); // Create the argument list. List<IChelaType> arguments = new List<IChelaType> (); // Add the this argument. IChelaType selfType = null; if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure) currentContainer; if(instanceFlags != MemberFlags.Static) { // Instance the building. building = building.GetSelfInstance(); // Create the self argument. selfType = ReferenceType.Create(building); arguments.Add(selfType); } } // Add the value argument. arguments.Add(eventVariable.GetVariableType()); // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), arguments, false); // Build the function name. string functionName = node.GetName() + "_" + eventVariable.GetName(); // Create the function. Function accessor; if(selfType != null) accessor = new Method(functionName, flags, currentContainer); else accessor = new Function(functionName, flags, currentContainer); // Set the arguments. accessor.SetFunctionType(functionType); // Set the function position. accessor.Position = node.GetPosition(); // Store the function in the event. if(node.GetName() == "add") eventVariable.AddModifier = accessor; else eventVariable.RemoveModifier = accessor; // Store the function in his scope. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction(functionName, accessor); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(accessor); } else { Error(node, "an event cannot be declared here."); } // If there's a body, declare the "argument" variables. if(node.GetChildren() != null) { LexicalScope scope = CreateLexicalScope(node, accessor); // Add the "this" local. if(selfType != null) new ArgumentVariable(0, "this", scope, selfType); // Add the "value" local LocalVariable valueVar = new LocalVariable("value", scope, eventVariable.GetVariableType()); node.SetValueLocal(valueVar); // Store the scope node.SetScope(scope); } // Set the node function to the accessor. node.SetFunction(accessor); return node; }
public override AstNode Visit(SetAccessorDefinition node) { PropertyVariable property = node.GetProperty(); if(node.GetChildren() == null && property.SetAccessor != null) return node; if(node.GetChildren() != null && property.SetAccessor != null) Error(node, "multiples definitions of the set accessor."); // Build the property flags. MemberFlags flags = node.GetFlags(); if(flags == MemberFlags.ImplicitVis) { flags = property.GetFlags(); } else { // TODO: Check compatibility. flags |= property.GetFlags() & ~MemberFlags.VisibilityMask; } // Get the instance type. MemberFlags instanceFlags = MemberFlags.InstanceMask & flags; // Abstract properties cannot have a body. if((instanceFlags == MemberFlags.Abstract || instanceFlags == MemberFlags.Contract) && node.GetChildren() != null) Error(node, "abstract properties cannot have a definition body."); // Create the set accesor. if(property.SetAccessor == null) { // Create the argument list. List<IChelaType> arguments = new List<IChelaType> (); // Add the this argument. IChelaType selfType = null; if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure) currentContainer; if(instanceFlags != MemberFlags.Static) { // Instance the building. building = building.GetSelfInstance(); // Create the self parameter. selfType = ReferenceType.Create(building); arguments.Add(selfType); } } // Append the indices. foreach(IChelaType indexType in property.Indices) arguments.Add(indexType); // Add the value argument. arguments.Add(property.GetVariableType()); // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), arguments, false); // Create the function. Function accessor; if(selfType != null) accessor = new Method("set_" + property.GetName(), flags, currentContainer); else accessor = new Function("set_" + property.GetName(), flags, currentContainer); // Set the arguments. accessor.SetFunctionType(functionType); // Set the function position. accessor.Position = node.GetPosition(); // Store the function in the property. property.SetAccessor = accessor; // Store the function in his scope. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction("set_" + property.GetName(), accessor); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(accessor); } else { Error(node, "a property cannot be declared here."); } // If there's a body, declare the "argument" variables. if(node.GetChildren() != null) { LexicalScope scope = CreateLexicalScope(node, accessor); // Add the "this" local. if(selfType != null) new ArgumentVariable(0, "this", scope, selfType); // Add the "value" local LocalVariable valueVar = new LocalVariable("value", scope, property.GetVariableType()); node.SetValueLocal(valueVar); // Add the indices variables. AstNode index = node.GetIndices(); List<LocalVariable> indexerVars = new List<LocalVariable> (); while(index != null) { // Create the local LocalVariable local = new LocalVariable(index.GetName(), scope, index.GetNodeType()); indexerVars.Add(local); // Process the next. index = index.GetNext(); } node.SetIndexerVariables(indexerVars); node.SetScope(scope); } } else { // Check for declaration compatibility. if(flags != property.SetAccessor.GetFlags()) Error(node, "incompatible set accessor declarations."); } // Set the node function to the accessor. node.SetFunction(property.SetAccessor); return node; }
public override AstNode Visit(FunctionPrototype node) { MemberFlags callingConvention = node.GetFlags() & MemberFlags.LanguageMask; bool isCdecl = callingConvention == MemberFlags.Cdecl; bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe; // Use the unsafe scope. if(isUnsafe) PushUnsafe(); // Generate a name for explicit contracts. if(node.GetNameExpression() != null) node.SetName(GenSym()); // Find an existing group. ScopeMember oldGroup = currentContainer.FindMember(node.GetName()); if(oldGroup != null && (oldGroup.IsType() || !oldGroup.IsFunctionGroup())) { if(oldGroup.IsFunction() && isCdecl) { // TODO: Add additional checks. Function oldDefinition = (Function)oldGroup; node.SetFunction(oldDefinition); node.SetNodeType(oldDefinition.GetFunctionType()); oldGroup = null; return node; } else Error(node, "cannot override something without a function group."); } FunctionGroup functionGroup = null; if(oldGroup != null) // Cast the group member. functionGroup = (FunctionGroup)oldGroup; // Make sure the destructor name is correct. if(node.GetDestructorName() != null) { // Get the building scope. Scope buildingScope = currentScope; while(buildingScope != null && (buildingScope.IsFunction() || buildingScope.IsPseudoScope() || buildingScope.IsLexicalScope())) buildingScope = buildingScope.GetParentScope(); // Make sure we are in a class. if(buildingScope == null || !buildingScope.IsClass()) Error(node, "only classes can have finalizers."); // Make sure the destructor and class name are the same. if(node.GetDestructorName() != buildingScope.GetName()) Error(node, "finalizers must have the same name as their class."); } // Read the instance flag. MemberFlags instanceFlags = node.GetFlags() & MemberFlags.InstanceMask; // Don't allow overloading with cdecl. if(isCdecl && functionGroup != null) Error(node, "overloading and cdecl are incompatible."); // Make sure static constructor doesn't have modifiers. if(instanceFlags == MemberFlags.StaticConstructor && node.GetFlags() != MemberFlags.StaticConstructor) Error(node, "static constructors cannot have modifiers."); // Static constructors cannot have paraemeters. if(instanceFlags == MemberFlags.StaticConstructor && node.GetArguments() != null) Error(node, "static constructors cannot have parameters."); // Add the this argument. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { // Cast the scope. Structure building = (Structure)currentContainer; // Add the this argument. if(instanceFlags != MemberFlags.Static && instanceFlags != MemberFlags.StaticConstructor) { // Instance the building. building = building.GetSelfInstance(); // Use the structure type. TypeNode thisType = new TypeNode(TypeKind.Reference, node.GetPosition()); thisType.SetOtherType(building); // Create the this argument. FunctionArgument thisArg = new FunctionArgument(thisType, "this", node.GetPosition()); // Add to the begin of the argument list. thisArg.SetNext(node.GetArguments()); node.SetArguments(thisArg); } } // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = null; PseudoScope protoScope = null; if(genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Create the placeholders scope. genProto = genericSign.GetPrototype(); protoScope = new PseudoScope(currentScope, genProto); node.SetScope(protoScope); } // Use the prototype scope. if(protoScope != null) PushScope(protoScope); // Visit the arguments. VisitList(node.GetArguments()); // Visit the return type. Expression returnTypeExpr = node.GetReturnType(); IChelaType returnType; if(returnTypeExpr != null) { // Don't allow the same name as the container. if((currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) && node.GetName() == currentContainer.GetName()) Error(node, "constructors cannot have a return type."); returnTypeExpr.Accept(this); returnType = returnTypeExpr.GetNodeType(); returnType = ExtractActualType(returnTypeExpr, returnType); // Use references for class/interface. if(returnType.IsPassedByReference()) returnType = ReferenceType.Create(returnType); } else if(node.GetDestructorName() != null) { returnType = ChelaType.GetVoidType(); } else { returnType = ChelaType.GetVoidType(); if(!currentContainer.IsStructure() && !currentContainer.IsClass()) Error(node, "only classes and structures can have constructors."); if(node.GetName() != currentContainer.GetName()) Error(node, "constructors must have the same name as their parent."); } // Restore the prototype scope. if(protoScope != null) PopScope(); // Create his function type. List<IChelaType> arguments = new List<IChelaType> (); bool variableArgs = false; // Add the argument types. AstNode argNode = node.GetArguments(); while(argNode != null) { // Cast the argument node. FunctionArgument funArg = (FunctionArgument)argNode; // Store the argument type. arguments.Add(funArg.GetNodeType()); // Set the variable argument flags. variableArgs = funArg.IsParams(); // Check the next argument. argNode = argNode.GetNext(); } // Set the function type. FunctionType type = FunctionType.Create(returnType, arguments, variableArgs, callingConvention); node.SetNodeType(type); // Check the function safetyness. if(type.IsUnsafe()) UnsafeError(node, "safe function with unsafe type."); // Avoid collisions. if(functionGroup != null) { Function ambiguos = functionGroup.Find(type, instanceFlags == MemberFlags.Static); if(ambiguos != null) Error(node, "adding ambiguous overload for " + ambiguos.GetFullName()); } // Create and add the method into his scope. Function function = null; if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { // Cast the scope. Structure building = (Structure) currentContainer; // Create the function according to his instance type. if(instanceFlags == MemberFlags.Static || instanceFlags == MemberFlags.StaticConstructor) { function = new Function(node.GetName(), node.GetFlags(), currentContainer); } else { Method method = new Method(node.GetName(), node.GetFlags(), currentContainer); function = method; // Check the constructor initializer. ConstructorInitializer ctorInit = node.GetConstructorInitializer(); if(ctorInit == null || ctorInit.IsBaseCall()) method.SetCtorLeaf(true); } // Set the function position. function.Position = node.GetPosition(); // Set the function type. function.SetFunctionType(type); // Add the function. try { building.AddFunction(node.GetName(), function); } catch(ModuleException error) { Error(node, error.Message); } } else if(currentContainer.IsNamespace()) { // Create the function. function = new Function(node.GetName(), node.GetFlags(), currentContainer); function.SetFunctionType(type); // Set the function position. function.Position = node.GetPosition(); // Add the method into his namespace. Namespace space = (Namespace) currentContainer; // Create the function group. if(functionGroup == null && !isCdecl) { functionGroup = new FunctionGroup(node.GetName(), currentContainer); oldGroup = functionGroup; space.AddMember(functionGroup); } // Add the function into the function group or the namespace. if(!isCdecl) functionGroup.Insert(function); else space.AddMember(function); } else { Error(node, "a function cannot be added here."); } // Store the generic prototype. if(genProto != null) function.SetGenericPrototype(genProto); // Set the node function. node.SetFunction(function); // Check for main function. if(function.IsStatic() && function.GetName() == "Main") CheckMainCandidate(node, function); // Create kernel entry point. if(function.IsKernel()) CreateKernelEntryPoint(node, function); // Restore the safety scope. if(isUnsafe) PopUnsafe(); return node; }
public override AstNode Visit(DelegateDefinition node) { // Check the security. bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe; if(isUnsafe) PushUnsafe(); // Get the delegate building. Structure building = node.GetStructure(); // Use the generic prototype. // Use the generic scope. PseudoScope genScope = node.GetGenericScope(); if(genScope != null) PushScope(genScope); // Visit the argument list. VisitList(node.GetArguments()); // Visit the return type. Expression returnTypeExpr = node.GetReturnType(); returnTypeExpr.Accept(this); IChelaType returnType = returnTypeExpr.GetNodeType(); returnType = ExtractActualType(returnTypeExpr, returnType); // Use references for class/interface. if(returnType.IsPassedByReference()) returnType = ReferenceType.Create(returnType); // Create the invoke function type. List<IChelaType> arguments = new List<IChelaType> (); // Add the argument types. AstNode argNode = node.GetArguments(); while(argNode != null) { arguments.Add(argNode.GetNodeType()); argNode = argNode.GetNext(); } // Create the function type. FunctionType functionType = FunctionType.Create(returnType, arguments); // Check the type security. if(functionType.IsUnsafe()) UnsafeError(node, "safe delegate with unsafe type."); // Create the invoke type. List<IChelaType> invokeArguments = new List<IChelaType> (); invokeArguments.Add(ReferenceType.Create(building)); for(int i = 0; i < arguments.Count; ++i) invokeArguments.Add(arguments[i]); FunctionType invokeType = FunctionType.Create(returnType, invokeArguments); // Create the constructor type. List<IChelaType> ctorArguments = new List<IChelaType> (); ctorArguments.Add(ReferenceType.Create(building)); ctorArguments.Add(ReferenceType.Create(currentModule.TypeMap(ChelaType.GetObjectType()))); ctorArguments.Add(ReferenceType.Create(functionType)); FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), ctorArguments); // Create the constructor method. Method ctorMethod = new Method("<ctor>", MemberFlags.Public | MemberFlags.Runtime | MemberFlags.Constructor, building); ctorMethod.SetFunctionType(ctorType); building.AddFunction("<ctor>", ctorMethod); // Create the invoke function. Method invokeMethod = new Method("Invoke", MemberFlags.Public | MemberFlags.Runtime, building); invokeMethod.SetFunctionType(invokeType); building.AddFunction("Invoke", invokeMethod); // Restore the scope. if(genScope != null) PopScope(); // Restore the security level. if(isUnsafe) PushUnsafe(); return node; }
private void CreateSimplifiedEventFunction(AstNode node, EventVariable eventVariable, FunctionType functionType, bool isAdd) { // Create the function name. string functionName = (isAdd ? "add_" : "remove_") + eventVariable.GetName(); // Create the function. Function function; if(functionType.GetArgumentCount() > 1) function = new Method(functionName, eventVariable.GetFlags(), currentContainer); else function = new Function(functionName, eventVariable.GetFlags(), currentContainer); // Set the function type. function.SetFunctionType(functionType); // Set the function position. function.Position = node.GetPosition(); // Store the function in the event. if(isAdd) eventVariable.AddModifier = function; else eventVariable.RemoveModifier = function; // Store the function in his container. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction(functionName, function); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(function); } else { Error(node, "an event cannot be declared here."); } }
private void CreateGenerator_Current(FunctionDefinition node, bool generic) { // Get the generator class. Class genClass = node.GeneratorClass; // Use the get_Current name for the most specific version. string name = "get_Current"; Function contract = null; if(!generic && node.IsGenericIterator) { name = GenSym(); contract = FindFirstConstract(currentModule.GetEnumeratorIface(), "get_Current"); } // Select the current type. IChelaType currentType = node.YieldType; if(!generic) currentType = ReferenceType.Create(currentModule.GetObjectClass()); // Create the function type. FunctionType functionType = FunctionType.Create(currentType, new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false); // Create the method. Method method = new Method(name, MemberFlags.Public, genClass); method.SetFunctionType(functionType); genClass.AddFunction(name, method); // Set the explicit contract. if(contract != null) method.SetExplicitContract(contract); // Create the method block. BasicBlock block = new BasicBlock(method); block.SetName("top"); // Create the return and error blocks. BasicBlock retBlock = new BasicBlock(method); retBlock.SetName("ret"); BasicBlock errorBlock = new BasicBlock(method); errorBlock.SetName("error"); // Make sure reset was called before the first Current. builder.SetBlock(block); builder.CreateLoadArg(0); builder.CreateLoadField(node.GeneratorState); builder.CreateLoadInt32(0); builder.CreateCmpEQ(); builder.CreateBr(errorBlock, retBlock); // Raise an error if reset wasn't called. builder.SetBlock(errorBlock); Class excpt = (Class)ExtractClass(node, currentModule.GetLangMember("InvalidOperationException")); builder.CreateLoadString("IEnumerator.MoveNext must be called before than IEnumerator.Current."); builder.CreateNewObject(excpt, GetExceptionCtor(node, excpt), 1); builder.CreateThrow(); // Load the yielded value. builder.SetBlock(retBlock); builder.CreateLoadArg(0); builder.CreateLoadField(node.YieldedValue); // Cast the yielded value. Cast(node, null, node.YieldType, currentType); // Return. builder.CreateRet(); }
private void CreateGenerator_Dispose(FunctionDefinition node, Function moveNext) { // Get the generator class. Class genClass = node.GeneratorClass; // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), new IChelaType[]{ReferenceType.Create(node.GeneratorClassInstance)}, false); // Create the method. Method method = new Method("Dispose", MemberFlags.Public, genClass); method.SetFunctionType(functionType); genClass.AddFunction("Dispose", method); // Create the top block. BasicBlock top = new BasicBlock(method); builder.SetBlock(top); // Create the return and dispose blocks. BasicBlock justReturn = new BasicBlock(method); BasicBlock disposeAndReturn = new BasicBlock(method); // Load the current state. builder.CreateLoadArg(0); builder.CreateDup1(); builder.CreateDup1(); builder.CreateLoadField(node.GeneratorState); builder.CreateDup1(); builder.CreateLoadInt32(1); builder.CreateCmpEQ(); builder.CreateBr(justReturn, disposeAndReturn); // Dispose and return implementation. builder.SetBlock(disposeAndReturn); // Increase the state. builder.CreateLoadInt32(1); builder.CreateAdd(); builder.CreateStoreField(node.GeneratorState); // Call move next. builder.CreateCall(moveNext, 1); builder.CreateRetVoid(); // Just return implementation. builder.SetBlock(justReturn); builder.CreateRetVoid(); }
public void SetAttributeConstructor(Method attributeConstructor) { this.attributeConstructor = attributeConstructor; }
private void CheckConstructorCycles(AstNode node, Method ctor) { Method current = ctor.GetCtorParent(); while(current != null) { // Don't continue checking when hitting a leaf. if(current.IsCtorLeaf()) return; // If the parent is equal to the start point, // a cycle has been found. if(current == ctor) Error(node, "constructor initializers produces a cycle."); // Check the next parent. current = current.GetCtorParent(); } }