public ConstantData(FieldVariable variable, Expression initializer) { this.variable = variable; this.initializer = initializer; this.dependencies = new List<ConstantData> (); this.visited = false; this.visiting = false; }
public void AddField(FieldVariable field) { // Store the field. fields.Add(field); // Register the position filename. TokenPosition pos = field.Position; if(pos == null) pos = NullPosition; AddFileName(pos.GetFileName()); }
public void AddField(FieldVariable field) { // Store the field. fields.Add(field); // Register the position filename. TokenPosition pos = field.Position; if (pos == null) { pos = NullPosition; } AddFileName(pos.GetFileName()); }
private void EmitFieldDebugInfo(ModuleWriter writer, FieldVariable field) { // Emit the field id. uint fieldId = field.GetSerialId(); writer.Write(fieldId); // Emit the field position. TokenPosition position = field.Position; if (position == null) { position = NullPosition; } EmitPosition(writer, position); }
public void SetVariable(FieldVariable variable) { this.variable = variable; }
public void CreateLoadFieldRef(FieldVariable field) { AppendInst1(OpCode.LoadFieldRef, field); }
public void CreateStoreField(FieldVariable field) { AppendInst1(OpCode.StoreField, field); }
private void PrepareReturning(AstNode where, Function function, LexicalScope scope) { // Get the definition node and check for generator. FunctionDefinition defNode = function.DefinitionNode; bool isGenerator = false; if(defNode != null) isGenerator = defNode.IsGenerator; // Use standard return. if(function.GetExceptionContext() == null && !isGenerator) return; // Create the return block. BasicBlock returnBlock = new BasicBlock(function); returnBlock.SetName("retBlock"); function.ReturnBlock = returnBlock; // Create the return value local. FunctionType functionType = function.GetFunctionType(); IChelaType retType = functionType.GetReturnType(); if(retType != ChelaType.GetVoidType() && !isGenerator) function.ReturnValueVar = new LocalVariable(GenSym() + "_retval", scope, retType); // Create the is returning flag. function.ReturningVar = new LocalVariable(GenSym() + "_isret", scope, ChelaType.GetBoolType(), isGenerator); function.ReturningVar.Type = LocalType.Return; // Create the field for generators. if(isGenerator) { FieldVariable returningField = new FieldVariable("returning", MemberFlags.Private, ChelaType.GetBoolType(), defNode.GeneratorClass); defNode.GeneratorClass.AddField(returningField); function.ReturningVar.ActualVariable = returningField; } // Initializer the returning flag to false. builder.CreateLoadBool(false); PerformAssignment(where, function.ReturningVar); }
private void DefineGeneratorBody(FunctionDefinition node) { // Get entry function. Function entryFunction = node.GetFunction(); // Rebase his locals. entryFunction.RebaseLocals(); // Create the generator class. Scope spaceScope = entryFunction.GetParentScope(); Class generatorClass = new Class(GenSym(), MemberFlags.Internal, spaceScope); node.GeneratorClass = generatorClass; // Use the same generic prototype as the entry point function. generatorClass.SetGenericPrototype(entryFunction.GetGenericPrototype()); // Add the generator class to the same scope as the function. if(spaceScope.IsClass() || spaceScope.IsStructure()) { Structure parentClass = (Structure)spaceScope; parentClass.AddType(generatorClass); } else if(spaceScope.IsNamespace()) { Namespace parentSpace = (Namespace)spaceScope; parentSpace.AddMember(generatorClass); } else { Error(node, "Cannot create generator class in {0}", spaceScope.GetFullName()); } // Add the enumerable interface. Structure enumerableIface = null; if(node.IsEnumerable) { enumerableIface = currentModule.GetEnumerableIface(); if(node.IsGenericIterator) { enumerableIface = currentModule.GetEnumerableGIface(); GenericInstance gargs = new GenericInstance(enumerableIface.GetGenericPrototype(), new IChelaType[]{node.YieldType}); enumerableIface = (Structure)enumerableIface.InstanceGeneric(gargs, currentModule); } generatorClass.AddInterface(enumerableIface); } // Add the enumerator interface. Structure enumeratorIface = currentModule.GetEnumeratorIface(); if(node.IsGenericIterator) { enumeratorIface = currentModule.GetEnumeratorGIface(); GenericInstance gargs = new GenericInstance(enumeratorIface.GetGenericPrototype(), new IChelaType[]{node.YieldType}); enumeratorIface = (Structure)enumeratorIface.InstanceGeneric(gargs, currentModule); } generatorClass.AddInterface(enumeratorIface); // Create the yielded field. FieldVariable yieldedValue = new FieldVariable("yielded", MemberFlags.Private, node.YieldType, generatorClass); generatorClass.AddField(yieldedValue); node.YieldedValue = yieldedValue; // Create the generator state variable. FieldVariable generatorState = new FieldVariable("state", MemberFlags.Private, ChelaType.GetIntType(), generatorClass); generatorClass.AddField(generatorState); node.GeneratorState = generatorState; // Encapsulate the locals in fields. foreach(LocalVariable local in entryFunction.GetLocals()) { if(!local.IsPseudoLocal) continue; // Variables containing arguments must be public. MemberFlags access = MemberFlags.Private; if(local.ArgumentIndex >= 0) access = MemberFlags.Public; // Create the field to hold the state. FieldVariable localField = new FieldVariable(GenSym(), access, local.GetVariableType(), generatorClass); generatorClass.AddField(localField); local.ActualVariable = localField; } // Create an instance of the generator class. Structure generatorClassInstance = generatorClass.GetClassInstance(); if(generatorClass.GetGenericPrototype().GetPlaceHolderCount() != 0) { // Create an instance using the same placeholders. GenericPrototype proto = generatorClass.GetGenericPrototype(); int numargs = proto.GetPlaceHolderCount(); IChelaType[] protoInstance = new IChelaType[numargs]; for(int i = 0; i < numargs; ++i) protoInstance[i] = proto.GetPlaceHolder(i); // Instance the generic class. GenericInstance instance = new GenericInstance(proto, protoInstance); generatorClassInstance = (Structure)generatorClassInstance.InstanceGeneric(instance, currentModule); } node.GeneratorClassInstance = generatorClassInstance; // Create the trivial constructor. Function ctor = CreateTrivialConstructor(generatorClass, generatorClassInstance); if(generatorClass.IsGeneric()) ctor = FindFirstConstructor(generatorClassInstance); // Create a local to hold the created closure. LexicalScope topScope = (LexicalScope)node.GetScope(); LocalVariable closureLocal = new LocalVariable("closure", topScope, ReferenceType.Create(generatorClassInstance)); // Create the entry point content. BasicBlock entryBlock = CreateBasicBlock(); entryBlock.SetName("entry"); builder.SetBlock(entryBlock); // Create the closure and store it in his local. builder.CreateNewObject(generatorClassInstance, ctor, 0); builder.CreateStoreLocal(closureLocal); // Load the closure. builder.CreateLoadLocal(closureLocal); // Store the arguments into the closure. FunctionPrototype prototype = node.GetPrototype(); AstNode argument = prototype.GetArguments(); byte index = 0; while(argument != null) { FunctionArgument argNode = (FunctionArgument) argument; // TODO: Forbid ref, out, stream arguments here. // Store the argument in the closure. LocalVariable argVar = argNode.GetVariable(); if(argVar != null) { // Load the closure builder.CreateDup1(); // Load the argument. builder.CreateLoadArg(index); // Store it into the field. builder.CreateStoreField((FieldVariable)argVar.ActualVariable); } // Process the next argument. argument = argument.GetNext(); index++; } // Encapsulate the argument variables. foreach(ArgumentVariable argVar in node.ArgumentVariables) { if(!argVar.IsPseudoArgument) continue; // Create the argument field. FieldVariable argField = new FieldVariable(GenSym(), MemberFlags.Public, argVar.GetVariableType(), generatorClass); generatorClass.AddField(argField); argVar.ActualVariable = argField; // Store the self field. if(!currentFunction.IsStatic() && argVar.GetArgumentIndex() == 0) node.GeneratorSelf = argField; // Load the closure. builder.CreateDup1(); // Load the argument. builder.CreateLoadArg((byte)argVar.GetArgumentIndex()); // Store it into the closure. builder.CreateStoreField(argField); } // Return the generator. builder.CreateRet(); // Notify the yields about their states. int stateIndex = 2; foreach(ReturnStatement yieldStmtn in node.Yields) { yieldStmtn.YieldState = stateIndex; stateIndex += 2; } // Implement IEnumerator. if(node.IsEnumerable) { // Create the object GetEnumerator method. CreateGenerator_GetEnumerator(node, currentModule.GetEnumeratorIface(), false); // Create the generic GetEnumerator method if(node.IsGenericIterator) CreateGenerator_GetEnumerator(node, enumeratorIface, true); } // Create the Current property. CreateGenerator_Current(node, false); if(node.IsGenericIterator) CreateGenerator_Current(node, true); // Create the Reset method. CreateGenerator_Reset(node); // Create the MoveNext method. Function moveNext = CreateGenerator_MoveNext(node); // Create the Dispose method. CreateGenerator_Dispose(node, moveNext); // Fix the inheritance. generatorClass.FixInheritance(); }
private void EmitFieldDebugInfo(ModuleWriter writer, FieldVariable field) { // Emit the field id. uint fieldId = field.GetSerialId(); writer.Write(fieldId); // Emit the field position. TokenPosition position = field.Position; if(position == null) position = NullPosition; EmitPosition(writer, position); }
public override AstNode Visit(FieldDefinition node) { // Push the unsafe context. bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe; if(isUnsafe) PushUnsafe(); // Get the type node. Expression typeExpression = node.GetTypeNode(); // Visit the type node. typeExpression.Accept(this); // Get the type of the type expression. IChelaType type = typeExpression.GetNodeType(); type = ExtractActualType(typeExpression, type); // Check field type security. if(type.IsUnsafe()) UnsafeError(node, "safe field with unsafe type."); // Class/interfaces instances are held by reference. if(type.IsPassedByReference()) type = ReferenceType.Create(type); // Constants are always static. if(type.IsConstant()) node.SetFlags((node.GetFlags() & ~MemberFlags.InstanceMask) | MemberFlags.Static); // Process the declarations. FieldDeclaration decl = node.GetDeclarations(); while(decl != null) { // Find an existent member. ScopeMember oldField = currentContainer.FindMember(decl.GetName()); if(oldField != null) Error(node, "already declared a member with the same name."); // Create the field. FieldVariable field = new FieldVariable(decl.GetName(), node.GetFlags(), type, currentContainer); field.Position = decl.GetPosition(); decl.SetVariable(field); decl.SetNodeType(type); // Add the field into the scope. if(currentContainer.IsStructure() || currentContainer.IsClass()) { // Add the field. Structure building = (Structure)currentContainer; building.AddField(field); } else if(currentContainer.IsNamespace()) { // Make sure its a global variable. if(!field.IsStatic()) Error(node, "namespaces only can have static fields."); Namespace space = (Namespace)currentContainer; space.AddMember(field); } else { Error(node, "a field must be declared inside an structure or class."); } // Process the next declaration. decl = (FieldDeclaration)decl.GetNext(); } if(isUnsafe) PopUnsafe(); return node; }
public override AstNode Visit(EnumConstantDefinition node) { // Use the same flags for all of the constants. MemberFlags flags = MemberFlags.Static | MemberFlags.Public; // The current container must be a structure. Structure building = (Structure)currentContainer; // Create the field. FieldVariable field = new FieldVariable(node.GetName(), flags, node.GetNodeType(), building); node.SetVariable(field); // Add it to the enumeration. building.AddField(field); // Return the node. return node; }
private void DeclareSimplifiedEvent(EventDefinition node) { // Get the event variable. EventVariable eventVariable = node.GetEvent(); // Get the flags. MemberFlags flags = node.GetFlags(); // Get the instance type. MemberFlags instanceFlags = MemberFlags.InstanceMask & flags; // 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); // Create the add function. CreateSimplifiedEventFunction(node, eventVariable, functionType, true); // Create the remove function CreateSimplifiedEventFunction(node, eventVariable, functionType, false); // Create the delegate field. string delFieldName = "_evdel_" + eventVariable.GetName(); MemberFlags delFieldFlags = flags & ~MemberFlags.VisibilityMask; if(eventVariable.IsPrivate()) delFieldFlags |= MemberFlags.Private; else delFieldFlags |= MemberFlags.Protected; // Store the delegate field in the current container. FieldVariable delField = new FieldVariable(delFieldName, delFieldFlags, eventVariable.GetVariableType(), currentContainer); delField.Position = node.GetPosition(); eventVariable.AssociatedField = delField; if(currentContainer.IsNamespace()) { Namespace space = (Namespace) currentContainer; space.AddMember(delField); } else if(currentContainer.IsClass() || currentContainer.IsStructure() || currentContainer.IsInterface()) { Structure building = (Structure) currentContainer; building.AddField(delField); } else Error(node, "an event cannot be defined here."); }
public override AstNode Visit(EnumDefinition node) { // Push the scope. PushScope(node.GetScope()); // Use a default type of const int. IChelaType baseType = ChelaType.GetIntType(); IChelaType enumType = ConstantType.Create(baseType); // Declare the value field. Structure building = node.GetStructure(); FieldVariable valueField = new FieldVariable("m_value", MemberFlags.Public, baseType, building); building.AddField(valueField); // Used for implicit prev + 1. IChelaType enumConst = ConstantType.Create(building); TypeNode enumIntExpr = new TypeNode(TypeKind.Other, node.GetPosition()); enumIntExpr.SetOtherType(enumType); // Visit the constant defininitions. EnumConstantDefinition prev = null; AstNode child = node.GetChildren(); while(child != null) { // Cast the child. EnumConstantDefinition constDef = (EnumConstantDefinition)child; // Set the child type. constDef.SetCoercionType(enumType); constDef.SetNodeType(enumConst); // If there isn't a constant expression, use previous + 1 or 0. if(constDef.GetValue() == null) { TokenPosition constPos = constDef.GetPosition(); if(prev != null) { // Previous + 1 Expression prevExpr = new CastOperation(enumIntExpr, new VariableReference(prev.GetName(), constPos), constPos); Expression implicitVal = new BinaryOperation(BinaryOperation.OpAdd, prevExpr, new ByteConstant(1, constPos), constPos); constDef.SetValue(implicitVal); } else { // First element is 0 constDef.SetValue(new ByteConstant(0, constPos)); } } // Visit the constant definition. constDef.Accept(this); // Process the next constant. prev = constDef; child = child.GetNext(); } // Restore the scope. PopScope(); return node; }