private void InsertThisPointerAtBody(ThisPointerProcOverload procOverload) { for (int n = 0; n < procOverload.procNode.FunctionBody.Body.Count; ++n) { if (procOverload.procNode.FunctionBody.Body[n] is BinaryExpressionNode) { BinaryExpressionNode assocNode = procOverload.procNode.FunctionBody.Body[n] as BinaryExpressionNode; AssociativeNode outLNode = null; AssociativeNode outRNode = null; // This is the first traversal of this statement and is therefore the assignment op Validity.Assert(Operator.assign == assocNode.Optr); TraverseAndAppendThisPtrArg(assocNode.LeftNode, ref outLNode); TraverseAndAppendThisPtrArg(assocNode.RightNode, ref outRNode); assocNode.LeftNode = outLNode; assocNode.RightNode = outRNode; } else if (procOverload.procNode.FunctionBody.Body[n] is LanguageBlockNode) { LanguageBlockNode langBlockNode = procOverload.procNode.FunctionBody.Body[n] as LanguageBlockNode; if (langBlockNode.CodeBlockNode is ProtoCore.AST.ImperativeAST.CodeBlockNode) { ProtoCore.AST.ImperativeAST.CodeBlockNode iCodeBlockNode = langBlockNode.CodeBlockNode as ProtoCore.AST.ImperativeAST.CodeBlockNode; for (int i = 0; i < iCodeBlockNode.Body.Count; ++i) { if (iCodeBlockNode.Body[i] is ProtoCore.AST.ImperativeAST.BinaryExpressionNode) { ProtoCore.AST.ImperativeAST.BinaryExpressionNode iNode = iCodeBlockNode.Body[i] as ProtoCore.AST.ImperativeAST.BinaryExpressionNode; ProtoCore.AST.ImperativeAST.ImperativeNode outLNode = null; ProtoCore.AST.ImperativeAST.ImperativeNode outRNode = null; // This is the first traversal of this statement and is therefore the assignment op Validity.Assert(Operator.assign == iNode.Optr); TraverseAndAppendThisPtrArg(iNode.LeftNode, ref outLNode); TraverseAndAppendThisPtrArg(iNode.RightNode, ref outRNode); iNode.LeftNode = outLNode; iNode.RightNode = outRNode; } } } else { Validity.Assert(false, "We dont have other langauges besides associative and imperative"); } } } }
private void BuildThisFunctionBody(ThisPointerProcOverload procOverload) { BinaryExpressionNode thisFunctionBody = new BinaryExpressionNode(); IdentifierNode leftNode = new IdentifierNode(); leftNode.Name = leftNode.Value = ProtoCore.DSDefinitions.Keyword.Return; thisFunctionBody.LeftNode = leftNode; thisFunctionBody.Optr = Operator.assign; // Build the function call and pass it the arguments including the this pointer FunctionCallNode fcall = new FunctionCallNode(); IdentifierNode identNode = new IdentifierNode(); identNode.Name = procOverload.procNode.Name; fcall.Function = identNode; // Set the arguments passed into the function excluding the 'this' argument List<AssociativeNode> args = new List<AssociativeNode>(); for (int n = 1; n < procOverload.procNode.Signature.Arguments.Count; ++n) { VarDeclNode varDecl = procOverload.procNode.Signature.Arguments[n]; args.Add(varDecl.NameNode); } fcall.FormalArguments = args; // Build the dotcall node procOverload.procNode.FunctionBody.Body = new List<AssociativeNode>(); procOverload.procNode.FunctionBody.Body.Add(thisFunctionBody); thisFunctionBody.RightNode = CoreUtils.GenerateCallDotNode(procOverload.procNode.Signature.Arguments[0].NameNode, fcall, core); }
/* 1 Copy user-defined function definitions (excluding constructors) into a temp 2 Modify its signature to include an additional this pointer as the first argument. The 'this' argument should take the type of the current class being traversed and be the first argument in the function. The function name must be name mangled in order to stay unique 3 Append this temp to the current vtable */ private void InsertThisPointerArg(ThisPointerProcOverload procOverload) { // Modify its signature to include an additional this pointer as the first argument. // The 'this' argument should take the type of the current class being traversed and be the first argument in the function. // The function name must be name mangled in order to stay unique ProtoCore.AST.AssociativeAST.FunctionDefinitionNode procNode = procOverload.procNode; string className = compileStateTracker.ClassTable.ClassNodes[procOverload.classIndex].name; string thisPtrArgName = ProtoCore.DSASM.Constants.kThisPointerArgName; ProtoCore.AST.AssociativeAST.IdentifierNode ident = new ProtoCore.AST.AssociativeAST.IdentifierNode(); ident.Name = ident.Value = thisPtrArgName; VarDeclNode thisPtrArg = new ProtoCore.AST.AssociativeAST.VarDeclNode() { memregion = ProtoCore.DSASM.MemoryRegion.kMemStack, access = ProtoCore.DSASM.AccessSpecifier.kPublic, NameNode = ident, ArgumentType = new ProtoCore.Type { Name = className, UID = procOverload.classIndex, IsIndexable = false, rank = 0 } }; procNode.Singnature.Arguments.Insert(0, thisPtrArg); ProtoCore.Type type = new ProtoCore.Type(); }
private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone, GraphNode graphNode = null) { ClassDeclNode classDecl = node as ClassDeclNode; // Restrict classes if (!IsClassAllowed(classDecl)) { return; } // Handling n-pass on class declaration if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassName == compilePass) { // Class name pass // Populating the class tables with the class names if (null != codeBlock.parent) { buildStatus.LogSemanticError(Resources.ClassCannotBeDefinedInsideLanguageBlock, core.CurrentDSFileName, classDecl.line, classDecl.col); } ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode(); thisClass.Name = classDecl.ClassName; thisClass.Size = classDecl.Variables.Count; thisClass.IsImportedClass = classDecl.IsImportedClass; thisClass.TypeSystem = core.TypeSystem; thisClass.ClassAttributes = classDecl.ClassAttributes; if (classDecl.ExternLibName != null) thisClass.ExternLib = classDecl.ExternLibName; else thisClass.ExternLib = Path.GetFileName(core.CurrentDSFileName); globalClassIndex = core.ClassTable.Append(thisClass); if (ProtoCore.DSASM.Constants.kInvalidIndex == globalClassIndex) { string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.ClassName); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } unPopulatedClasses.Add(globalClassIndex, classDecl); //Always allow us to convert a class to a bool thisClass.CoerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore); } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassBaseClass == compilePass) { // Base class pass // Populating each class entry with their immediate baseclass globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.BaseClasses) { for (int n = 0; n < classDecl.BaseClasses.Count; ++n) { int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]); if (baseClass == globalClassIndex) { string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.ClassName); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { if (core.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass) { string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n", core.ClassTable.ClassNodes[baseClass].Name); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } thisClass.Bases.Add(baseClass); thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); } else { string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.BaseClasses[n]); buildStatus.LogSemanticError(message, core.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassHierarchy == compilePass) { // Class hierarchy pass // Populating each class entry with all sub classes in the hierarchy globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.BaseClasses) { for (int n = 0; n < classDecl.BaseClasses.Count; ++n) { int baseClass = core.ClassTable.GetClassId(classDecl.BaseClasses[n]); // baseClass is already resovled in the previous pass Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != baseClass); // Iterate through all the base classes until the the root class // For every base class, add the coercion score ProtoCore.DSASM.ClassNode tmpCNode = core.ClassTable.ClassNodes[baseClass]; if (tmpCNode.Bases.Count > 0) { baseClass = tmpCNode.Bases[0]; while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { thisClass.CoerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); tmpCNode = core.ClassTable.ClassNodes[baseClass]; baseClass = ProtoCore.DSASM.Constants.kInvalidIndex; if (tmpCNode.Bases.Count > 0) { baseClass = tmpCNode.Bases[0]; } } } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemVar == compilePass) { EmitMemberVariables(classDecl, graphNode); } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncSig == compilePass) { // Class member variable pass // Populating each class entry vtables with their respective // member variables signatures globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>(); foreach (AssociativeNode funcdecl in classDecl.Procedures) { DfsTraverse(funcdecl, ref inferedType); var funcDef = funcdecl as FunctionDefinitionNode; if (funcDef == null || funcDef.IsStatic || funcDef.Name == ProtoCore.DSDefinitions.Keyword.Dispose) continue; bool isGetterSetter = CoreUtils.IsGetterSetter(funcDef.Name); var thisPtrArgName = Constants.kThisPointerArgName; if (!isGetterSetter) { var classsShortName = classDecl.ClassName.Split('.').Last(); var typeDepName = classsShortName.ToLower(); if (typeDepName != classsShortName && funcDef.Signature.Arguments.All(a => a.NameNode.Name != typeDepName)) thisPtrArgName = typeDepName; } // This is a function, create its parameterized this pointer overload ThisPointerProcOverload thisProc = new ThisPointerProcOverload(); thisProc.classIndex = globalClassIndex; thisProc.procNode = new FunctionDefinitionNode(funcDef); var thisPtrArg = new VarDeclNode() { Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic, NameNode = AstFactory.BuildIdentifier(thisPtrArgName), ArgumentType = new ProtoCore.Type { Name = classDecl.ClassName, UID = globalClassIndex, rank = 0 } }; thisProc.procNode.Signature.Arguments.Insert(0, thisPtrArg); thisProc.procNode.IsAutoGeneratedThisProc = true; if (CoreUtils.IsGetterSetter(funcDef.Name)) { InsertThisPointerAtBody(thisProc); } else { // Generate a static function for member function f(): // satic def f(a: A) // { // return = a.f() // } thisProc.procNode.IsStatic = true; BuildThisFunctionBody(thisProc); } thisPtrOverloadList.Add(thisProc.procNode); } foreach (var overloadFunc in thisPtrOverloadList) { // Emit the newly defined overloads DfsTraverse(overloadFunc, ref inferedType); } classDecl.Procedures.AddRange(thisPtrOverloadList); if (!classDecl.IsExternLib) { ProtoCore.DSASM.ProcedureTable vtable = core.ClassTable.ClassNodes[globalClassIndex].ProcTable; if (vtable.GetFunctionBySignature(classDecl.ClassName, new List<ProtoCore.Type>()) == null) { ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode(); defaultConstructor.Name = classDecl.ClassName; defaultConstructor.LocalVariableCount = 0; defaultConstructor.Signature = new ArgumentSignatureNode(); defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 }; defaultConstructor.FunctionBody = new CodeBlockNode(); defaultConstructor.BaseConstructor = null; defaultConstructor.Access = ProtoCore.CompilerDefinitions.AccessModifier.kPublic; defaultConstructor.IsExternLib = false; defaultConstructor.ExternLibName = null; DfsTraverse(defaultConstructor, ref inferedType); classDecl.Procedures.Add(defaultConstructor); } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kGlobalScope == compilePass) { // before populate the attributes, we must know the attribute class constructor signatures // in order to check the parameter // populate the attributes for the class and class member variable globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) { ProtoCore.DSASM.ClassNode thisClass = core.ClassTable.ClassNodes[globalClassIndex]; // class if (classDecl.Attributes != null) { thisClass.Attributes = PopulateAttributes(classDecl.Attributes); } // member variable int ix = -1; int currentClassScope = -1; foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.Symbols.symbolList.Values) { // only populate the attributes for member variabls if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex) continue; if (sn.classScope != globalClassIndex) { if (currentClassScope != sn.classScope) { currentClassScope = sn.classScope; ix = 0; } // copy attribute information from base class sn.Attributes = core.ClassTable.ClassNodes[currentClassScope].Symbols.symbolList[ix++].Attributes; } else { if (currentClassScope != globalClassIndex) { currentClassScope = globalClassIndex; ix = 0; } } } } } else if (ProtoCore.CompilerDefinitions.Associative.CompilePass.kClassMemFuncBody == compilePass) { // Class member variable pass // Populating the function body of each member function defined in the class vtables globalClassIndex = core.ClassTable.GetClassId(classDecl.ClassName); // Initialize the global function table for this class // 'classIndexAtCallsite' is the class index as it is stored at the callsite function tables int classIndexAtCallsite = globalClassIndex + 1; core.FunctionTable.InitGlobalFunctionEntry(classIndexAtCallsite); foreach (AssociativeNode funcdecl in classDecl.Procedures) { // reset the inferedtype between functions inferedType = new ProtoCore.Type(); DfsTraverse(funcdecl, ref inferedType, false, null, subPass); } } // Reset the class index core.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope; }
private void EmitClassDeclNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { ClassDeclNode classDecl = node as ClassDeclNode; // Handling n-pass on class declaration if (ProtoCore.DSASM.AssociativeCompilePass.kClassName == compilePass) { // Class name pass // Populating the class tables with the class names if (null != codeBlock.parent) { buildStatus.LogSemanticError("A class cannot be defined inside a language block.\n", compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); } if (ProtoCore.DSASM.Constants.kInvalidIndex != compileStateTracker.ClassTable.IndexOf(classDecl.className)) { string message = string.Format("Class redefinition '{0}' (BE1C3285).\n", classDecl.className); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } ProtoCore.DSASM.ClassNode thisClass = new ProtoCore.DSASM.ClassNode(); thisClass.name = classDecl.className; thisClass.size = classDecl.varlist.Count; thisClass.IsImportedClass = classDecl.IsImportedClass; thisClass.typeSystem = compileStateTracker.TypeSystem; if (classDecl.ExternLibName != null) thisClass.ExternLib = classDecl.ExternLibName; else thisClass.ExternLib = Path.GetFileName(compileStateTracker.CurrentDSFileName); globalClassIndex = compileStateTracker.ClassTable.Append(thisClass); unPopulatedClasses.Add(globalClassIndex, classDecl); //Always allow us to convert a class to a bool thisClass.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore); } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassHeirarchy == compilePass) { // Class heirarchy pass // Populating each class entry with their respective base classes globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex]; // Verify and store the list of classes it inherits from if (null != classDecl.superClass) { for (int n = 0; n < classDecl.superClass.Count; ++n) { int baseClass = compileStateTracker.ClassTable.IndexOf(classDecl.superClass[n]); if (baseClass == globalClassIndex) { string message = string.Format("Class '{0}' cannot derive from itself (DED0A61F).\n", classDecl.className); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } if (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { if (compileStateTracker.ClassTable.ClassNodes[baseClass].IsImportedClass && !thisClass.IsImportedClass) { string message = string.Format("Cannot derive from FFI class {0} (DA87AC4D).\n", compileStateTracker.ClassTable.ClassNodes[baseClass].name); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } thisClass.baseList.Add(baseClass); thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); // Iterate through all the base classes until the the root class // For every base class, add the coercion score // TODO Jun: -Integrate this with multiple inheritace when supported // -Cleansify ProtoCore.DSASM.ClassNode tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass]; if (tmpCNode.baseList.Count > 0) { baseClass = tmpCNode.baseList[0]; while (ProtoCore.DSASM.Constants.kInvalidIndex != baseClass) { thisClass.coerceTypes.Add(baseClass, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceBaseClass); tmpCNode = compileStateTracker.ClassTable.ClassNodes[baseClass]; baseClass = ProtoCore.DSASM.Constants.kInvalidIndex; if (tmpCNode.baseList.Count > 0) { baseClass = tmpCNode.baseList[0]; } } } } else { string message = string.Format("Unknown base class '{0}' (9E44FFB3).\n", classDecl.superClass[n]); buildStatus.LogSemanticError(message, compileStateTracker.CurrentDSFileName, classDecl.line, classDecl.col); throw new BuildHaltException(message); } } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemVar == compilePass) { EmitMemberVariables(classDecl); } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncSig == compilePass) { // Class member variable pass // Populating each class entry vtables with their respective member variables signatures globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); List<AssociativeNode> thisPtrOverloadList = new List<AssociativeNode>(); foreach (AssociativeNode funcdecl in classDecl.funclist) { DfsTraverse(funcdecl, ref inferedType); // If this is a function, create its parameterized this pointer overload if (funcdecl is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode) { string procName = (funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode).Name; bool isFunctionExcluded = procName.Equals(ProtoCore.DSASM.Constants.kStaticPropertiesInitializer); // TODO Jun: There is a current limitation of not supporting classes yet at live execution // Fix this soon - the first fix would be in import load and unload for every delta run //if (!core.Options.IsDeltaExecution) if (!compileStateTracker.Options.IsDeltaExecution) { if (!isFunctionExcluded) { ThisPointerProcOverload thisProc = new ThisPointerProcOverload(); thisProc.classIndex = globalClassIndex; thisProc.procNode = new ProtoCore.AST.AssociativeAST.FunctionDefinitionNode(funcdecl as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode); thisProc.procNode.IsAutoGeneratedThisProc = true; InsertThisPointerArg(thisProc); //InsertThisPointerAtBody(thisProc); if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName)) { InsertThisPointerAtBody(thisProc); } else { // This is a normal function // the body thsould be the actaul function called through the this pointer argument // // def f() { return = 1 } // def f(%this : A) { return = %this.f()} // BuildThisFunctionBody(thisProc); } // Emit the newly defined overloads DfsTraverse(thisProc.procNode, ref inferedType); thisPtrOverloadList.Add(thisProc.procNode); } } } } classDecl.funclist.AddRange(thisPtrOverloadList); if (!classDecl.IsExternLib) { ProtoCore.DSASM.ProcedureTable vtable = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable; if (vtable.IndexOfExact(classDecl.className, new List<ProtoCore.Type>()) == ProtoCore.DSASM.Constants.kInvalidIndex) { ConstructorDefinitionNode defaultConstructor = new ConstructorDefinitionNode(); defaultConstructor.Name = classDecl.className; defaultConstructor.localVars = 0; defaultConstructor.Signature = new ArgumentSignatureNode(); defaultConstructor.Pattern = null; defaultConstructor.ReturnType = new ProtoCore.Type { Name = "var", UID = 0 }; defaultConstructor.FunctionBody = new CodeBlockNode(); defaultConstructor.baseConstr = null; defaultConstructor.access = ProtoCore.DSASM.AccessSpecifier.kPublic; defaultConstructor.IsExternLib = false; defaultConstructor.ExternLibName = null; DfsTraverse(defaultConstructor, ref inferedType); classDecl.funclist.Add(defaultConstructor); } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kGlobalScope == compilePass) { // before populate the attributes, we must know the attribute class constructor signatures // in order to check the parameter // populate the attributes for the class and class member variable globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) { ProtoCore.DSASM.ClassNode thisClass = compileStateTracker.ClassTable.ClassNodes[globalClassIndex]; // class if (classDecl.Attributes != null) { thisClass.Attributes = PopulateAttributes(classDecl.Attributes); } // member variable int ix = -1; int currentClassScope = -1; foreach (ProtoCore.DSASM.SymbolNode sn in thisClass.symbols.symbolList.Values) { // only populate the attributes for member variabls if (sn.functionIndex != ProtoCore.DSASM.Constants.kInvalidIndex) continue; if (sn.classScope != globalClassIndex) { if (currentClassScope != sn.classScope) { currentClassScope = sn.classScope; ix = 0; } // copy attribute information from base class sn.Attributes = compileStateTracker.ClassTable.ClassNodes[currentClassScope].symbols.symbolList[ix++].Attributes; } else { if (currentClassScope != globalClassIndex) { currentClassScope = globalClassIndex; ix = 0; } ProtoCore.AST.AssociativeAST.VarDeclNode varnode = classDecl.varlist[ix++] as ProtoCore.AST.AssociativeAST.VarDeclNode; sn.Attributes = PopulateAttributes((varnode).Attributes); } } } } else if (ProtoCore.DSASM.AssociativeCompilePass.kClassMemFuncBody == compilePass) { // Class member variable pass // Populating the function body of each member function defined in the class vtables globalClassIndex = compileStateTracker.ClassTable.IndexOf(classDecl.className); foreach (AssociativeNode funcdecl in classDecl.funclist) { // reset the inferedtype between functions inferedType = new ProtoCore.Type(); DfsTraverse(funcdecl, ref inferedType, false, null, subPass); } } // Reset the class index compileStateTracker.ClassIndex = globalClassIndex = ProtoCore.DSASM.Constants.kGlobalScope; }