示例#1
0
        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");
                    }
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
        /*
            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();
        }
示例#4
0
        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;
        }
示例#5
0
        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;
        }